#include "comdel_lexer.h" #include "comdel_parser.h" #include "parser_util.h" #include #include #include #include std::optional load_library_from_file(ParseContext *parseContext, const char *name, std::ostream &stream) { std::ifstream in(name, std::ios::in | std::ios::binary); if (!in) { stream << "ERROR: cannot open file '" << name << "' (file does not exist or is unreadable)" << std::endl; return std::nullopt; } std::string source((std::istreambuf_iterator(in)), std::istreambuf_iterator()); ComdelLexer lexer(name, source, parseContext); LexerResult lexerResult = lexer.tokenize(); if (!lexerResult.errors.empty()) { for (auto &error: lexerResult.errors) { parseContext->formatError(error, stream, "ERROR: "); } return std::nullopt; // if lexer has found errors => don't parseLibrary } ComdelParser parser(lexerResult.tokens); auto unit = parser.parseLibrary(); if (!unit) { for (auto &error: parser.getErrors()) { parseContext->formatError(error, stream, "ERROR: "); } return std::nullopt; } return *unit; } std::optional load_schema_from_file(ParseContext *parseContext, const char *name, std::ostream &stream) { std::ifstream in(name, std::ios::in | std::ios::binary); if (!in) { stream << "ERROR: cannot open file '" << name << "' (file does not exist or is unreadable)" << std::endl; return std::nullopt; } std::string source((std::istreambuf_iterator(in)), std::istreambuf_iterator()); ComdelLexer lexer(name, source, parseContext); LexerResult lexerResult = lexer.tokenize(); if (!lexerResult.errors.empty()) { for (auto &error: lexerResult.errors) { parseContext->formatError(error, stream, "ERROR: "); } return std::nullopt; // if lexer has found errors => don't parseLibrary } ComdelParser parser(lexerResult.tokens); auto unit = parser.parseSchema(); if (!unit) { for (auto &error: parser.getErrors()) { parseContext->formatError(error, stream, "ERROR: "); } return std::nullopt; } if (unit->source) { QFileInfo info(name); auto filepath = info.absolutePath(); QDir::setCurrent(filepath); QDir dir; auto libraryPath = dir.absoluteFilePath(QString::fromStdString(unit->source->asString())); unit->library = load_library_from_file(parseContext, libraryPath.toUtf8().data(), stream); if (unit->library == std::nullopt) { return std::nullopt; } } return *unit; }