// Term → Unary Term' bool AnimExpression::parseTerm(const QString& str, QString::const_iterator& iter) { if (!parseUnary(str, iter)) { return false; } if (!parseTermPrime(str, iter)) { return false; } return true; }
//////////////////////////////////////////////////////////////////////////////// // Tag --> Unary {( "_hastag_" | "_notag_" ) Unary} bool Eval::parseTag ( std::vector <std::pair <std::string, Lexer::Type> >& infix, int &i) const { if (i < infix.size () && parseUnary (infix, i)) { while (i < infix.size () && (infix[i].first == "_hastag_" || infix[i].first == "_notag_") && infix[i].second == Lexer::typeOperator) { ++i; if (! parseUnary (infix, i)) return false; } return true; } return false; }
// Unary → '!' Unary | Factor bool AnimExpression::parseUnary(const QString& str, QString::const_iterator& iter) { auto token = consumeToken(str, iter); if (token.type == Token::Not) { if (!parseUnary(str, iter)) { unconsumeToken(token); return false; } _opCodes.push_back(OpCode {OpCode::Not}); return true; } unconsumeToken(token); return parseFactor(str, iter); }
AstNode* Parser::parseBinary(int minPrecedence) { AstNode* left = parseUnary(); int precedence = tokenPrecedence(currentToken()); while (precedence >= minPrecedence) { while (tokenPrecedence(currentToken()) == precedence) { TokenKind op = currentToken(); uint32_t op_pos = _currentTokenIndex; consumeToken(); AstNode* right = parseBinary(precedence + 1); left = new BinaryOpNode(op_pos, op, left, right); } precedence--; } return left; }
// Term' → '&&' Unary Term' | ε bool AnimExpression::parseTermPrime(const QString& str, QString::const_iterator& iter) { auto token = consumeToken(str, iter); if (token.type == Token::And) { if (!parseUnary(str, iter)) { unconsumeToken(token); return false; } if (!parseTermPrime(str, iter)) { unconsumeToken(token); return false; } _opCodes.push_back(OpCode {OpCode::And}); return true; } else { unconsumeToken(token); return true; } }
AstNode* Parser::parseUnary() { if (isUnaryOp(currentToken())) { TokenKind op = currentToken(); consumeToken(); return new UnaryOpNode(_currentTokenIndex, op, parseUnary()); } else if (currentToken() == tIDENT && lookaheadToken(1) == tLPAREN) { AstNode* expr = parseCall(); return expr; } else if (currentToken() == tIDENT) { AstVar* var = _currentScope->lookupVariable(currentTokenValue()); if (var == 0) { error("undeclared variable: %s", currentTokenValue().c_str()); } LoadNode* result = new LoadNode(_currentTokenIndex, var); consumeToken(); return result; } else if (currentToken() == tDOUBLE) { DoubleLiteralNode* result = new DoubleLiteralNode(_currentTokenIndex, parseDouble(currentTokenValue())); consumeToken(); return result; } else if (currentToken() == tINT) { IntLiteralNode* result = new IntLiteralNode(_currentTokenIndex, parseInt(currentTokenValue())); consumeToken(); return result; } else if (currentToken() == tSTRING) { StringLiteralNode* result = new StringLiteralNode(_currentTokenIndex, currentTokenValue()); consumeToken(); return result; } else if (currentToken() == tLPAREN) { consumeToken(); AstNode* expr = parseExpression(); ensureToken(tRPAREN); return expr; } else { error("Unexpected token: %s", tokenStr(currentToken())); return 0; } }