/** * parse expression */ expr_t parse_expr(tokenizer_t t){ expr_t expr_left, expr_right; expr_left = parse_eq_expr(t); struct token tok = cur_tok(t); if(tok.kind == TOK_ASSIGN){ eat_it(t, TOK_ASSIGN); expr_right = parse_expr(t); expr_t assign_expr = mk_expr_bin_op(t->filename, t->line, op_kind_assign, expr_left, expr_right); return assign_expr; }else{ // これは式文 return expr_left; } }
// log_and_expr := log_and_expr && equality_expr // equality_expr // // log_and_expr := equality_expr (log_and_expr) Expr* parse_log_and_expr(Parser& p, Token_stream& ts) { if (Expr* e1 = parse_eq_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 log_and_tok: return parse_log_and_rest(p, ts, ts.advance(), e1); default: return e1; } } return e1; } return nullptr; }
// log_and_rest := ... && equality_expr (log_and_rest) Expr* parse_log_and_rest(Parser& p, Token_stream& ts, Token const* tok, Expr* e1) { if (Expr* e2 = parse_eq_expr(p, ts)) { if (Token const* t = ts.next()) { // keep parsing the 'rest' while we still have a valid operator if (t->kind() == log_and_tok) return parse_log_and_rest(p, ts, ts.advance(), p.on_binary(tok, e1, e2)); else return p.on_binary(tok, e1, e2); } return p.on_binary(tok, e1, e2); } error("Expected expression after logical-or expr: "); print(e1); print(tok); print("\n"); return nullptr; }