expr_t parse_add_expr(tokenizer_t t){ expr_t expr_left, expr_right; expr_left = parse_mult_expr(t); struct token tok = cur_tok(t); while(tok.kind == TOK_PLUS || tok.kind == TOK_MINUS){ eat_it(t, TOK_ANY); // なんでも食べる expr_right = parse_mult_expr(t); expr_left = mk_expr_bin_op(t->filename, t->line, (tok.kind == TOK_PLUS) ? op_kind_bin_plus : op_kind_bin_minus // +, - のどちらかしかない , expr_left, expr_right); // left にたたんでいく tok = cur_tok(t); } return expr_left; }
// expr ::= expr '+' multiplicative expr // expr '-' multiplicative expr // multiplicative expr // // or // expr ::= multi_expr (add-rest) Expr* parse_add_expr(Parser& p, Token_stream& ts) { // parse primary expressions if (Expr* e1 = parse_mult_expr(p, ts)) { if (Token const* tok = ts.next()) { switch (tok->kind()) { // advance past the operator and move to parse the 'rest' of the expr case plus_tok: case minus_tok: return parse_add_rest(p, ts, ts.advance(), e1); default: return e1; } } // no operator or rhs means end of expr else return e1; } return nullptr; }
// add-rest ::= '+' mult_expr (add-rest) // '-' mult_expr (add-rest) // // assuming the first mult_expr has already been parsed // we start to parse the 'rest' of the expression Expr* parse_add_rest(Parser& p, Token_stream& ts, Token const* tok, Expr* e1) { if (Expr* e2 = parse_mult_expr(p, ts)) { if (Token const* t = ts.next()) { // keep parsing the 'rest' while we still have a valid operator if (is_additive_op(t->kind())) return parse_add_rest(p, ts, ts.advance(), p.on_binary(tok, e1, e2)); else return p.on_binary(tok, e1, e2); } else return p.on_binary(tok, e1, e2); } error("Expected expression after additive expr: "); print(e1); print(tok); print("\n"); return nullptr; }