// Parse a unary expression. // // unary-expr -> '+' unary-expr // | '-' unary-expr // | '!' unary-expr // | postfix-expr Expr* Parser::unary_expr() { if (match_if(plus_tok)) { Expr* e = unary_expr(); return on_pos(e); } else if (match_if(minus_tok)) { Expr* e = unary_expr(); return on_neg(e); } else if (match_if(not_tok)) { Expr* e = unary_expr(); return on_not(e); } else { return postfix_expr(); } }
static int binary_expr(ParserState* ps, int p, Ast** expr) { Ast *left, *right; if (unary_expr(ps, &left)) { *expr = left; int r = 0xffff; while (ps->curr != 0 && ps->curr->t < TkOpEnd && OpPrec[ps->curr->t] >= p && OpPrec[ps->curr->t] <= r) { Ast* op = ps->curr; step(ps); if (binary_expr(ps, OpPrec[op->t] + 1, &right)) { r = OpPrec[op->t]; ast_swap(left, op); ast_next_to_first_child(left); ast_next_to_last_child(left); *expr = left; } else { parerr(ps, "invalid syntax"); } } return 1; } else return 0; }
// Parse a multiplicative expression. // // multiplicative-expr -> multiplicative-expr '*' unary-expr // | multiplicative-expr '/' unary-expr // | multiplicative-expr '%' unary-expr // | unary-expr Expr* Parser::multiplicative_expr() { Expr* e1 = unary_expr(); while (true) { if (match_if(star_tok)) { Expr* e2 = unary_expr(); e1 = on_mul(e1, e2); } else if (match_if(slash_tok)) { Expr* e2 = unary_expr(); e1 = on_div(e1, e2); } else if (match_if(percent_tok)) { Expr* e2 = unary_expr(); e1 = on_rem(e1, e2); } 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; }
static value_t *e_expr(env_t *env, expr_t *expr) { value_t *result; switch (expr->type) { default: // This is to handle invalid tags. case p_unused: if (*(int *)NULL) { printf("should crash.\n"); } return NULL; case p_and: { value_t *l = e_expr(env, binary_left(expr)); if (bool_val(l)) { result = e_expr(env, binary_right(expr)); } else { result = l; } } break; case p_or: { value_t *l = e_expr(env, binary_left(expr)); if (bool_val(l)) { result = l; } else { result = e_expr(env, binary_right(expr)); } } break; case p_add: case p_div: case p_ge: case p_gt: case p_le: case p_lt: case p_mod: case p_mul: case p_sub: result = e_binary_op(env, expr); break; case p_bconst: result = alloc_value(v_bool); bool_val(result) = bool_val(expr); break; case p_cconst: result = alloc_value(v_char); char_val(result) = char_val(expr); break; case p_datacons: result = e_datacons(env, expr); break; case p_eqop: result = e_equals(env, binary_left(expr), binary_right(expr)); break; case p_fncall: result = e_fncall(env, fncall_fn(expr), fncall_args(expr)); break; case p_nconst: result = alloc_value(v_num); num_val(result) = num_val(expr); break; case p_ite: result = e_ite(env, expr); break; case p_let: result = e_let(env, expr); break; case p_listcons: result = e_listcons(env, expr); break; case p_listlit: result = e_listlit(env, expr); break; case p_listempty: result = e_listempty(); break; case p_match: result = e_match(env, expr); break; case p_ne: result = e_equals(env, binary_left(expr), binary_right(expr)); bool_val(result) = !bool_val(result); break; case p_negate: result = e_expr(env, unary_expr(expr)); bool_val(result) = !bool_val(result); break; case p_tuple: result = e_tuple(env, expr); break; case p_var: result = env_lookup(env, var_name(expr)); if (result == NULL) { error("e_expr: variable '%s' not in scope on line %d.\n", var_name(expr), expr->line_num); } result = thunk_force(result); break; } return result; }
/** * $ANTLR start nonparentherized_boolean * /home/cross/workspace/djondb/db/grammars/filter_expression.g:114:1: nonparentherized_boolean returns [BaseExpression* val] : u1= unary_expr ( OPER u2= unary_expr )* ; */ static BaseExpression* nonparentherized_boolean(pfilter_expressionParser ctx) { BaseExpression* val; pANTLR3_COMMON_TOKEN OPER6; BaseExpression* u1; #undef RETURN_TYPE_u1 #define RETURN_TYPE_u1 BaseExpression* BaseExpression* u2; #undef RETURN_TYPE_u2 #define RETURN_TYPE_u2 BaseExpression* /* Initialize rule variables */ OPER6 = NULL; { // /home/cross/workspace/djondb/db/grammars/filter_expression.g:115:2: (u1= unary_expr ( OPER u2= unary_expr )* ) // /home/cross/workspace/djondb/db/grammars/filter_expression.g:115:4: u1= unary_expr ( OPER u2= unary_expr )* { FOLLOWPUSH(FOLLOW_unary_expr_in_nonparentherized_boolean215); u1=unary_expr(ctx); FOLLOWPOP(); if (HASEXCEPTION()) { goto rulenonparentherized_booleanEx; } { val= u1 ; } // /home/cross/workspace/djondb/db/grammars/filter_expression.g:117:4: ( OPER u2= unary_expr )* for (;;) { int alt4=2; switch ( LA(1) ) { case OPER: { alt4=1; } break; } switch (alt4) { case 1: // /home/cross/workspace/djondb/db/grammars/filter_expression.g:117:6: OPER u2= unary_expr { OPER6 = (pANTLR3_COMMON_TOKEN) MATCHT(OPER, &FOLLOW_OPER_in_nonparentherized_boolean221); if (HASEXCEPTION()) { goto rulenonparentherized_booleanEx; } FOLLOWPUSH(FOLLOW_unary_expr_in_nonparentherized_boolean225); u2=unary_expr(ctx); FOLLOWPOP(); if (HASEXCEPTION()) { goto rulenonparentherized_booleanEx; } { FILTER_OPERATORS oper = parseFilterOperator((char*)(OPER6->getText(OPER6))->chars); BinaryExpression* be = new BinaryExpression(oper); be->push( val ); be->push(u2 ); val= be; } } break; default: goto loop4; /* break out of the loop */ break; } } loop4: ; /* Jump out to here if this rule does not match */ } } // This is where rules clean up and exit // goto rulenonparentherized_booleanEx; /* Prevent compiler warnings */ rulenonparentherized_booleanEx: ; return val; }