/*!
 *  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;
}
示例#4
0
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;
}