2022-03-29 19:31:45 +00:00
|
|
|
#include "comdellexer.h"
|
|
|
|
#include "comdelparser.h"
|
|
|
|
#include "parserutil.h"
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
#include <fstream>
|
|
|
|
#include <string>
|
|
|
|
|
2022-03-29 21:49:32 +00:00
|
|
|
std::optional<LibraryNode> loadLibraryFromFile(ParseContext * parseContext,
|
2022-03-29 19:31:45 +00:00
|
|
|
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<char>(in)),
|
|
|
|
std::istreambuf_iterator<char>());
|
|
|
|
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;
|
|
|
|
}
|
2022-03-31 21:20:41 +00:00
|
|
|
|
|
|
|
|
|
|
|
std::optional<SchemaNode> 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<char>(in)),
|
|
|
|
std::istreambuf_iterator<char>());
|
|
|
|
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) {
|
|
|
|
unit->library = loadLibraryFromFile(parseContext, unit->source->asString().c_str(), stream);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return *unit;
|
|
|
|
}
|