// Parse a postfix expression. // // postfix-expression -> postfix-expression '(' argument-list ')' // | postfix-expression '[' expression ']' // | postfix-expression . identifier // | primary-expression Expr* Parser::postfix_expr() { Expr* e1 = primary_expr(); while (true) { // dot-expr if (match_if(dot_tok)) { Token tok = match(identifier_tok); Expr* e2 = on_id(tok); e1 = on_dot(e1, e2); } // call-expr else if (match_if(lparen_tok)) { Expr_seq args; while (lookahead() != rparen_tok) { args.push_back(expr()); if (match_if(comma_tok)) continue; else break; } match(rparen_tok); e1 = on_call(e1, args); } // index-expr else if (match_if(lbrack_tok)) { Expr* e2 = expr(); match(rbrack_tok); e1 = on_index(e1, e2); } // anything else else { break; } } return e1; }
static int unary_expr(ParserState* ps, Ast** expr) { Ast* start = ps->curr; if (curris(ps, OpSub) || curris(ps, OpNot)) { if (curris(ps, OpSub)) ps->curr->t = OpNeg; Ast* op = ps->curr; step(ps); if (unary_expr(ps, expr)) { ast_next_to_first_child(op); *expr = op; } else { parerr(ps, "invlaid syntax"); } return 1; } else if (primary_expr(ps, expr)) { return 1; } ps->curr = start; return 0; }