sptr<ExprNode> Parser::ParseMul() { sptr<ExprNode> mul = ParseUnary(); while (Match(MUL, DIVIS, DIV, MOD, AND, -1)) { mul = sptr<MulNode>(new MulNode(currToken, mul)); NextToken(); dynamic_pointer_cast<MulNode>(mul)->PushChild(ParseUnary()); } return mul; }
// binoprhs // ::= ('+' unary)* std::unique_ptr<CExprAST> CParser::ParseBinOpRHS(int precedence, std::unique_ptr<CExprAST> lhs) { // If this is a binary operation, find its precedence while (true) { int p = GetTokenPrecedence(); // If this is a binop that binds at least as tightly as the current binop, // consume it, otherwise we are done if (p < precedence) return lhs; int binop = m_CurrentToken; GetNextToken(); // eating that binop // Parsing unary expression after the binary operator auto rhs = ParseUnary(); if (!rhs) return nullptr; // If binop binds less tightly that the operator after rhs, // let the pending operator take rhs as it lhs int nextp = GetTokenPrecedence(); if (p < nextp) { rhs = ParseBinOpRHS(p + 1, std::move(rhs)); if (!rhs) return nullptr; } // Merge lhs/rhs lhs = std::make_unique<CBinaryExprAST>(binop, std::move(lhs), std::move(rhs)); } }
// expression // ::= unary binoprhs // std::unique_ptr<CExprAST> CParser::ParseExpression() { auto lhs = ParseUnary(); if (!lhs) return nullptr; return ParseBinOpRHS(0, std::move(lhs)); }
sptr<ExprNode> Parser::ParseUnary() { if (Match(PLUS, MINUS, NOT, -1)) { sptr<Token> buff = currToken; NextToken(); return sptr<UnOpNode>(new UnOpNode(buff, ParseUnary())); } else { return ParsePrimary(); } }
// unary // ::= primary // ::= '!' unary std::unique_ptr<CExprAST> CParser::ParseUnary() { // If current token is not an operator, it must be a primary expr if (!isascii(m_CurrentToken) || m_CurrentToken == '(' || m_CurrentToken == ',') return ParsePrimary(); // If this is an unary operator, read it int opcode = m_CurrentToken; GetNextToken(); auto operand = ParseUnary(); if (operand) return std::make_unique<CUnaryExprAST>(opcode, std::move(operand)); return nullptr; }
void ParseExprA() { loop: ParseUnary(); if(Token==TOK_ADD || Token==TOK_SUB || Token==TOK_MUL || Token==TOK_DIV || Token==TOK_MOD || Token==TOK_GE || Token==TOK_GT || Token==TOK_LE || Token==TOK_LT || Token==TOK_EQ || Token==TOK_NE || Token==TOK_AND || Token==TOK_OR || Token==TOK_EOR || Token==TOK_ANDAND || Token==TOK_OROR || Token==TOK_LEFT || Token==TOK_RIGHT || Token==TOK_ASSADD || Token==TOK_ASSSUB || Token==TOK_ASSMUL || Token==TOK_ASSDIV || Token==TOK_ASSMOD || Token==TOK_ASSAND || Token==TOK_ASSOR || Token==TOK_ASSEOR || Token==TOK_ASSLEFT || Token==TOK_ASSRIGHT || Token==TOK_PTR || Token==TOK_ASSIGN/* || Token==TOK_COMMA*/) { Match(); goto loop; } }