kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

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 }