added domain model

This commit is contained in:
Borna Rajkovic committed 2022-03-31 23:20:41 +02:00
1 parent 18d84727ab
commit f4450494d8
43 files changed
+1903 -234

No files matched your search

+109 -48
View File
@@ -31,6 +31,9 @@ public:
struct StringNode: public AstNode
{
std::string value;
std::string asString() {
return value.substr(1, value.length() - 2);
}
};
struct IdentifierNode: public AstNode
@@ -44,6 +47,7 @@ struct NumberNode: public AstNode {
NumberNode(): value(0) {}
};
struct CountNode: public AstNode
{
NumberNode first;
@@ -54,7 +58,7 @@ struct CountNode: public AstNode
};
struct AddressSpace: public AstNode
struct AddressSpaceNode: public AstNode
{
IdentifierNode name;
NumberNode start;
@@ -62,13 +66,14 @@ struct AddressSpace: public AstNode
};
class Value: AstNode
class ValueNode: AstNode
{
public:
enum ValueType {
INT,
STRING,
BOOL,
WIRE,
IDENTIFIER
};
@@ -81,6 +86,8 @@ private:
std::optional<std::string> identifierValue;
public:
ValueNode() {};
ValueType getType() {
return type;
}
@@ -113,43 +120,50 @@ public:
return this->type == type;
}
static Value ofBool(bool _value) {
Value value;
static ValueNode ofBool(bool _value) {
ValueNode value;
value.type = BOOL;
value.boolValue = std::optional<bool>(_value);
return value;
}
static Value ofInt(long long _value) {
Value value;
static ValueNode ofInt(long long _value) {
ValueNode value;
value.type = INT;
value.intValue = std::optional<long long>(_value);
return value;
}
static Value ofString(std::string _value) {
Value value;
static ValueNode ofString(std::string _value) {
ValueNode value;
value.type = STRING;
value.stringValue = std::optional<std::string>(_value);
return value;
}
static Value ofIdentifier(std::string _value) {
Value value;
static ValueNode ofIdentifier(std::string _value) {
ValueNode value;
value.type = IDENTIFIER;
value.identifierValue = std::optional<std::string>(_value);
return value;
}
static ValueNode ofWire(std::string _value) {
ValueNode value;
value.type = WIRE;
value.identifierValue = std::optional<std::string>(_value);
return value;
}
};
struct Condition
struct ConditionNode
{
bool negated;
IdentifierNode functionName;
std::vector<Value> params;
std::vector<ValueNode> params;
};
class Action: AstNode {
class ActionNode: AstNode {
public:
enum ActionType {
ERROR,
@@ -161,46 +175,47 @@ public:
};
struct IfStmt: AstNode
struct IfStatementnode: AstNode
{
Condition condition;
Action action;
ConditionNode condition;
ActionNode action;
};
struct Rule: AstNode
struct RuleNode: AstNode
{
std::vector<IfStmt> statements;
std::vector<IfStatementnode> statements;
};
struct EnumerationNode: AstNode
{
StringNode key;
Value value;
ValueNode value;
};
struct Popup: AstNode
struct PopupNode: AstNode
{
enum PopupType {
AUTOMATIC,
ON_DEMAND
};
PopupType type;
StringNode title;
StringNode text;
std::optional<PopupType> type;
std::optional<StringNode> title;
std::optional<StringNode> text;
bool enumerated;
std::vector<EnumerationNode> enumeration;
std::vector<Rule> rules;
std::vector<RuleNode> rules;
};
struct PropertyNode: public AstNode
{
IdentifierNode key;
Value value;
ValueNode value;
};
@@ -239,11 +254,9 @@ struct PinNode: AstNode
IdentifierNode name;
PinType type;
StringNode tooltip;
PinConnectionNode connection;
DisplayNode display;
std::optional<StringNode> tooltip;
std::optional<PinConnectionNode> connection;
std::optional<DisplayNode> display;
};
@@ -270,10 +283,10 @@ struct WireNode: public AstNode
struct AttributeNode: AstNode
{
Value::ValueType type;
ValueNode::ValueType type;
IdentifierNode name;
std::optional<Value> defaultValue;
std::optional<Popup> popup;
std::optional<ValueNode> defaultValue;
std::optional<PopupNode> popup;
};
struct ConnectionNode: AstNode
@@ -295,14 +308,14 @@ struct ComponentNode: AstNode
};
IdentifierNode name;
StringNode tooltip;
StringNode source;
std::optional<StringNode> tooltip;
std::optional<StringNode> source;
ComponentType type;
std::vector<Rule> rules;
StringNode instanceName;
CountNode count;
DisplayNode display;
std::vector<PinNode> pin;
std::vector<RuleNode> rules;
std::optional<StringNode> instanceName;
std::optional<CountNode> count;
std::optional<DisplayNode> display;
std::vector<PinNode> pins;
std::vector<AttributeNode> attributes;
};
@@ -316,21 +329,21 @@ struct BusNode: AstNode
BusType type;
IdentifierNode name;
StringNode tooltip;
CountNode count;
DisplayNode display;
std::optional<StringNode> tooltip;
std::optional<CountNode> count;
std::optional<DisplayNode> display;
std::vector<WireNode> wires;
};
struct LibraryNode: AstNode
{
StringNode name;
StringNode libraryInfo;
StringNode header;
StringNode componentDirectory;
std::optional<StringNode> name;
std::optional<StringNode> libraryInfo;
std::optional<StringNode> header;
std::optional<StringNode> componentDirectory;
std::vector<AddressSpace> addressSpaces;
std::vector<AddressSpaceNode> addressSpaces;
std::vector<ComponentNode> components;
std::vector<BusNode> buses;
@@ -339,6 +352,54 @@ struct LibraryNode: AstNode
std::vector<PropertyNode> messages;
};
// SCHEMA models
struct WireInstanceNode: AstNode
{
IdentifierNode name;
std::optional<CountNode> position;
std::optional<DisplayNode> display;
};
struct InstanceAttributeNode: AstNode
{
IdentifierNode name;
ValueNode value;
};
struct InstanceNode: AstNode
{
IdentifierNode name;
IdentifierNode component;
std::optional<CountNode> position;
std::vector<InstanceAttributeNode> attributes;
std::optional<NumberNode> size;
};
struct ConnectionInstanceNode: AstNode
{
IdentifierNode instance;
IdentifierNode pin;
IdentifierNode bus;
std::optional<IdentifierNode> wire;
std::vector<InstanceAttributeNode> attributes;
};
struct SchemaNode: AstNode
{
std::optional<StringNode> source;
std::vector<InstanceNode> instances;
std::vector<WireInstanceNode> wires;
std::vector<ConnectionInstanceNode> connections;
std::optional<LibraryNode> library;
};
#endif // ASTNODE_H
+224 -43
View File
@@ -360,7 +360,7 @@ PResult<PropertyNode> ComdelParser::parseProperty(std::optional<TokenType> value
return unexpected();
}
}
Value value;
ValueNode value;
ASSIGN_OR_RETURN_IF_ERR(value, parseValue());
RETURN_IF_NOT_TOKEN(TokenType::SEMICOLON);
@@ -374,14 +374,14 @@ PResult<PropertyNode> ComdelParser::parseProperty(std::optional<TokenType> value
/****************************************************************************
*
* AddressSpace := "@address" + IDENTIFIER "(" + NUMER + "," + NUMBER + ")"
* AddressSpaceNode := "@address" + IDENTIFIER "(" + NUMER + "," + NUMBER + ")"
*
****************************************************************************/
PResult<AddressSpace> ComdelParser::parseAddress()
PResult<AddressSpaceNode> ComdelParser::parseAddress()
{
auto spanner = getSpanner();
AddressSpace addressSpace{};
AddressSpaceNode addressSpace{};
RETURN_IF_NOT_TOKEN(TokenType::KW_ADDRESS);
@@ -439,7 +439,7 @@ PResult<ComponentNode> ComdelParser::parseComponent()
} else if(check(TokenType::KW_DISPLAY)) {
ASSIGN_OR_RETURN_IF_ERR(component.display, parseDisplay());
} else if(check(TokenType::KW_PIN)) {
APPEND_OR_RETURN_IF_ERR(component.pin, parsePin());
APPEND_OR_RETURN_IF_ERR(component.pins, parsePin());
} else if(check(TokenType::KW_ATTRIBUTE)) {
APPEND_OR_RETURN_IF_ERR(component.attributes, parseAttribute());
} else if(check(TokenType::KW_RULE)) {
@@ -697,13 +697,13 @@ PResult<AttributeNode> ComdelParser::parseAttribute() {
}
if(check(TokenType::INT_TYPE)) {
attribute.type = Value::INT;
attribute.type = ValueNode::INT;
} else if(check(TokenType::STRING_TYPE)) {
attribute.type = Value::STRING;
attribute.type = ValueNode::STRING;
} else if(check(TokenType::BOOL_TYPE)) {
attribute.type = Value::BOOL;
attribute.type = ValueNode::BOOL;
} else if(check(TokenType::WIRE_TYPE)) {
attribute.type = Value::IDENTIFIER;
attribute.type = ValueNode::IDENTIFIER;
} else {
return unexpected();
}
@@ -711,32 +711,32 @@ PResult<AttributeNode> ComdelParser::parseAttribute() {
RETURN_IF_NOT_TOKEN(TokenType::DEFAULT);
if(attribute.type == Value::BOOL) {
if(attribute.type == ValueNode::BOOL) {
if(check(TokenType::TRUE)) {
attribute.defaultValue = Value::ofBool(true);
attribute.defaultValue = ValueNode::ofBool(true);
} else if(check(TokenType::FALSE)) {
attribute.defaultValue = Value::ofBool(false);
attribute.defaultValue = ValueNode::ofBool(false);
} else {
return unexpected();
}
} else if(attribute.type == Value::INT) {
} else if(attribute.type == ValueNode::INT) {
if(check(TokenType::NUMBER)) {
auto number = parseNumber();
attribute.defaultValue = Value::ofInt(number->value);
attribute.defaultValue = ValueNode::ofInt(number->value);
} else {
return unexpected();
}
} else if(attribute.type == Value::STRING) {
} else if(attribute.type == ValueNode::STRING) {
if(check(TokenType::STRING)) {
auto string = parseString();
attribute.defaultValue = Value::ofString(string->value);
attribute.defaultValue = ValueNode::ofString(string->value);
} else {
return unexpected();
}
} else if(attribute.type == Value::IDENTIFIER) {
} else if(attribute.type == ValueNode::IDENTIFIER) {
if(check(TokenType::IDENTIFIER)) {
auto identifier = parseIdentifier();
attribute.defaultValue = Value::ofIdentifier(identifier->value);
attribute.defaultValue = ValueNode::ofIdentifier(identifier->value);
} else {
return unexpected();
}
@@ -744,14 +744,14 @@ PResult<AttributeNode> ComdelParser::parseAttribute() {
if(check(TokenType::LBRACE)) {
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
Popup popup;
PopupNode popup;
if(!check(TokenType::KW_POPUP)) {
return unexpected();
}
ASSIGN_OR_RETURN_IF_ERR(popup, parsePopup());
attribute.popup = std::optional<Popup>(popup);
attribute.popup = std::optional<PopupNode>(popup);
RETURN_IF_NOT_TOKEN(TokenType::RBRACE);
}
@@ -770,7 +770,7 @@ PResult<EnumerationNode> ComdelParser::parseEnumeration() {
ASSIGN_OR_RETURN_IF_ERR(key, parseString());
RETURN_IF_NOT_TOKEN(TokenType::EQUALS);
Value value;
ValueNode value;
ASSIGN_OR_RETURN_IF_ERR(value, parseValue());
EnumerationNode node;
@@ -782,26 +782,26 @@ PResult<EnumerationNode> ComdelParser::parseEnumeration() {
/****************************************************************************
*
* Popup := "@popup " + ("automatic" | "on_demand") { POPUP BODY }
* PopupNode := "@popup " + ("automatic" | "on_demand") { POPUP BODY }
*
****************************************************************************/
PResult<Popup> ComdelParser::parsePopup() {
PResult<PopupNode> ComdelParser::parsePopup() {
auto spanner = getSpanner();
Popup popup;
PopupNode popup;
RETURN_IF_NOT_TOKEN(TokenType::KW_POPUP);
if(check(TokenType::IDENTIFIER)) {
auto type = parseIdentifier();
if(type.value().value == "automatic") {
popup.type = Popup::AUTOMATIC;
popup.type = PopupNode::AUTOMATIC;
} else if(type.value().value == "on_demand") {
popup.type = Popup::ON_DEMAND;
popup.type = PopupNode::ON_DEMAND;
} else {
return PError(SourceError{current().span, "expected type 'automatic', 'on_demand'"});
}
} else {
popup.type = Popup::ON_DEMAND;
popup.type = PopupNode::ON_DEMAND;
}
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
@@ -880,12 +880,12 @@ PResult<ConnectionNode> ComdelParser::parseConnection() {
/****************************************************************************
*
* Rule := "@rule {" + if-else statements + "}"
* RuleNode := "@rule {" + if-else statements + "}"
*
****************************************************************************/
PResult<Rule> ComdelParser::parseRule() {
PResult<RuleNode> ComdelParser::parseRule() {
auto spanner = getSpanner();
Rule rule;
RuleNode rule;
RETURN_IF_NOT_TOKEN(TokenType::KW_RULE);
@@ -910,9 +910,9 @@ PResult<Rule> ComdelParser::parseRule() {
* IfStatement := "if(!function(params...)) { error(MESSAGE) | warning(MESSAGE) }
*
****************************************************************************/
PResult<IfStmt> ComdelParser::parseIfStatement() {
PResult<IfStatementnode> ComdelParser::parseIfStatement() {
auto spanner = getSpanner();
IfStmt ifStatement;
IfStatementnode ifStatement;
RETURN_IF_NOT_TOKEN(TokenType::IF);
@@ -927,7 +927,7 @@ PResult<IfStmt> ComdelParser::parseIfStatement() {
ASSIGN_OR_RETURN_IF_ERR(ifStatement.condition.functionName, parseIdentifier());
ASSIGN_OR_RETURN_IF_ERR(ifStatement.condition.params, parseList<Value>(std::optional<TokenType>(TokenType::LPAREN),
ASSIGN_OR_RETURN_IF_ERR(ifStatement.condition.params, parseList<ValueNode>(std::optional<TokenType>(TokenType::LPAREN),
TokenType::RPAREN,
TokenType::COMMA,
false,
@@ -939,9 +939,9 @@ PResult<IfStmt> ComdelParser::parseIfStatement() {
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
if(check(TokenType::ERROR)) {
ifStatement.action.type = Action::ERROR;
ifStatement.action.type = ActionNode::ERROR;
} else if(check(TokenType::WARNING)) {
ifStatement.action.type = Action::WARNING;
ifStatement.action.type = ActionNode::WARNING;
} else {
return unexpected();
}
@@ -957,27 +957,208 @@ PResult<IfStmt> ComdelParser::parseIfStatement() {
return spanner(ifStatement);
}
PResult<Value> ComdelParser::parseValue() {
PResult<ValueNode> ComdelParser::parseValue() {
auto spanner = getSpanner();
Value value;
ValueNode value;
if(check(TokenType::IDENTIFIER)) {
value = Value::ofIdentifier(parseIdentifier()->value);
value = ValueNode::ofIdentifier(parseIdentifier()->value);
} else if(check(TokenType::STRING)) {
value = Value::ofString(parseString()->value);
value = ValueNode::ofString(parseString()->value);
} else if(check(TokenType::NUMBER)) {
value = Value::ofInt(parseNumber()->value);
value = ValueNode::ofInt(parseNumber()->value);
} else if(check(TokenType::TRUE)) {
value = Value::ofBool(true);
value = ValueNode::ofBool(true);
} else if(check(TokenType::FALSE)) {
value = Value::ofBool(false);
value = ValueNode::ofBool(false);
} else {
return unexpected();
}
return spanner(value);
//return spanner(value);
return value;
}
std::optional<SchemaNode> ComdelParser::parseSchema() {
auto spanner = getSpanner();
SchemaNode schema{};
if(check(TokenType::KW_SOURCE)) {
bump();
if(check(TokenType::STRING)) {
auto source = parseString();
schema.source = *source;
} else {
errors.push_back(SourceError{current().span, "expected `@source`"});
return std::nullopt;
}
} else {
errors.push_back(SourceError{current().span, "expected `@source`"});
return std::nullopt;
}
if(!check(TokenType::KW_SCHEMA)) {
errors.push_back(SourceError{current().span, "expected `@schema`"});
return std::nullopt;
}
bump();
if(!check(TokenType::LBRACE)) {
errors.push_back(SourceError{current().span, "expected `{`"});
return std::nullopt;
}
bump();
while ( ! check(TokenType::RBRACE) ) {
PResult<poly<AstNode>> err;
if(check(TokenType::KW_INSTANCE)){
APPEND_OR_SET_ERR(schema.instances, parseInstance());
} else if(check(TokenType::KW_WIRE)) {
APPEND_OR_SET_ERR(schema.wires, parseWireInstance());
} else if(check(TokenType::KW_CONNECTION)) {
APPEND_OR_SET_ERR(schema.connections, parseConnectionInstance());
} else {
err = unexpected();
}
if(!err.has_value()) {
errors.push_back(err.error());
break;
}
}
if(!check(TokenType::RBRACE)) {
errors.push_back(SourceError{current().span, "expected `}`"});
return std::nullopt;
} else {
bump();
}
if(!check(TokenType::END_OF_FILE)) {
errors.push_back(SourceError{current().span, "expected `EOF`"});
}
if (errors.size())
return std::nullopt;
return spanner(schema);
}
PResult<WireInstanceNode> ComdelParser::parseWireInstance() {
auto spanner = getSpanner();
WireInstanceNode wireInstance;
RETURN_IF_NOT_TOKEN(TokenType::KW_WIRE);
ASSIGN_OR_RETURN_IF_ERR(wireInstance.name, parseIdentifier());
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
while(!check(TokenType::RBRACE)) {
if(check(TokenType::KW_POSITION)) {
ASSIGN_OR_RETURN_IF_ERR(wireInstance.position, parsePosition());
} else if(check(TokenType::KW_DISPLAY)) {
ASSIGN_OR_RETURN_IF_ERR(wireInstance.display, parseDisplay());
} else {
return unexpected();
}
}
RETURN_IF_NOT_TOKEN(TokenType::RBRACE);
return spanner(wireInstance);
}
/****************************************************************************
*
* CountNode := "@position (" + NumberNode + "," + NumberNode + ")"
*
****************************************************************************/
PResult<CountNode> ComdelParser::parsePosition()
{
auto spanner = getSpanner();
RETURN_IF_NOT_TOKEN(TokenType::KW_POSITION);
RETURN_IF_NOT_TOKEN(TokenType::LPAREN);
auto first = parseNumber();
if(!first.has_value()) {
return PError(first.error());
}
RETURN_IF_NOT_TOKEN(TokenType::COMMA);
auto second = parseNumber();
if(!second.has_value()) {
return PError(second.error());
}
RETURN_IF_NOT_TOKEN(TokenType::RPAREN);
return spanner(CountNode{first.value(), second.value()});
}
PResult<InstanceNode> ComdelParser::parseInstance() {
auto spanner = getSpanner();
RETURN_IF_NOT_TOKEN(TokenType::KW_INSTANCE);
InstanceNode instance;
ASSIGN_OR_RETURN_IF_ERR(instance.name, parseIdentifier());
ASSIGN_OR_RETURN_IF_ERR(instance.component, parseIdentifier());
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
while(!check(TokenType::RBRACE)) {
if(check(TokenType::KW_POSITION)) {
ASSIGN_OR_RETURN_IF_ERR(instance.position, parsePosition());
} else if(check(TokenType::KW_ATTRIBUTE)) {
APPEND_OR_RETURN_IF_ERR(instance.attributes, parseInstanceAttribute());
} else if(check(TokenType::KW_SIZE)) {
bump();
auto number = parseNumber();
RETURN_IF_ERR(number);
instance.size = *number;
} else {
return unexpected();
}
}
RETURN_IF_NOT_TOKEN(TokenType::RBRACE);
return spanner(instance);
}
PResult<InstanceAttributeNode> ComdelParser::parseInstanceAttribute() {
auto spanner = getSpanner();
RETURN_IF_NOT_TOKEN(TokenType::KW_ATTRIBUTE);
InstanceAttributeNode attribute;
ASSIGN_OR_RETURN_IF_ERR(attribute.name, parseIdentifier());
ASSIGN_OR_RETURN_IF_ERR(attribute.value, parseValue());
return spanner(attribute);
}
PResult<ConnectionInstanceNode> ComdelParser::parseConnectionInstance() {
auto spanner = getSpanner();
RETURN_IF_NOT_TOKEN(TokenType::KW_CONNECTION);
ConnectionInstanceNode connection;
RETURN_IF_NOT_TOKEN(TokenType::LPAREN);
ASSIGN_OR_RETURN_IF_ERR(connection.instance, parseIdentifier());
RETURN_IF_NOT_TOKEN(TokenType::DOT);
ASSIGN_OR_RETURN_IF_ERR(connection.pin, parseIdentifier());
RETURN_IF_NOT_TOKEN(TokenType::COMMA);
ASSIGN_OR_RETURN_IF_ERR(connection.bus, parseIdentifier());
RETURN_IF_NOT_TOKEN(TokenType::RPAREN);
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
while(!check(TokenType::RBRACE)) {
if(check(TokenType::KW_WIRE)) {
bump();
ASSIGN_OR_RETURN_IF_ERR(connection.wire, parseIdentifier());
} else if(check(TokenType::KW_ATTRIBUTE)) {
APPEND_OR_RETURN_IF_ERR(connection.attributes, parseInstanceAttribute());
} else {
return unexpected();
}
}
RETURN_IF_NOT_TOKEN(TokenType::RBRACE);
return spanner(connection);
}
+13 -6
View File
@@ -27,7 +27,7 @@ public:
template <typename T, typename = std::enable_if<std::is_base_of<AstNode, T>::value>>
typename std::remove_reference_t<T> operator()(T&& astNode) const {
//astNode.span = lo.to(prevSpan);
astNode.span = lo.to(prevSpan);
return std::move(astNode);
}
};
@@ -71,22 +71,29 @@ private:
PResult<EnumerationNode> parseEnumeration();
PResult<ComponentNode> parseComponent();
PResult<AddressSpace> parseAddress();
PResult<AddressSpaceNode> parseAddress();
PResult<PinNode> parsePin();
PResult<DisplayNode> parseDisplay();
PResult<PinConnectionNode> parsePinConnection();
PResult<AttributeNode> parseAttribute();
PResult<Popup> parsePopup();
PResult<Rule> parseRule();
PResult<PopupNode> parsePopup();
PResult<RuleNode> parseRule();
PResult<BusNode> parseBus();
PResult<WireNode> parseWire();
PResult<ConnectionNode> parseConnection();
PResult<DisplayItemNode> parseDisplayItem();
PResult<IfStmt> parseIfStatement();
PResult<Value> parseValue();
PResult<IfStatementnode> parseIfStatement();
PResult<ValueNode> parseValue();
PResult<WireInstanceNode> parseWireInstance();
PResult<CountNode> parsePosition();
PResult<InstanceNode> parseInstance();
PResult<InstanceAttributeNode> parseInstanceAttribute();
PResult<ConnectionInstanceNode> parseConnectionInstance();
public:
ComdelParser(std::vector<Token> tokens);
std::optional<SchemaNode> parseSchema();
std::optional<LibraryNode> parse();
const std::vector<SourceError>& getErrors();
};
+41
View File
@@ -40,3 +40,44 @@ std::optional<LibraryNode> loadLibraryFromFile(ParseContext * parseContext,
return *unit;
}
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;
}
+4
View File
@@ -8,4 +8,8 @@ std::optional<LibraryNode> loadLibraryFromFile(ParseContext * parseContext,
const char* name,
std::ostream& stream);
std::optional<SchemaNode> loadSchemaFromFile(ParseContext * parseContext,
const char* name,
std::ostream& stream);
#endif // PARSERUTIL_H
+1 -1
View File
@@ -128,7 +128,7 @@ TokenTables::TokenTables() {
add( TokenType::PIN_OUT, "out", TOKENIZABLE),
add( TokenType::PIN_IN_OUT, "inOut", TOKENIZABLE),
// Action types
// ActionNode types
add( TokenType::ERROR, "error", TOKENIZABLE),
add( TokenType::WARNING, "warning", TOKENIZABLE),