Updated error handling while parsing *.csl files

This commit is contained in:
Borna Rajković 2022-05-01 18:13:01 +02:00
parent d6c1023df2
commit dde9bb8af8
5 changed files with 179 additions and 68 deletions

View File

@ -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"});
}
} }
} }

View File

@ -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 &current(); Token &current();
[[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();

View File

@ -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);
}

View File

@ -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

View File

@ -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) {