/*! * rule ::= 'id' ( '::=' | '->' ) expression */ RuleNode* Parser::parseRule() { std::string name = token_value_; consumeToken(); if (token_ != Lexer::Token::coloncolonequal && token_ != Lexer::Token::minusgreater) { return static_cast<RuleNode*>(errorNode("missing terminating character \"::=\" or\" ->\"")); } consumeToken(); Node* node = parseExpression(); return new RuleNode(name, node); }
/*! * factor ::= ( 'id' | 'text' | '(' expression ')' ) ( '+' | '*' | ) */ Node* Parser::parseFactor() { Node* n = 0; switch (token_) { case Lexer::Token::identifier: n = new SymbolNode(token_value_); consumeToken(); break; case Lexer::Token::text: n = new TerminalNode(token_value_.substr(1, token_value_.size() - 2)); consumeToken(); break; case Lexer::Token::l_paren: consumeToken(); n = new ParenNode(parseExpression()); if (token_ != Lexer::Token::r_paren) { return errorNode("missing terminating character \")\""); } consumeToken(); break; default: assert(false && "unexpected token"); break; } switch (token_) { case Lexer::Token::plus: consumeToken(); n = new PlusNode(n); break; case Lexer::Token::star: consumeToken(); n = new StarNode(new PlusNode(n)); break; default: break; } return n; }
/*! * syntax ::= ( rule )+ */ std::vector<RuleNode*> Parser::parseSyntax() { std::vector<RuleNode*> v; // parsed but an error occurred if (!error_info_.empty()) { return v; } // parsed and ok if (!nodes_.empty()) { for (auto& n: nodes_) { v.push_back(n.get()); } return v; } // not parsed, let's start v.push_back(parseRule()); while (token_ == Lexer::Token::identifier) { v.push_back(parseRule()); } if (token_ != Lexer::Token::eof) { errorNode("too much token"); } // an error occurred while parsing if (!error_info_.empty()) { for (auto& n: v) { delete n; } v.clear(); } for (auto& n: v) { nodes_.push_back(std::shared_ptr<RuleNode>(n)); } return v; }
AST performAction(AST t) { AST s = t; AST ret; if(s->kind == ACTION_NK) { AST x = performAction(s->fields.subtrees.s1); AST y = applyNode(s->fields.subtrees.s2,x); ret = performAction(simplify(y)); } else if(s->kind == BASIC_FUNC_NK) { if(s->extra == PRILST_FK) { AST x= simplify(s->fields.subtrees.s1); while(x->kind != EMPTYLIST) { if(x->kind == ERROR_NK) ret= errorNode(x->fields.stringval); AST y = applyBasicFunc(x,"head"); AST tmp = simplify(y); printValue(simplify(tmp)); y = applyBasicFunc(x,"tail"); x = simplify(y); } ret = emptyList(); } else if(s->extra == PRINT_FK) { AST r = simplify(s->fields.subtrees.s1); printValue(r); ret = emptyList(); } else if(s->extra == PROD_FK) { ret = simplify(s->fields.subtrees.s1); } else if(s->extra == READI_FK) { char str[11]; if(fgets(str,11,stdin) != NULL) ret = numberNode(atoi(str)); else ret = errorNode("Not a valid number"); } else if(s->extra == READC_FK) { char str[2]; if(fgets(str,2,stdin) != NULL) ret = charNode(str); else ret = errorNode("Not a valid character"); } else { ret = errorNode("No action specified"); } } else if(s->kind == ERROR_NK) { ret = errorNode(s->fields.stringval); } else { ret = errorNode("No action specified"); } return ret; }