bool Parser::checkValidity(std::vector<std::pair<std::string, Token>> tokens) { setExpected({t_start, t_end}); int parenthesisLevel = 0; std::vector<std::pair<std::string, Token>>::iterator lastParenthesis = tokens.end(); auto it = tokens.begin(); while(it != tokens.end()) { if(it->second == t_parenthesis_close || it->second == t_parenthesis_open) lastParenthesis = it; if(!isExpected(it->second)) { std::string err = ""; if(it->second == t_end) err = "Unexpected end of expression."; else if(it->second == t_unknown) err = "Unknown token."; else if(it->second == t_error) err = "Simply error."; else { std::string exp = ""; Lexer lexer; bool first = true; // For printing commas for(auto& i: expected) { auto t = lexer.getStringFromToken(i); if(t != "") { if(!first) exp += ", "; exp += t; } first = false; } err = "Token not expected."; if(Options::has(Options::Option::PrintExpected)) err += "\nExpected: " + exp; } std::cout << error(it, &tokens, err).first; return false; } setExpected({}); switch(it->second) { case t_start: addExpected({t_number, t_identifier, t_parenthesis_open, t_quote, t_end}); break; case t_end: if(parenthesisLevel > 0) { while(it != tokens.begin()) { if(it->second == t_parenthesis_open) if(Helper::getClosingToken(&it, &tokens, t_parenthesis_close) == tokens.end()) break; it--; } std::cout << error(it, &tokens, "Unmatched [(].").first; return false; } else if(parenthesisLevel < 0) { it = lastParenthesis; std::cout << error(it, &tokens, "Extraneous [)].").first; return false; } break; case t_semicolon: addExpected({t_number, t_identifier, t_parenthesis_open, t_end, t_semicolon}); break; case t_number: addExpected(getOperatorTokens()); addExpected({t_parenthesis_close, t_end}); break; case t_identifier: addExpected(getOperatorTokens()); addExpected({t_equals, t_dot, t_parenthesis_close, t_increment, t_decrement, t_end}); break; case t_dot: addExpected({t_identifier}); break; case t_equals: addExpected({t_number, t_identifier, t_quote, t_parenthesis_open}); break; case t_parenthesis_open: parenthesisLevel += 1; addExpected({t_number, t_identifier, t_parenthesis_open, t_parenthesis_close}); break; case t_parenthesis_close: parenthesisLevel -= 1; addExpected(getOperatorTokens()); addExpected({t_parenthesis_close, t_end}); break; case t_quote: { auto closing = Helper::getClosingToken(&it, &tokens); if(closing == tokens.end()) { it = tokens.end(); // Create the unexpected end of expression error } else { it = closing; addExpected(getOperatorTokens()); addExpected({t_end, t_parenthesis_close}); } } break; case t_increment: case t_decrement: addExpected(getOperatorTokens()); addExpected({t_end}); break; case t_plus: case t_minus: case t_forw_slash: case t_asterix: case t_raised: case t_modulo: case t_equal_to: case t_not_equal_to: case t_greater_than: case t_less_than: case t_less_than_or_equal: case t_greater_than_or_equal: addExpected({t_number, t_identifier, t_parenthesis_open, t_quote}); break; default: std::cout << error(it, &tokens, "Token not handled. (validity)").first; return false; break; } it++; } return true; }
void LineParser::throwAllExpected(const SegmentParseExpectedException& finalEx) { addExpected(finalEx); throwAllExpected(); }