#include "comdellexer.h" #include "comdelparser.h" #include "parserutil.h" #include #include #include #include std::optional loadLibraryFromFile(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.size()) { for (auto& error : lexerResult.errors) { parseContext->formatError(error, stream, "ERROR: "); } return std::nullopt; // if lexer has found errors => don't parse } ComdelParser parser(lexerResult.tokens); auto unit = parser.parse(); if (!unit) { for (auto& error : parser.getErrors()) { parseContext->formatError(error, stream, "ERROR: "); } return std::nullopt; } return *unit; } std::optional loadSchemaFromFile(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.size()) { for (auto& error : lexerResult.errors) { parseContext->formatError(error, stream, "ERROR: "); } return std::nullopt; // if lexer has found errors => don't parse } 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 dir; dir.setCurrent(filepath); auto libraryPath = dir.absoluteFilePath(QString::fromStdString(unit->source->asString())); unit->library = loadLibraryFromFile(parseContext, libraryPath.toUtf8().data(), stream); if(unit->library == std::nullopt) { return std::nullopt; } } return *unit; }