expr_t parse_multi_expr(tokenizer_t t) { char * filename = cur_tok(t).filename; int line = cur_tok(t).line_num; expr_t e = parse_unary_expr(t); while((cur_tok(t).kind == TOK_MUL)|(cur_tok(t).kind == TOK_DIV)|(cur_tok(t).kind == TOK_REM)) { op_kind_t op = parse_multi_oper(t); expr_t e0 = parse_unary_expr(t); e = mk_expr_bin_op(filename, line, op, e, e0); } return e; }
// multi-rest ::= '*' primary expr (multi-rest) // '/' primary expr (multi-rest) // '%' primary expr (multi-rest) // // assuming the first primary expr and operator has already been parsed // this parses the 'rest' of the expression Expr* parse_mult_rest(Parser& p, Token_stream& ts, Token const* tok, Expr* e1) { // look for the next operand if (Expr* e2 = parse_unary_expr(p, ts)) { // if there is another operator after the primary expr // and it is a multiplicative operator // then consume it. // the expr so far becomes the lhs operand // and we recurse until there are no more multiplicative operators. if (Token const* t = ts.next()) { if (is_mult_op(t->kind())) return parse_mult_rest(p, ts, ts.advance(), p.on_binary(tok, e1, e2)); // return once we're done eating up multiplicative operators else return p.on_binary(tok, e1, e2); } else return p.on_binary(tok, e1, e2); } error("Expected expression after multiplicative expr: "); print(e1); print(tok); print("\n"); return nullptr; }
// not ::= ! unary expr Expr* parse_not(Parser& p, Token_stream& ts) { // eat the not tok Token const* tok = ts.advance(); assert(tok->kind() == bang_tok); if (Expr* e = parse_unary_expr(p, ts)) return p.on_unary(tok, e); error("Expected primary expr after '!'."); return nullptr; }
expr_t parse_mult_expr(tokenizer_t t){ expr_t expr_left, expr_right; expr_left = parse_unary_expr(t); struct token tok = cur_tok(t); // relational-operator while(tok.kind == TOK_MUL || tok.kind == TOK_DIV || tok.kind == TOK_REM){ eat_it(t, TOK_ANY); // なんでも食べる expr_right = parse_unary_expr(t); op_kind_t op_kind; if(tok.kind == TOK_MUL) op_kind = op_kind_mult; if(tok.kind == TOK_DIV) op_kind = op_kind_div; if(tok.kind == TOK_REM) op_kind = op_kind_rem; expr_left = mk_expr_bin_op(t->filename, t->line, op_kind, expr_left, expr_right); // left にたたんでいく tok = cur_tok(t); } return expr_left; }
expr_t parse_op_expr(tokenizer_t t) { // struct token tok = cur_tok(t); expr_t expr; if(cur_tok(t).kind == TOK_BANG){ eat_it(t, TOK_BANG); expr = parse_unary_expr(t); return mk_expr_un_op(t->filename, t->line, op_kind_logneg, expr); }else if(cur_tok(t).kind == TOK_PLUS){ eat_it(t, TOK_PLUS); expr = parse_unary_expr(t); return mk_expr_un_op(t->filename, t->line, op_kind_un_plus, expr); }else if(cur_tok(t).kind == TOK_MINUS){ eat_it(t, TOK_MINUS); expr = parse_unary_expr(t); return mk_expr_un_op(t->filename, t->line, op_kind_un_minus, expr); }else{ syntax_error(t, "error: parse_op_expr (expected TOK_BANG, TOK_PLUS, TOK_MINUS)"); return NULL; // exit } // } }
// factor ::= factor '*' primary expr // factor '/' primary expr // factor '%' primary expr // primary expr // // or // factor ::= primary expr (multi-rest) Expr* parse_mult_expr(Parser& p, Token_stream& ts) { if (Expr* e1 = parse_unary_expr(p, ts)) { if (Token const* tok = ts.next()) { switch (tok->kind()) { case star_tok: return parse_mult_rest(p, ts, ts.expect(star_tok), e1); case fslash_tok: return parse_mult_rest(p, ts, ts.expect(fslash_tok), e1); case mod_tok: return parse_mult_rest(p, ts, ts.expect(mod_tok), e1); // anything else and we consider e1 a lone primary expr default: return e1; } } // if it is only the primary expr else return e1; } return nullptr; }
expr_t parse_unary_expr(tokenizer_t t) { char * filename = cur_tok(t).filename; int line = cur_tok(t).line_num; char * f =(char *)safe_malloc(sizeof(char) * 50) ; if(cur_tok(t).kind == TOK_INT_LITERAL) { strcpy(f, cur_tok(t).num); f = (char *)realloc(f, sizeof(char) * strlen(f) + 1); eat_it(t, TOK_INT_LITERAL); return mk_expr_int_literal(filename, line, f); } else if(cur_tok(t).kind == TOK_ID) { strcpy(f, parse_identifier(t)); f = (char *)realloc(f, sizeof(char) * strlen(f) + 1); if(cur_tok(t).kind == TOK_LPAREN) { eat_it(t, TOK_LPAREN); expr_list_t args = parse_arg_expr_list(t); eat_it(t, TOK_RPAREN); return mk_expr_call(filename, line, f, args); } else { return mk_expr_id(filename, line, f); } } else if(cur_tok(t).kind == TOK_LPAREN) { eat_it(t, TOK_LPAREN); expr_t e = parse_expr(t); eat_it(t, TOK_RPAREN); return mk_expr_paren(filename, line, e); } else if((cur_tok(t).kind == TOK_PLUS)|(cur_tok(t).kind == TOK_MINUS)|(cur_tok(t).kind == TOK_BANG)) { op_kind_t op = parse_unary_oper(t); expr_t exp = parse_unary_expr(t); return mk_expr_un_op(filename, line, op, exp); } else { printf("exit_5\n"); exit(1); } }
static int parse_multiplicative_expr(int need_eval, cfg_cond_value_t *prv) { return parse_unary_expr(need_eval, prv); }