void Parser::parseUnaryExpr() { Token t = lex.peek(); if (t.type == Token::EXCLAIM || t.type == Token::MINUS) { lex.consume(); parseUnaryExpr(); } else parseCastExpr(); }
void Parser::parseRHS(/* ASTNode* LHS, */ unsigned MinPrec) { unsigned NextTokPrec = getOperatorPrecedence(lex.peek()); while (1) { // If this token has a lower precedence than we are allowed to parse (e.g. // because we are called recursively, or because the token is not a binop), // then we are done! if (NextTokPrec < MinPrec) return /* LHS */; // Consume the operator, saving the operator token for error reporting. Token OpToken = lex.peek(); lex.consume(); // Special case handling for the ternary operator /* ASTNode* TernaryMiddle = 0 */ if (NextTokPrec == Precedence::Conditional) { if (lex.peek().type != Token::COLON) /* TernaryMiddle = */ parseExpression(); // Eat the colon lex.consume(Token::COLON); } // Parse another leaf here for the RHS of the operator. /* ASTNode* RHS = */ parseUnaryExpr(); // Remember the precedence of this operator and get the precedence of the // operator immediately to the right of the RHS. unsigned ThisPrec = NextTokPrec; NextTokPrec = getOperatorPrecedence(lex.peek()); // Assignment and conditional expressions are right-associative. bool isRightAssoc = ThisPrec == Precedence::Conditional || ThisPrec == Precedence::Assignment; // Get the precedence of the operator to the right of the RHS. If it binds // more tightly with RHS than we do, evaluate it completely first. if (ThisPrec < NextTokPrec || (ThisPrec == NextTokPrec && isRightAssoc)) { // If this is left-associative, only parse things on the RHS that bind // more tightly than the current operator. If it is left-associative, it // is okay, to bind exactly as tightly. For example, compile A=B=C=D as // A=(B=(C=D)), where each paren is a level of recursion here. /* RHS =*/ parseRHS(/* RHS, */ ThisPrec + !isRightAssoc); NextTokPrec = getOperatorPrecedence(lex.peek()); } assert(NextTokPrec <= ThisPrec && "Recursion didn't work!"); /* if (TernaryMiddle) LHS = new TernaryASTNode(LHS, TernaryMiddle, RHS); else LHS = new ASTNode(OpToken, LHS, RHS); */ } }
Node* Parser::parseBinaryExpr() { // BinaryExpr: Unary { OP Unary } stack<OperatorType> opStack; stack<Node*> nodeStack; auto _begin = parseUnaryExpr(); if (_begin == nullptr) return nullptr; nodeStack.push(_begin); while (Token::isOperator(lookahead)) { int prec = getPrecedence(Token::toOperator(lookahead)); if (opStack.empty() || prec > getPrecedence(opStack.top())) { opStack.push(Token::toOperator(lookahead)); nextToken(); auto l = parseUnaryExpr(); nodeStack.push(l); } else { while (!opStack.empty() && prec <= getPrecedence(opStack.top())) { Node *l1, *l2; l1 = nodeStack.top(); nodeStack.pop(); l2 = nodeStack.top(); nodeStack.pop(); nodeStack.push(make_node<BinaryExprNode>(opStack.top(), l2, l1)); opStack.pop(); } } } while (!opStack.empty()) { Node *l1, *l2; l1 = nodeStack.top(); nodeStack.pop(); l2 = nodeStack.top(); nodeStack.pop(); nodeStack.push(make_node<BinaryExprNode>(opStack.top(), l2, l1)); opStack.pop(); } return nodeStack.top(); }
static Node *parseExpr(Parser *p) { Node *expr = 0; expr = parseUnaryExpr(p); if (expr) { int prec = getPrec(p->tok); if (prec > 0) { Node *e2 = parseBinaryExpr(p, &expr, prec); if (e2) { #ifdef LOG_PARSE info("解析得到BinaryExpr\n"); #endif expr = e2; } else { nodeFree(expr); expr = 0; } } } return expr; }
static Node *parseBinaryExpr(Parser *p, Node **lhs, int prec) { enum Token op; Node *rhs; int prec2; op = p->tok; p->tok = lexerGetToken(p->lex, &p->tokval, &p->toklen); rhs = parseUnaryExpr(p); if (!rhs) { handleParserError(p, 1, "解析BinaryExpr出错"); return 0; } prec2 = getPrec(p->tok); if (prec2 < 0) { Node *e = (Node *)binaryExprNew(*lhs, op, rhs); if (e) { return e; } } else if (prec2 <= prec) { Node *newlhs = (Node *)binaryExprNew(*lhs, op, rhs); if (newlhs) { *lhs = newlhs; return parseBinaryExpr(p, lhs, prec2); } } else { Node *newrhs = parseBinaryExpr(p, &rhs, prec2); if (newrhs) { rhs = newrhs; Node *e2 = (Node *)binaryExprNew(*lhs, op, rhs); if (e2) { return e2; } } } nodeFree(rhs); return 0; }
void Parser::parseAssignmentExpr() { /* LHS = */parseUnaryExpr(); parseRHS(/* LHS, */ Precedence::Assignment); }
void Parser::parseExpression() { /* LHS = */parseUnaryExpr(); parseRHS(/* LHS, */ Precedence::Comma); }