コード例 #1
0
ファイル: parser.c プロジェクト: nukamu/c0_compiler
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;
}
コード例 #2
0
ファイル: parse-expr.cpp プロジェクト: thehexia/mathmagician
// 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;
}
コード例 #3
0
ファイル: parse-expr.cpp プロジェクト: thehexia/mathmagician
// 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;
}
コード例 #4
0
ファイル: parse.c プロジェクト: sidestepism/compiler
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;  
}
コード例 #5
0
ファイル: parse.c プロジェクト: sidestepism/compiler
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
  }
  // }
}
コード例 #6
0
ファイル: parse-expr.cpp プロジェクト: thehexia/mathmagician
// 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;
}
コード例 #7
0
ファイル: parser.c プロジェクト: nukamu/c0_compiler
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);
    }
}
コード例 #8
0
ファイル: parsecfg.c プロジェクト: NUOG/ejudge
static int
parse_multiplicative_expr(int need_eval, cfg_cond_value_t *prv)
{
  return parse_unary_expr(need_eval, prv);
}