Updated error handling while parsing *.csl files
This commit is contained in:
parent
d6c1023df2
commit
dde9bb8af8
|
@ -145,6 +145,30 @@ ComdelParser::parseList(std::optional<TokenType> openDelim,
|
||||||
return vec;
|
return vec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ComdelParser::skipUntilNextKeyword() {
|
||||||
|
int depth = 0;
|
||||||
|
bool enteredBlock = false;
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
if(is_keyword(current().type) && (!enteredBlock || (enteredBlock && depth == 0))) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(check(TokenType::LBRACE)) {
|
||||||
|
enteredBlock = true;
|
||||||
|
depth++;
|
||||||
|
} else if(check(TokenType::RBRACE)) {
|
||||||
|
if(depth == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
depth--;
|
||||||
|
} else if(check(TokenType::END_OF_FILE)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bump();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const std::vector<SourceError> &ComdelParser::getErrors()
|
const std::vector<SourceError> &ComdelParser::getErrors()
|
||||||
{
|
{
|
||||||
return errors;
|
return errors;
|
||||||
|
@ -241,12 +265,17 @@ std::optional<LibraryNode> ComdelParser::parse()
|
||||||
false,
|
false,
|
||||||
[this]{return parseProperty(std::optional<TokenType>(TokenType::STRING));}
|
[this]{return parseProperty(std::optional<TokenType>(TokenType::STRING));}
|
||||||
));
|
));
|
||||||
|
if(!err.has_value()) {
|
||||||
|
skipUntilNextKeyword();
|
||||||
|
bump();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
err = unexpected();
|
err = unexpected();
|
||||||
|
bump();
|
||||||
}
|
}
|
||||||
if(!err.has_value()) {
|
if(!err.has_value()) {
|
||||||
errors.push_back(err.error());
|
errors.push_back(err.error());
|
||||||
break;
|
skipUntilNextKeyword();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -417,25 +446,32 @@ PResult<ComponentNode> ComdelParser::parseComponent()
|
||||||
PResult<poly<AstNode>> err;
|
PResult<poly<AstNode>> err;
|
||||||
if(check(TokenType::KW_INSTANCE_NAME)) {
|
if(check(TokenType::KW_INSTANCE_NAME)) {
|
||||||
bump();
|
bump();
|
||||||
ASSIGN_OR_RETURN_IF_ERR(component.instanceName, parseString());
|
ASSIGN_OR_SET_ERR(component.instanceName, parseString());
|
||||||
} else if(check(TokenType::KW_TOOLTIP)) {
|
} else if(check(TokenType::KW_TOOLTIP)) {
|
||||||
bump();
|
bump();
|
||||||
ASSIGN_OR_RETURN_IF_ERR(component.tooltip, parseString());
|
ASSIGN_OR_SET_ERR(component.tooltip, parseString());
|
||||||
} else if(check(TokenType::KW_SOURCE)) {
|
} else if(check(TokenType::KW_SOURCE)) {
|
||||||
bump();
|
bump();
|
||||||
ASSIGN_OR_RETURN_IF_ERR(component.source, parseString());
|
ASSIGN_OR_SET_ERR(component.source, parseString());
|
||||||
} else if(check(TokenType::KW_COUNT)) {
|
} else if(check(TokenType::KW_COUNT)) {
|
||||||
ASSIGN_OR_RETURN_IF_ERR(component.count, parseCount());
|
ASSIGN_OR_SET_ERR(component.count, parseCount());
|
||||||
} else if(check(TokenType::KW_DISPLAY)) {
|
} else if(check(TokenType::KW_DISPLAY)) {
|
||||||
ASSIGN_OR_RETURN_IF_ERR(component.display, parseDisplay());
|
ASSIGN_OR_SET_ERR(component.display, parseDisplay());
|
||||||
} else if(check(TokenType::KW_PIN)) {
|
} else if(check(TokenType::KW_PIN)) {
|
||||||
APPEND_OR_RETURN_IF_ERR(component.pins, parsePin());
|
APPEND_OR_SET_ERR(component.pins, parsePin());
|
||||||
} else if(check(TokenType::KW_ATTRIBUTE)) {
|
} else if(check(TokenType::KW_ATTRIBUTE)) {
|
||||||
APPEND_OR_RETURN_IF_ERR(component.attributes, parseAttribute());
|
APPEND_OR_SET_ERR(component.attributes, parseAttribute());
|
||||||
} else if(check(TokenType::KW_RULE)) {
|
} else if(check(TokenType::KW_RULE)) {
|
||||||
APPEND_OR_RETURN_IF_ERR(component.rules, parseRule());
|
APPEND_OR_SET_ERR(component.rules, parseRule());
|
||||||
} else {
|
} else {
|
||||||
return unexpected();
|
err = unexpected();
|
||||||
|
}
|
||||||
|
if(!err.has_value()) {
|
||||||
|
errors.push_back(err.error());
|
||||||
|
skipUntilNextKeyword();
|
||||||
|
if(check(TokenType::END_OF_FILE)) {
|
||||||
|
return PError({Span(spanner.lo), "Reached EOF"});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -526,6 +562,7 @@ PResult<BusNode> ComdelParser::parseBus() {
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
||||||
|
|
||||||
while(!check(TokenType::RBRACE)) {
|
while(!check(TokenType::RBRACE)) {
|
||||||
|
PResult<poly<AstNode>> err;
|
||||||
if(check(TokenType::KW_TOOLTIP)) {
|
if(check(TokenType::KW_TOOLTIP)) {
|
||||||
bump();
|
bump();
|
||||||
ASSIGN_OR_RETURN_IF_ERR(bus.tooltip, parseString());
|
ASSIGN_OR_RETURN_IF_ERR(bus.tooltip, parseString());
|
||||||
|
@ -545,7 +582,14 @@ PResult<BusNode> ComdelParser::parseBus() {
|
||||||
}
|
}
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::RBRACE);
|
RETURN_IF_NOT_TOKEN(TokenType::RBRACE);
|
||||||
} else {
|
} else {
|
||||||
return unexpected();
|
err = unexpected();
|
||||||
|
}
|
||||||
|
if(!err.has_value()) {
|
||||||
|
errors.push_back(err.error());
|
||||||
|
skipUntilNextKeyword();
|
||||||
|
if(check(TokenType::END_OF_FILE)) {
|
||||||
|
return PError({Span(spanner.lo), "Reached EOF"});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -668,13 +712,14 @@ PResult<PinNode> ComdelParser::parsePin() {
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
||||||
|
|
||||||
while(!check(TokenType::RBRACE)) {
|
while(!check(TokenType::RBRACE)) {
|
||||||
|
PResult<poly<AstNode>> err;
|
||||||
if (check(TokenType::KW_TOOLTIP)) {
|
if (check(TokenType::KW_TOOLTIP)) {
|
||||||
bump();
|
bump();
|
||||||
ASSIGN_OR_RETURN_IF_ERR(pin.tooltip, parseString());
|
ASSIGN_OR_SET_ERR(pin.tooltip, parseString());
|
||||||
} else if (check(TokenType::KW_DISPLAY)) {
|
} else if (check(TokenType::KW_DISPLAY)) {
|
||||||
ASSIGN_OR_RETURN_IF_ERR(pin.display, parseDisplay());
|
ASSIGN_OR_SET_ERR(pin.display, parseDisplay());
|
||||||
} else if (check(TokenType::KW_CONNECTION)) {
|
} else if (check(TokenType::KW_CONNECTION)) {
|
||||||
ASSIGN_OR_RETURN_IF_ERR(pin.connection, parsePinConnection());
|
ASSIGN_OR_SET_ERR(pin.connection, parsePinConnection());
|
||||||
} else if (check(TokenType::KW_WIRES)){
|
} else if (check(TokenType::KW_WIRES)){
|
||||||
bump();
|
bump();
|
||||||
auto wires = parseList<ValueNode>(std::optional<TokenType>(TokenType::LBRACE), TokenType::RBRACE, std::optional<TokenType>(TokenType::COMMA), false,
|
auto wires = parseList<ValueNode>(std::optional<TokenType>(TokenType::LBRACE), TokenType::RBRACE, std::optional<TokenType>(TokenType::COMMA), false,
|
||||||
|
@ -682,7 +727,14 @@ PResult<PinNode> ComdelParser::parsePin() {
|
||||||
RETURN_IF_ERR(wires);
|
RETURN_IF_ERR(wires);
|
||||||
pin.wires = *wires;
|
pin.wires = *wires;
|
||||||
} else {
|
} else {
|
||||||
return unexpected();
|
err = unexpected();
|
||||||
|
}
|
||||||
|
if(!err.has_value()) {
|
||||||
|
errors.push_back(err.error());
|
||||||
|
skipUntilNextKeyword();
|
||||||
|
if(check(TokenType::END_OF_FILE)) {
|
||||||
|
return PError({Span(spanner.lo), "Reached EOF"});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -873,18 +925,19 @@ PResult<PopupNode> ComdelParser::parsePopup() {
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
||||||
|
|
||||||
while(!check(TokenType::RBRACE)) {
|
while(!check(TokenType::RBRACE)) {
|
||||||
|
PResult<poly<AstNode>> err;
|
||||||
if(check(TokenType::KW_TITLE)) {
|
if(check(TokenType::KW_TITLE)) {
|
||||||
bump();
|
bump();
|
||||||
ASSIGN_OR_RETURN_IF_ERR(popup.title, parseString());
|
ASSIGN_OR_SET_ERR(popup.title, parseString());
|
||||||
} else if(check(TokenType::KW_TEXT)) {
|
} else if(check(TokenType::KW_TEXT)) {
|
||||||
bump();
|
bump();
|
||||||
ASSIGN_OR_RETURN_IF_ERR(popup.text, parseString());
|
ASSIGN_OR_SET_ERR(popup.text, parseString());
|
||||||
} else if(check(TokenType::KW_RULE)) {
|
} else if(check(TokenType::KW_RULE)) {
|
||||||
APPEND_OR_RETURN_IF_ERR(popup.rules, parseRule());
|
APPEND_OR_SET_ERR(popup.rules, parseRule());
|
||||||
} else if(check(TokenType::KW_ENUMERATED)) {
|
} else if(check(TokenType::KW_ENUMERATED)) {
|
||||||
bump();
|
bump();
|
||||||
popup.enumerated = true;
|
popup.enumerated = true;
|
||||||
ASSIGN_OR_RETURN_IF_ERR(popup.enumeration,
|
ASSIGN_OR_SET_ERR(popup.enumeration,
|
||||||
parseList<EnumerationNode>(
|
parseList<EnumerationNode>(
|
||||||
std::optional<TokenType>(TokenType::LBRACE),
|
std::optional<TokenType>(TokenType::LBRACE),
|
||||||
TokenType::RBRACE,
|
TokenType::RBRACE,
|
||||||
|
@ -894,7 +947,14 @@ PResult<PopupNode> ComdelParser::parsePopup() {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return unexpected();
|
err = unexpected();
|
||||||
|
}
|
||||||
|
if(!err.has_value()) {
|
||||||
|
errors.push_back(err.error());
|
||||||
|
skipUntilNextKeyword();
|
||||||
|
if(check(TokenType::END_OF_FILE)) {
|
||||||
|
return PError({Span(spanner.lo), "Reached EOF"});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -938,6 +998,7 @@ PResult<ConnectionNode> ComdelParser::parseConnection() {
|
||||||
int wireCount = 0;
|
int wireCount = 0;
|
||||||
|
|
||||||
while(!check(TokenType::RBRACE)) {
|
while(!check(TokenType::RBRACE)) {
|
||||||
|
PResult<poly<AstNode>> err;
|
||||||
if (check(TokenType::KW_ATTRIBUTE)) {
|
if (check(TokenType::KW_ATTRIBUTE)) {
|
||||||
APPEND_OR_RETURN_IF_ERR(connection.attributes, parseAttribute());
|
APPEND_OR_RETURN_IF_ERR(connection.attributes, parseAttribute());
|
||||||
} else if(check(TokenType::KW_WIRES)) {
|
} else if(check(TokenType::KW_WIRES)) {
|
||||||
|
@ -954,7 +1015,14 @@ PResult<ConnectionNode> ComdelParser::parseConnection() {
|
||||||
}
|
}
|
||||||
wireCount++;
|
wireCount++;
|
||||||
} else {
|
} else {
|
||||||
return unexpected();
|
err = unexpected();
|
||||||
|
}
|
||||||
|
if(!err.has_value()) {
|
||||||
|
errors.push_back(err.error());
|
||||||
|
skipUntilNextKeyword();
|
||||||
|
if(check(TokenType::END_OF_FILE)) {
|
||||||
|
return PError({Span(spanner.lo), "Reached EOF"});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1108,10 +1176,11 @@ std::optional<SchemaNode> ComdelParser::parseSchema() {
|
||||||
APPEND_OR_SET_ERR(schema.connections, parseConnectionInstance());
|
APPEND_OR_SET_ERR(schema.connections, parseConnectionInstance());
|
||||||
} else {
|
} else {
|
||||||
err = unexpected();
|
err = unexpected();
|
||||||
|
bump();
|
||||||
}
|
}
|
||||||
if(!err.has_value()) {
|
if(!err.has_value()) {
|
||||||
errors.push_back(err.error());
|
errors.push_back(err.error());
|
||||||
break;
|
skipUntilNextKeyword();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!check(TokenType::RBRACE)) {
|
if(!check(TokenType::RBRACE)) {
|
||||||
|
@ -1139,12 +1208,20 @@ PResult<WireInstanceNode> ComdelParser::parseWireInstance() {
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
||||||
|
|
||||||
while(!check(TokenType::RBRACE)) {
|
while(!check(TokenType::RBRACE)) {
|
||||||
|
PResult<poly<AstNode>> err;
|
||||||
if(check(TokenType::KW_POSITION)) {
|
if(check(TokenType::KW_POSITION)) {
|
||||||
ASSIGN_OR_RETURN_IF_ERR(wireInstance.position, parsePosition());
|
ASSIGN_OR_SET_ERR(wireInstance.position, parsePosition());
|
||||||
} else if(check(TokenType::KW_DISPLAY)) {
|
} else if(check(TokenType::KW_DISPLAY)) {
|
||||||
ASSIGN_OR_RETURN_IF_ERR(wireInstance.display, parseDisplay());
|
ASSIGN_OR_SET_ERR(wireInstance.display, parseDisplay());
|
||||||
} else {
|
} else {
|
||||||
return unexpected();
|
err = unexpected();
|
||||||
|
}
|
||||||
|
if(!err.has_value()) {
|
||||||
|
errors.push_back(err.error());
|
||||||
|
skipUntilNextKeyword();
|
||||||
|
if(check(TokenType::END_OF_FILE)) {
|
||||||
|
return PError({Span(spanner.lo), "Reached EOF"});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1192,17 +1269,25 @@ PResult<InstanceNode> ComdelParser::parseInstance() {
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
||||||
|
|
||||||
while(!check(TokenType::RBRACE)) {
|
while(!check(TokenType::RBRACE)) {
|
||||||
|
PResult<poly<AstNode>> err;
|
||||||
if(check(TokenType::KW_POSITION)) {
|
if(check(TokenType::KW_POSITION)) {
|
||||||
ASSIGN_OR_RETURN_IF_ERR(instance.position, parsePosition());
|
ASSIGN_OR_SET_ERR(instance.position, parsePosition());
|
||||||
} else if(check(TokenType::KW_ATTRIBUTE)) {
|
} else if(check(TokenType::KW_ATTRIBUTE)) {
|
||||||
APPEND_OR_RETURN_IF_ERR(instance.attributes, parseInstanceAttribute());
|
APPEND_OR_SET_ERR(instance.attributes, parseInstanceAttribute());
|
||||||
} else if(check(TokenType::KW_SIZE)) {
|
} else if(check(TokenType::KW_SIZE)) {
|
||||||
bump();
|
bump();
|
||||||
auto number = parseNumber();
|
auto number = parseNumber();
|
||||||
RETURN_IF_ERR(number);
|
RETURN_IF_ERR(number);
|
||||||
instance.size = *number;
|
instance.size = *number;
|
||||||
} else {
|
} else {
|
||||||
return unexpected();
|
err = unexpected();
|
||||||
|
}
|
||||||
|
if(!err.has_value()) {
|
||||||
|
errors.push_back(err.error());
|
||||||
|
skipUntilNextKeyword();
|
||||||
|
if(check(TokenType::END_OF_FILE)) {
|
||||||
|
return PError({Span(spanner.lo), "Reached EOF"});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1247,13 +1332,21 @@ PResult<ConnectionInstanceNode> ComdelParser::parseConnectionInstance() {
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
||||||
|
|
||||||
while(!check(TokenType::RBRACE)) {
|
while(!check(TokenType::RBRACE)) {
|
||||||
|
PResult<poly<AstNode>> err;
|
||||||
if(check(TokenType::KW_WIRE)) {
|
if(check(TokenType::KW_WIRE)) {
|
||||||
bump();
|
bump();
|
||||||
ASSIGN_OR_RETURN_IF_ERR(connection.wire, parseIdentifier());
|
ASSIGN_OR_SET_ERR(connection.wire, parseIdentifier());
|
||||||
} else if(check(TokenType::KW_ATTRIBUTE)) {
|
} else if(check(TokenType::KW_ATTRIBUTE)) {
|
||||||
APPEND_OR_RETURN_IF_ERR(connection.attributes, parseInstanceAttribute());
|
APPEND_OR_SET_ERR(connection.attributes, parseInstanceAttribute());
|
||||||
} else {
|
} else {
|
||||||
return unexpected();
|
err = unexpected();
|
||||||
|
}
|
||||||
|
if(!err.has_value()) {
|
||||||
|
errors.push_back(err.error());
|
||||||
|
skipUntilNextKeyword();
|
||||||
|
if(check(TokenType::END_OF_FILE)) {
|
||||||
|
return PError({Span(spanner.lo), "Reached EOF"});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,13 +16,14 @@
|
||||||
/// Spanner's call operator MOVES from the node so it should
|
/// Spanner's call operator MOVES from the node so it should
|
||||||
/// be always used last.
|
/// be always used last.
|
||||||
class Spanner {
|
class Spanner {
|
||||||
const Span lo; // the low end of the span, beginning of the node
|
|
||||||
|
|
||||||
// REFERENCE to the parser's prevSpan. After parsing a node this will
|
// REFERENCE to the parser's prevSpan. After parsing a node this will
|
||||||
// "point" to the span of the last token contained in the node.
|
// "point" to the span of the last token contained in the node.
|
||||||
const Span& prevSpan;
|
const Span& prevSpan;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
const Span lo; // the low end of the span, beginning of the node
|
||||||
|
|
||||||
|
|
||||||
Spanner(Span lo, Span& prevSpan) : lo(lo), prevSpan(prevSpan) {}
|
Spanner(Span lo, Span& prevSpan) : lo(lo), prevSpan(prevSpan) {}
|
||||||
|
|
||||||
template <typename T, typename = std::enable_if<std::is_base_of<AstNode, T>::value>>
|
template <typename T, typename = std::enable_if<std::is_base_of<AstNode, T>::value>>
|
||||||
|
@ -48,6 +49,8 @@ private:
|
||||||
bool consume(TokenType tokenType);
|
bool consume(TokenType tokenType);
|
||||||
bool check(TokenType tokenType);
|
bool check(TokenType tokenType);
|
||||||
|
|
||||||
|
void skipUntilNextKeyword();
|
||||||
|
|
||||||
Token ¤t();
|
Token ¤t();
|
||||||
|
|
||||||
[[nodiscard]] PError unexpected();
|
[[nodiscard]] PError unexpected();
|
||||||
|
@ -61,7 +64,6 @@ private:
|
||||||
|
|
||||||
Spanner getSpanner();
|
Spanner getSpanner();
|
||||||
|
|
||||||
|
|
||||||
PResult<StringNode> parseString();
|
PResult<StringNode> parseString();
|
||||||
PResult<IdentifierNode> parseIdentifier();
|
PResult<IdentifierNode> parseIdentifier();
|
||||||
PResult<NumberNode> parseNumber();
|
PResult<NumberNode> parseNumber();
|
||||||
|
|
|
@ -20,6 +20,7 @@ struct TokenTables {
|
||||||
std::unordered_map<std::string, TokenType> keywords;
|
std::unordered_map<std::string, TokenType> keywords;
|
||||||
|
|
||||||
TokenType tokenize(std::string value, TokenType initial);
|
TokenType tokenize(std::string value, TokenType initial);
|
||||||
|
bool is_keyword(TokenType token);
|
||||||
|
|
||||||
void add(TokenType tokenType, const std::string& txt,
|
void add(TokenType tokenType, const std::string& txt,
|
||||||
unsigned short attribs = 0);
|
unsigned short attribs = 0);
|
||||||
|
@ -41,7 +42,7 @@ void TokenTables::add (TokenType tokenType, const std::string& txt,
|
||||||
TokenTables::TokenTables() {
|
TokenTables::TokenTables() {
|
||||||
|
|
||||||
add( TokenType::IDENTIFIER, "identifier" );
|
add( TokenType::IDENTIFIER, "identifier" );
|
||||||
add( TokenType::KEYWORD, "keyword" );
|
add( TokenType::KEYWORD, "keyword" , KEYWORD_NAME);
|
||||||
|
|
||||||
// Literals (bool is not here, it has two keywords: false and true)
|
// Literals (bool is not here, it has two keywords: false and true)
|
||||||
add( TokenType::NUMBER, "number");
|
add( TokenType::NUMBER, "number");
|
||||||
|
@ -79,34 +80,34 @@ TokenTables::TokenTables() {
|
||||||
add( TokenType::NIL, "null", TOKENIZABLE),
|
add( TokenType::NIL, "null", TOKENIZABLE),
|
||||||
|
|
||||||
// all keywords
|
// all keywords
|
||||||
add( TokenType::KW_NAME, "@name", TOKENIZABLE),
|
add( TokenType::KW_NAME, "@name", TOKENIZABLE | KEYWORD_NAME),
|
||||||
add( TokenType::KW_INFO, "@info", TOKENIZABLE),
|
add( TokenType::KW_INFO, "@info", TOKENIZABLE | KEYWORD_NAME),
|
||||||
add( TokenType::KW_HEADER, "@header", TOKENIZABLE),
|
add( TokenType::KW_HEADER, "@header", TOKENIZABLE | KEYWORD_NAME),
|
||||||
add( TokenType::KW_DIRECTORY, "@directory", TOKENIZABLE),
|
add( TokenType::KW_DIRECTORY, "@directory", TOKENIZABLE | KEYWORD_NAME),
|
||||||
add( TokenType::KW_LIBRARY, "@library", TOKENIZABLE),
|
add( TokenType::KW_LIBRARY, "@library", TOKENIZABLE | KEYWORD_NAME),
|
||||||
add( TokenType::KW_ADDRESS, "@address", TOKENIZABLE),
|
add( TokenType::KW_ADDRESS, "@address", TOKENIZABLE | KEYWORD_NAME),
|
||||||
add( TokenType::KW_COMPONENT, "@component", TOKENIZABLE),
|
add( TokenType::KW_COMPONENT, "@component", TOKENIZABLE | KEYWORD_NAME),
|
||||||
add( TokenType::KW_MESSAGES, "@messages", TOKENIZABLE),
|
add( TokenType::KW_MESSAGES, "@messages", TOKENIZABLE | KEYWORD_NAME),
|
||||||
add( TokenType::KW_INSTANCE_NAME, "@instanceName", TOKENIZABLE),
|
add( TokenType::KW_INSTANCE_NAME, "@instanceName", TOKENIZABLE | KEYWORD_NAME),
|
||||||
add( TokenType::KW_COUNT, "@count", TOKENIZABLE),
|
add( TokenType::KW_COUNT, "@count", TOKENIZABLE | KEYWORD_NAME),
|
||||||
add( TokenType::KW_DISPLAY, "@display", TOKENIZABLE),
|
add( TokenType::KW_DISPLAY, "@display", TOKENIZABLE | KEYWORD_NAME),
|
||||||
add( TokenType::KW_PIN, "@pin", TOKENIZABLE),
|
add( TokenType::KW_PIN, "@pin", TOKENIZABLE | KEYWORD_NAME),
|
||||||
add( TokenType::KW_TOOLTIP, "@tooltip", TOKENIZABLE),
|
add( TokenType::KW_TOOLTIP, "@tooltip", TOKENIZABLE | KEYWORD_NAME),
|
||||||
add( TokenType::KW_CONNECTION, "@connection", TOKENIZABLE),
|
add( TokenType::KW_CONNECTION, "@connection", TOKENIZABLE | KEYWORD_NAME),
|
||||||
add( TokenType::KW_ATTRIBUTE, "@attribute", TOKENIZABLE),
|
add( TokenType::KW_ATTRIBUTE, "@attribute", TOKENIZABLE | KEYWORD_NAME),
|
||||||
add( TokenType::KW_SOURCE, "@source", TOKENIZABLE),
|
add( TokenType::KW_SOURCE, "@source", TOKENIZABLE | KEYWORD_NAME),
|
||||||
add( TokenType::KW_POPUP, "@popup", TOKENIZABLE),
|
add( TokenType::KW_POPUP, "@popup", TOKENIZABLE | KEYWORD_NAME),
|
||||||
add( TokenType::KW_RULE, "@rule", TOKENIZABLE),
|
add( TokenType::KW_RULE, "@rule", TOKENIZABLE | KEYWORD_NAME),
|
||||||
add( TokenType::KW_TITLE, "@title", TOKENIZABLE),
|
add( TokenType::KW_TITLE, "@title", TOKENIZABLE | KEYWORD_NAME),
|
||||||
add( TokenType::KW_TEXT, "@text", TOKENIZABLE),
|
add( TokenType::KW_TEXT, "@text", TOKENIZABLE | KEYWORD_NAME),
|
||||||
add( TokenType::KW_BUS, "@bus", TOKENIZABLE),
|
add( TokenType::KW_BUS, "@bus", TOKENIZABLE | KEYWORD_NAME),
|
||||||
add( TokenType::KW_WIRES, "@wires", TOKENIZABLE),
|
add( TokenType::KW_WIRES, "@wires", TOKENIZABLE | KEYWORD_NAME),
|
||||||
add( TokenType::KW_ENUMERATED, "@enumerated", TOKENIZABLE),
|
add( TokenType::KW_ENUMERATED, "@enumerated", TOKENIZABLE | KEYWORD_NAME),
|
||||||
add( TokenType::KW_WIRE, "@wire", TOKENIZABLE),
|
add( TokenType::KW_WIRE, "@wire", TOKENIZABLE | KEYWORD_NAME),
|
||||||
add( TokenType::KW_INSTANCE, "@instance", TOKENIZABLE),
|
add( TokenType::KW_INSTANCE, "@instance", TOKENIZABLE | KEYWORD_NAME),
|
||||||
add( TokenType::KW_SCHEMA, "@schema", TOKENIZABLE),
|
add( TokenType::KW_SCHEMA, "@schema", TOKENIZABLE | KEYWORD_NAME),
|
||||||
add( TokenType::KW_POSITION, "@position", TOKENIZABLE),
|
add( TokenType::KW_POSITION, "@position", TOKENIZABLE | KEYWORD_NAME),
|
||||||
add( TokenType::KW_SIZE, "@size", TOKENIZABLE),
|
add( TokenType::KW_SIZE, "@size", TOKENIZABLE | KEYWORD_NAME),
|
||||||
|
|
||||||
// All types
|
// All types
|
||||||
add( TokenType::INT_TYPE, "int", TOKENIZABLE),
|
add( TokenType::INT_TYPE, "int", TOKENIZABLE),
|
||||||
|
@ -156,6 +157,19 @@ TokenType TokenTables::tokenize(std::string value, TokenType initial) {
|
||||||
return initial;
|
return initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TokenTables::is_keyword(TokenType token) {
|
||||||
|
for(auto& [key, param]: allTokensInfo) {
|
||||||
|
if(param.attributes & KEYWORD_NAME && key == token) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
TokenType from_token(std::string value, TokenType initial) {
|
TokenType from_token(std::string value, TokenType initial) {
|
||||||
return tokenTables.tokenize(value, initial);
|
return tokenTables.tokenize(value, initial);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_keyword(TokenType tokenType) {
|
||||||
|
return tokenTables.is_keyword(tokenType);
|
||||||
}
|
}
|
|
@ -10,4 +10,6 @@ const std::string& tokenTypeToString(TokenType tokenType);
|
||||||
|
|
||||||
TokenType from_token(std::string value, TokenType initial);
|
TokenType from_token(std::string value, TokenType initial);
|
||||||
|
|
||||||
|
bool is_keyword(TokenType tokenType);
|
||||||
|
|
||||||
#endif // TOKENS_TYPE_H
|
#endif // TOKENS_TYPE_H
|
||||||
|
|
|
@ -93,7 +93,7 @@ void MainWindow::onLoadLibrary() {
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
buffer<<"Bad request"<<std::endl;
|
buffer<<"Failed loading library"<<std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,7 +158,7 @@ void MainWindow::onStoreScheme() {
|
||||||
|
|
||||||
for(auto &instance: schema->instances) {
|
for(auto &instance: schema->instances) {
|
||||||
auto componentInstance = dynamic_cast<domain::ComponentInstance*>(instance);
|
auto componentInstance = dynamic_cast<domain::ComponentInstance*>(instance);
|
||||||
if(componentInstance != NULL) {
|
if(componentInstance != nullptr) {
|
||||||
buffer << "\t" << "@instance " << componentInstance->name << " " << componentInstance->component.getName() << " {" << std::endl;
|
buffer << "\t" << "@instance " << componentInstance->name << " " << componentInstance->component.getName() << " {" << std::endl;
|
||||||
buffer << "\t\t" << "@position (" << componentInstance->position.first << ", " << componentInstance->position.second << ")" << std::endl;
|
buffer << "\t\t" << "@position (" << componentInstance->position.first << ", " << componentInstance->position.second << ")" << std::endl;
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ void MainWindow::onStoreScheme() {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto busInstance = dynamic_cast<domain::BusInstance*>(instance);
|
auto busInstance = dynamic_cast<domain::BusInstance*>(instance);
|
||||||
if(busInstance != NULL) {
|
if(busInstance != nullptr) {
|
||||||
buffer << "\t" << "@instance " << busInstance->name << " " << busInstance->bus.getName() << " {" << std::endl;
|
buffer << "\t" << "@instance " << busInstance->name << " " << busInstance->bus.getName() << " {" << std::endl;
|
||||||
buffer << "\t\t" << "@position (" << busInstance->position.first << ", " << busInstance->position.second << ")" << std::endl;
|
buffer << "\t\t" << "@position (" << busInstance->position.first << ", " << busInstance->position.second << ")" << std::endl;
|
||||||
buffer << "\t\t" << "@size " << busInstance->size << std::endl;
|
buffer << "\t\t" << "@size " << busInstance->size << std::endl;
|
||||||
|
@ -236,10 +236,10 @@ void MainWindow::onValidateSchema(bool /*toggled*/) {
|
||||||
std::ostringstream buff;
|
std::ostringstream buff;
|
||||||
|
|
||||||
for(auto err: errors) {
|
for(auto err: errors) {
|
||||||
if(err.instance != NULL) {
|
if(err.instance != nullptr) {
|
||||||
buff << err.instance->name;
|
buff << err.instance->name;
|
||||||
}
|
}
|
||||||
if(err.attribute != NULL) {
|
if(err.attribute != nullptr) {
|
||||||
buff << "::" << err.attribute->name;
|
buff << "::" << err.attribute->name;
|
||||||
}
|
}
|
||||||
if(err.type == domain::Action::ERROR) {
|
if(err.type == domain::Action::ERROR) {
|
||||||
|
|
Loading…
Reference in New Issue