diff options
author | kartofen <mladenovnasko0@gmail.com> | 2025-07-08 18:25:29 +0300 |
---|---|---|
committer | kartofen <mladenovnasko0@gmail.com> | 2025-07-08 18:25:29 +0300 |
commit | d028cc9c04cf46256166434bdea68d5f5c6d310f (patch) | |
tree | 28420104516e446a06172687eae16e3bf4dfd5bd /lr-parser.c | |
parent | 919611902c39fd70afe1162883ee6bfd34f2642e (diff) |
simple calculator example
Diffstat (limited to 'lr-parser.c')
-rw-r--r-- | lr-parser.c | 60 |
1 files changed, 41 insertions, 19 deletions
diff --git a/lr-parser.c b/lr-parser.c index 0d244fd..ad7dae5 100644 --- a/lr-parser.c +++ b/lr-parser.c @@ -20,23 +20,25 @@ typedef int stack_item; static stack_item stack_bottom[STACK_CAP]; static stack_item *stack_head = stack_bottom; -int lr_parser() +int lr_parser(int *value) { -#define push(item) ({ if(++stack_head - stack_bottom < STACK_CAP ) (*stack_head = item); else { fprintf(stderr, "ERROR: STACK_CAP exceeded\n"); return 1; }}) +#define push(item) do { \ + if(++stack_head - stack_bottom < STACK_CAP ) *stack_head = item; \ + else { fprintf(stderr, "ERROR: STACK_CAP exceeded\n"); return 1; } \ + } while(0) #define pop() (--stack_head) #define eat() toklist_eat() -#define peek() ({ \ - symbol s = toklist_peek(); \ - if(!symbol_is_valid(s)) { fprintf(stderr, "ERROR: Unknown token '%d'\n", s); return 1;} \ - s; }) +#define peek() toklist_peek() while(1) { - struct action a = table[(size_t)*stack_head][peek()]; + struct action a = table[(size_t)*stack_head][token_sym(peek())]; switch(a.type) { - case ACTION_SHIFT: - push(eat()); - push(-10000000); // the semantic action + case ACTION_SHIFT:; + struct token *t = eat(); + + push(token_sym(t)); + push(token_val(t)); push(a.arg); break; case ACTION_REDUCE: @@ -57,12 +59,13 @@ int lr_parser() push(a_goto.arg); break; case ACTION_ACCEPT: - return *(stack_head-1); + *value = *(stack_head-1); + return 0; case ACTION_NOT_SET: default: fprintf(stderr, - "ERROR: Unexpected token '%d' at state %zu\n", - peek(), (size_t)*stack_head); + "ERROR: Unexpected symbol '%d' at state %zu\n", + token_sym(peek()), (size_t)*stack_head); return 1; } } @@ -124,19 +127,38 @@ struct action **table = (struct action *([])){ size_t table_states = 13; -// implement toklist -static symbol toklist[] = {N0, PLUS, N1, END_INPUT}; -static symbol *tok = toklist; +// implement toklist.h +struct token { + symbol s; + int v; +}; + +static struct token toklist[] = {{N0}, {PLUS}, {N1}, {END_INPUT}}; +static const size_t ntoklist = sizeof(toklist)/sizeof(*toklist); -symbol toklist_eat() { return *(tok++); } // unsafe -symbol toklist_peek() { return *tok; } // unsafe +static size_t tok; + +struct token *toklist_eat() +{ + if(tok == ntoklist) return toklist + ntoklist-1; + return toklist + tok++; +} +struct token *toklist_peek() { return toklist + tok; } + +symbol token_sym(struct token *t) { return t->s; } +int token_val(struct token *t) { return t->v; } int none(int *stack_head) {(void)stack_head; return 0;} semantic_action_fn *semantic_actions = (semantic_action_fn[]){none, none, none, none, none, none, none, none}; int main(void) { - return lr_parser(); + int value; + + if(lr_parser(&value)) return 1; + printf("%d\n", value); + + return 0; } #endif |