schema_editor/comdel/parser/parser_util.cpp

93 lines
2.9 KiB
C++
Raw Normal View History

2022-06-09 18:24:27 +00:00
#include "comdel_lexer.h"
2022-05-27 06:18:17 +00:00
#include "comdel_parser.h"
#include "parser_util.h"
2022-03-29 19:31:45 +00:00
#include <iostream>
#include <fstream>
#include <string>
2022-04-12 21:37:05 +00:00
#include <QDir>
2022-03-29 19:31:45 +00:00
2022-05-27 06:18:17 +00:00
std::optional<LibraryNode> load_library_from_file(ParseContext *parseContext,
const char *name,
std::ostream &stream) {
2022-03-29 19:31:45 +00:00
std::ifstream in(name, std::ios::in | std::ios::binary);
2022-05-27 06:18:17 +00:00
if (!in) {
2022-03-29 19:31:45 +00:00
stream << "ERROR: cannot open file '" << name
<< "' (file does not exist or is unreadable)" << std::endl;
return std::nullopt;
}
std::string source((std::istreambuf_iterator<char>(in)),
std::istreambuf_iterator<char>());
ComdelLexer lexer(name, source, parseContext);
LexerResult lexerResult = lexer.tokenize();
2022-05-27 06:18:17 +00:00
if (!lexerResult.errors.empty()) {
for (auto &error: lexerResult.errors) {
2022-03-29 19:31:45 +00:00
parseContext->formatError(error, stream, "ERROR: ");
}
2022-05-27 06:18:17 +00:00
return std::nullopt; // if lexer has found errors => don't parseLibrary
2022-03-29 19:31:45 +00:00
}
ComdelParser parser(lexerResult.tokens);
2022-05-27 06:18:17 +00:00
auto unit = parser.parseLibrary();
2022-03-29 19:31:45 +00:00
if (!unit) {
2022-05-27 06:18:17 +00:00
for (auto &error: parser.getErrors()) {
2022-03-29 19:31:45 +00:00
parseContext->formatError(error, stream, "ERROR: ");
}
return std::nullopt;
}
return *unit;
}
2022-03-31 21:20:41 +00:00
2022-05-27 06:18:17 +00:00
std::optional<SchemaNode> load_schema_from_file(ParseContext *parseContext,
const char *name,
std::ostream &stream) {
2022-03-31 21:20:41 +00:00
std::ifstream in(name, std::ios::in | std::ios::binary);
2022-05-27 06:18:17 +00:00
if (!in) {
2022-03-31 21:20:41 +00:00
stream << "ERROR: cannot open file '" << name
<< "' (file does not exist or is unreadable)" << std::endl;
return std::nullopt;
}
std::string source((std::istreambuf_iterator<char>(in)),
std::istreambuf_iterator<char>());
ComdelLexer lexer(name, source, parseContext);
LexerResult lexerResult = lexer.tokenize();
2022-05-27 06:18:17 +00:00
if (!lexerResult.errors.empty()) {
for (auto &error: lexerResult.errors) {
2022-03-31 21:20:41 +00:00
parseContext->formatError(error, stream, "ERROR: ");
}
2022-05-27 06:18:17 +00:00
return std::nullopt; // if lexer has found errors => don't parseLibrary
2022-03-31 21:20:41 +00:00
}
ComdelParser parser(lexerResult.tokens);
auto unit = parser.parseSchema();
if (!unit) {
2022-05-27 06:18:17 +00:00
for (auto &error: parser.getErrors()) {
2022-03-31 21:20:41 +00:00
parseContext->formatError(error, stream, "ERROR: ");
}
return std::nullopt;
}
2022-05-27 06:18:17 +00:00
if (unit->source) {
2022-04-12 21:37:05 +00:00
QFileInfo info(name);
auto filepath = info.absolutePath();
2022-05-27 06:18:17 +00:00
QDir::setCurrent(filepath);
2022-04-12 21:37:05 +00:00
2022-05-27 06:18:17 +00:00
QDir dir;
2022-04-12 21:37:05 +00:00
auto libraryPath = dir.absoluteFilePath(QString::fromStdString(unit->source->asString()));
2022-05-27 06:18:17 +00:00
unit->library = load_library_from_file(parseContext, libraryPath.toUtf8().data(), stream);
if (unit->library == std::nullopt) {
2022-04-12 21:37:05 +00:00
return std::nullopt;
}
2022-03-31 21:20:41 +00:00
}
return *unit;
}