calc.c (6376B)
1 /* calc.c — HAND-WRITTEN stand-in for `gramgen` output: the static parse tables 2 * for the calc grammar plus the thin constructor. All control flow lives in 3 * the shared driver (runtime/gramparse.c). */ 4 #include "calc.h" 5 #include <kit/support/gram_parse_tables.h> 6 7 /* ---- guard sets for { } / [ ] (pooled) ---- */ 8 static const KitGramTokenKind g_sets[] = { 9 TOK_PLUS, TOK_MINUS, /* set 0: FIRST(expr_tail) */ 10 TOK_STAR, TOK_SLASH, /* set 1: FIRST(term_tail) */ 11 TOK_MINUS, /* set 2: optional unary minus */ 12 }; 13 static const uint16_t g_set_off[] = { 0, 2, 4, 5 }; 14 15 /* ---- single-symbol bodies of { } / [ ] ---- */ 16 static const KitGramSym sub_exprtail[] = { KIT_GRAM_RULE(R_expr_tail) }; 17 static const KitGramSym sub_termtail[] = { KIT_GRAM_RULE(R_term_tail) }; 18 static const KitGramSym sub_optminus[] = { KIT_GRAM_TERM(TOK_MINUS) }; 19 20 /* ---- productions (kids arity == nsyms; a REP/OPT counts as one) ---- */ 21 static const KitGramSym p_expr0[] = { KIT_GRAM_RULE(R_term), 22 { .kind = KIT_GRAM_S_REP, .first = 0, .sub = sub_exprtail, .nsub = 1 } }; 23 static const KitGramSym p_exprtail0[] = { KIT_GRAM_RULE(R_add_op), KIT_GRAM_RULE(R_term) }; 24 static const KitGramSym p_addop0[] = { KIT_GRAM_TERM(TOK_PLUS) }; 25 static const KitGramSym p_addop1[] = { KIT_GRAM_TERM(TOK_MINUS) }; 26 static const KitGramSym p_term0[] = { KIT_GRAM_RULE(R_factor), 27 { .kind = KIT_GRAM_S_REP, .first = 1, .sub = sub_termtail, .nsub = 1 } }; 28 static const KitGramSym p_termtail0[] = { KIT_GRAM_RULE(R_mul_op), KIT_GRAM_RULE(R_factor) }; 29 static const KitGramSym p_mulop0[] = { KIT_GRAM_TERM(TOK_STAR) }; 30 static const KitGramSym p_mulop1[] = { KIT_GRAM_TERM(TOK_SLASH) }; 31 static const KitGramSym p_factor0[] = { { .kind = KIT_GRAM_S_OPT, .first = 2, .sub = sub_optminus, .nsub = 1 }, 32 KIT_GRAM_RULE(R_primary) }; 33 static const KitGramSym p_primary0[] = { KIT_GRAM_TERM(TOK_NUMBER) }; 34 static const KitGramSym p_primary1[] = { KIT_GRAM_TERM(TOK_LPAREN), KIT_GRAM_RULE(R_expr), KIT_GRAM_TERM(TOK_RPAREN) }; 35 36 #define PROD(arr) { .syms = (arr), .nsyms = (uint16_t)(sizeof(arr) / sizeof((arr)[0])) } 37 38 static const KitGramProd prods_expr[] = { PROD(p_expr0) }; 39 static const KitGramProd prods_exprtail[] = { PROD(p_exprtail0) }; 40 static const KitGramProd prods_addop[] = { PROD(p_addop0), PROD(p_addop1) }; 41 static const KitGramProd prods_term[] = { PROD(p_term0) }; 42 static const KitGramProd prods_termtail[] = { PROD(p_termtail0) }; 43 static const KitGramProd prods_mulop[] = { PROD(p_mulop0), PROD(p_mulop1) }; 44 static const KitGramProd prods_factor[] = { PROD(p_factor0) }; 45 static const KitGramProd prods_primary[] = { PROD(p_primary0), PROD(p_primary1) }; 46 47 /* ---- prediction + FIRST (reused for "expected" reporting) ---- */ 48 static const KitGramTokenKind fst_expr[] = { TOK_MINUS, TOK_NUMBER, TOK_LPAREN }; 49 static const uint8_t pp_expr[] = { 0, 0, 0 }; 50 static const KitGramTokenKind fst_exprtail[] = { TOK_PLUS, TOK_MINUS }; 51 static const uint8_t pp_exprtail[] = { 0, 0 }; 52 static const KitGramTokenKind fst_addop[] = { TOK_PLUS, TOK_MINUS }; 53 static const uint8_t pp_addop[] = { 0, 1 }; 54 static const KitGramTokenKind fst_term[] = { TOK_MINUS, TOK_NUMBER, TOK_LPAREN }; 55 static const uint8_t pp_term[] = { 0, 0, 0 }; 56 static const KitGramTokenKind fst_termtail[] = { TOK_STAR, TOK_SLASH }; 57 static const uint8_t pp_termtail[] = { 0, 0 }; 58 static const KitGramTokenKind fst_mulop[] = { TOK_STAR, TOK_SLASH }; 59 static const uint8_t pp_mulop[] = { 0, 1 }; 60 static const KitGramTokenKind fst_factor[] = { TOK_MINUS, TOK_NUMBER, TOK_LPAREN }; 61 static const uint8_t pp_factor[] = { 0, 0, 0 }; 62 static const KitGramTokenKind fst_primary[] = { TOK_NUMBER, TOK_LPAREN }; 63 static const uint8_t pp_primary[] = { 0, 1 }; 64 65 /* ---- FOLLOW (panic-mode resync) ---- */ 66 static const KitGramTokenKind flw_expr[] = { TOK_EOF, TOK_RPAREN }; 67 static const KitGramTokenKind flw_exprtail[] = { TOK_PLUS, TOK_MINUS, TOK_EOF, TOK_RPAREN }; 68 static const KitGramTokenKind flw_addop[] = { TOK_MINUS, TOK_NUMBER, TOK_LPAREN }; 69 static const KitGramTokenKind flw_term[] = { TOK_PLUS, TOK_MINUS, TOK_EOF, TOK_RPAREN }; 70 static const KitGramTokenKind flw_termtail[] = { TOK_STAR, TOK_SLASH, TOK_PLUS, TOK_MINUS, TOK_EOF, TOK_RPAREN }; 71 static const KitGramTokenKind flw_mulop[] = { TOK_MINUS, TOK_NUMBER, TOK_LPAREN }; 72 static const KitGramTokenKind flw_factor[] = { TOK_STAR, TOK_SLASH, TOK_PLUS, TOK_MINUS, TOK_EOF, TOK_RPAREN }; 73 static const KitGramTokenKind flw_primary[] = { TOK_STAR, TOK_SLASH, TOK_PLUS, TOK_MINUS, TOK_EOF, TOK_RPAREN }; 74 75 #define N(arr) (uint16_t)(sizeof(arr) / sizeof((arr)[0])) 76 #define RULE(nm, pr, np, fst, pd, flw) \ 77 { .name = nm, .prods = pr, .nprods = np, \ 78 .predict_tok = fst, .predict_prod = pd, .npredict = N(fst), \ 79 .first = fst, .nfirst = N(fst), .follow = flw, .nfollow = N(flw) } 80 81 static const KitGramRule g_rules[] = { 82 [R_expr] = RULE("expr", prods_expr, 1, fst_expr, pp_expr, flw_expr), 83 [R_expr_tail] = RULE("expr_tail", prods_exprtail, 1, fst_exprtail, pp_exprtail, flw_exprtail), 84 [R_add_op] = RULE("add_op", prods_addop, 2, fst_addop, pp_addop, flw_addop), 85 [R_term] = RULE("term", prods_term, 1, fst_term, pp_term, flw_term), 86 [R_term_tail] = RULE("term_tail", prods_termtail, 1, fst_termtail, pp_termtail, flw_termtail), 87 [R_mul_op] = RULE("mul_op", prods_mulop, 2, fst_mulop, pp_mulop, flw_mulop), 88 [R_factor] = RULE("factor", prods_factor, 1, fst_factor, pp_factor, flw_factor), 89 [R_primary] = RULE("primary", prods_primary, 2, fst_primary, pp_primary, flw_primary), 90 }; 91 92 static const char *const g_tok_names[] = { 93 "EOF", "+", "-", "*", "/", "NUMBER", "(", ")" 94 }; 95 96 const KitGramGrammar calc_grammar = { 97 .name = "calc", 98 .rules = g_rules, .nrules = R__COUNT, 99 .start = R_expr, .eof = TOK_EOF, 100 .sets = g_sets, .set_off = g_set_off, .nsets = 3, 101 .tok_names = g_tok_names, .ntoks = TOK__COUNT, 102 }; 103 104 void calc_parser_init(KitGramParser *mem, const KitGramConfig *cfg) { 105 kit_gram_parser_init(mem, &calc_grammar, cfg); 106 }