ast::Expr *parseExpr(TokenIt &it, const TokenIt &end) { ast::Expr *lhs = parsePrimary(it, end); if(!lhs) return NULL; return parseBinOpRHS(NULL, lhs, it, end); }
// <binoprhs> ::= ( operator <expression>)* IAstExpression *Parser::parseBinOpRhs(int precedence, IAstExpression *lhs) { while (true) { if (_curTokenType == ';') { return lhs; } if (_curTokenType == '[') { lhs = parsePostfixUnaryExpr(lhs); } int tokPrec = getTokenPrecedence(); if (tokPrec < precedence) { return lhs; } std::string operStr = _curToken->Value(); int binOp = _curTokenType; next(); // eat binop IAstExpression *rhs = parsePrimary(); if (rhs == nullptr) { return Error("Failed to parse right hand side of expression."); } int nextPrec = getTokenPrecedence(); if (tokPrec < nextPrec) { rhs = parseBinOpRhs(tokPrec + 1, rhs); if (rhs == nullptr) { return Error("Failed to parse right hand side of expression."); } } lhs = new AstBinaryOperatorExpr(operStr, (TokenType)binOp, lhs, rhs, _curToken->Line(), _curToken->Column()); } }
ast::Expr *parseBinOpRHS(int exprPrecendence, ast::Expr *lhs, TokenIt &it, const TokenIt &end) { while(1) { Token *current = currentToken(it, end); char binOp = current ? current->value.c_str()[0] : 0; int precendence = opPrecedence(binOp); if(precendence < exprPrecendence) return lhs; nextToken(it, end); ast::Expr *rhs = parsePrimary(it, end); if(!rhs) return NULL; current = currentToken(it, end); int nextPrecedence = opPrecedence(current ? current->value.c_str()[0] : 0); if(precendence < nextPrecedence) { rhs = parseBinOpRHS(precendence + 1, rhs, it, end); if(!rhs) return NULL; } lhs = new ast::BinaryExpr(binOp, lhs, rhs); } }
std::unique_ptr<ExprAST> Parser::parseBinOpRHS(int prec, std::unique_ptr<ExprAST> lhs, s_cursor_t &it, const s_cursor_t &end) { while (true) { int prec_ = currentTokPrecedence(); if (prec_ < prec) { return lhs; } int binOp = _curTok; getNextToken(it, end); auto rhs = parsePrimary(it, end); if (!rhs) return nullptr; int nextPrec = currentTokPrecedence(); if (prec_ < nextPrec) { rhs = parseBinOpRHS(prec_ + 1, std::move(rhs), it, end); if (!rhs) return nullptr; } lhs = llvm::make_unique<BinaryExprAST>(&_builder, binOp, std::move(lhs), std::move(rhs)); } }
std::unique_ptr<ExprAST> Parser::parseExpression(s_cursor_t &it, const s_cursor_t &end) { auto lhs = parsePrimary(it, end); if (!lhs) return nullptr; return parseBinOpRHS(0, std::move(lhs), it, end); }
// Parse a complete expression ExprAST *Parser::parseExpression () { ExprAST *LHS = parsePrimary (); if (!LHS) return NULL; return parseBinOpRHS (0, LHS); }
// <expression> ::= <primary> <binoprhs> // | <unaryop> <primary> // | <primary> <unaryop> IAstExpression *Parser::parseExpression() { IAstExpression *unaryPre = parsePrefixUnaryExpr(); if (unaryPre != nullptr) { // if we parsed a unary expression, see if it's used in a binary operation return parseBinOpRhs(0, unaryPre); } IAstExpression *primary = parsePrimary(); if (primary != nullptr) { IAstExpression *unaryPost = parsePostfixUnaryExpr(primary); if (unaryPost != nullptr) { // if we parsed a unary expression, see if it's used in a binary operation return parseBinOpRhs(0, unaryPost); } return parseBinOpRhs(0, primary); // otherwise just keep parsing the binop } return nullptr; }
void Parser::parseCastExpr() { Token t = lex.peek(); switch(t.type) { case Token::FLOAT: case Token::STRING: case Token::COLOR: case Token::POINT: case Token::VECTOR: case Token::NORMAL: case Token::MATRIX: parseTypecast(); default: break; } parsePrimary(); }
// <prefixunary> ::= unaryoper <primary> IAstExpression *Parser::parsePrefixUnaryExpr() { if (!_curToken->IsUnaryOperator()) { // short curcuit if not an unary operator. return nullptr; } std::string oper = _curToken->Value(); int tokenType = _curTokenType; IAstExpression *operand; if (tokenType == tok_new) { return parseNewMallocExpression(); } else { next(); // eat unaryoper operand = parsePrimary(); if (operand == nullptr) { return nullptr; } } return new AstUnaryOperatorExpr(oper, (TokenType)tokenType, operand, false, _curToken->Line(), _curToken->Column()); }
ExprAST* Parser::parseBinOpRHS(int exprPrecedence, ExprAST* LHS) { while (1) { int TokPrec = getOpPrecedence(); if (TokPrec < exprPrecedence) return LHS; int binOp = lexer->token; lexer->NextToken(); ExprAST* RHS = parsePrimary(); if (!RHS) return 0; int NextPrec = getOpPrecedence(); if (TokPrec < NextPrec) { RHS = parseBinOpRHS(TokPrec + 1, RHS); if (!RHS) return 0; } LHS = new BinaryExprAST(LHS, RHS, binOp); } }
ExprAST *Parser::parseBinOpRHS (int exprPrecedence, ExprAST *LHS) { while (1) { // This should be either an operator, a close-paren, comma, // or the end of the formula. if (currentToken != TOKEN_OPERATOR && currentToken != TOKEN_PAREN_CLOSE && currentToken != TOKEN_COMMA && currentToken != TOKEN_END) { error (boost::format ("Attempting to parse the RHS of a binary operator, " "and got %1%!") % formatToken ()); return NULL; } // Get the precedence int tokenPrecedence = -1; for (int i = 0 ; i < NUM_OPERATORS ; i++) { if (strToken == operators[i].name) { tokenPrecedence = operators[i].precedence; break; } } // We're done if we run into an equivalent or lower-precedence binary // operator (or, notably, something that's not an operator at all, like // the end of the formula) if (tokenPrecedence < exprPrecedence) return LHS; // Pull off the operator std::string binOp = strToken; getNextToken (); // Parse the primary after the operator ExprAST *RHS = parsePrimary (); if (!RHS) return NULL; // We've now parsed a full binary operator pair, "A op B". If the next // thing is a binary operator (which it should be, or it should be // nothing at all), we need to see whether we want "(A op B) op2 ..." or // "A op (B op2 ...)" by precedence rules. Look ahead: int nextPrecedence = -1; for (int i = 0 ; i < NUM_OPERATORS ; i++) { if (strToken == operators[i].name) { nextPrecedence = operators[i].precedence; break; } } if (tokenPrecedence < nextPrecedence) { // Next precedence is greater, we want "A op (B op2 ...)". Do that by // parsing B op2 ... into a new RHS. RHS = parseBinOpRHS (tokenPrecedence + 1, RHS); if (RHS == NULL) return NULL; } // Next precedence is lower, we want "(A op B) op2 ...", so make a new LHS LHS = new BinaryExprAST (binOp, LHS, RHS); // And loop back to the beginning } }