int parse_factor(CALC_ELEMENT ** e) { PARSE_SYMBOL s = get_symbol(); switch (s) { case PARSE_NUMBER: *e = create_number(get_current_number()); accept(s); return 0; break; case PARSE_X: *e = create_x(); accept(s); return 0; break; case PARSE_LOG: return parse_log(e); break; case PARSE_LPAREN: return parse_paren_expr(e); break; default: parser_error("\'number\', \'x\', \'log\' or \'(\'"); return -1; } }
int parse_log(CALC_ELEMENT ** e) { CALC_ELEMENT *t = NULL; if (!accept(PARSE_LOG)) { parser_error("\'log\'"); return -1; } if (parse_paren_expr(&t) == -1) return -1; else { *e = create_log(t); return 0; } }
expr_t parse_unary_expr(tokenizer_t t) { struct token tok = cur_tok(t); switch(tok.kind){ case TOK_INT_LITERAL: return parse_intlit_expr(t); break; case TOK_ID: return parse_id_expr(t); break; case TOK_LPAREN: return parse_paren_expr(t); break; case TOK_PLUS: case TOK_MINUS: case TOK_BANG: return parse_op_expr(t); break; default: syntax_error(t, "parse_expr error (expected TOK_INT_LITERAL, TOK_ID, TOK_LPAREN, TOK_PLUS, TOK_MINUS, TOK_BANG)"); break; } return NULL; }
static int parse_primary(struct peg_grammar_parser *pgp, struct peg_cursor *pc, int *prip) { struct peg_grammar *peg = pgp->peg; int pri; int rv; int match = -1; struct peg_cursor npc = *pc; int prefix = PEG_ATTR_NONE; int suffix = PEG_ATTR_NONE; int action = PEG_ACT_NONE; struct raw r = { 0, NULL }; struct peg_node *pn; if ( string_match(pgp, "&", &npc) ) prefix = PEG_ATTR_AND; else if ( string_match(pgp, "!", &npc) ) prefix = PEG_ATTR_NOT; if ( (rv = parse_id_and_not_arrow(pgp, &npc, &match)) != 0 ) { if ( rv < 0 ) goto err; } else if ( (rv = parse_paren_expr(pgp, &npc, &match)) != 0 ) { if ( rv < 0 ) goto err; } else if ( (rv = parse_literal(pgp, &npc, &match)) != 0 ) { if ( rv < 0 ) goto err; } else if ( (rv = parse_class(pgp, &npc, &match)) != 0 ) { if ( rv < 0 ) goto err; } else { if ( prefix == PEG_ATTR_NONE ) return 0; pgp->err = PEG_ERR_BAD_PRIMARY; pgp->eloc = *pc; return -1; } pri = peg_node_new(peg, PEG_PRIMARY, pc->line); if ( pri < 0 ) { pgp->err = PEG_ERR_NOMEM; goto err; } if ( string_match(pgp, "?", &npc) ) suffix = PEG_ATTR_QUESTION; else if ( string_match(pgp, "*", &npc) ) suffix = PEG_ATTR_STAR; else if ( string_match(pgp, "+", &npc) ) suffix = PEG_ATTR_PLUS; else suffix = PEG_ATTR_NONE; rv = parse_code(pgp, &npc, &r); if ( rv < 0 ) goto err; if ( rv > 0 ) { action = PEG_ACT_CODE; } else { rv = parse_action_label(pgp, &npc, &r); if ( rv < 0 ) goto err; if ( rv > 0 ) action = PEG_ACT_LABEL; } pn = NODE(peg, pri); pn->pn_next = -1; pn->pp_match = match; pn->pp_prefix = prefix; pn->pp_suffix = suffix; pn->pp_action = action; pn->pn_action_cb = NULL; pn->pp_code = r; *pc = npc; *prip = pri; return 1; err: peg_node_free(peg, match); return -1; }