diff options
author | kartofen <mladenovnasko0@gmail.com> | 2025-07-06 17:35:06 +0300 |
---|---|---|
committer | kartofen <mladenovnasko0@gmail.com> | 2025-07-06 17:35:06 +0300 |
commit | b65dd53885eabb8f39a3115039563edc08efb2b4 (patch) | |
tree | 75ec27e5cda989316b2498c913e0283c9ed08841 /lr-parser.c | |
parent | 0e0c0e0f26fcd669e45604fd5d9bcc2891a932a2 (diff) |
quick and easy semantic actions
Diffstat (limited to 'lr-parser.c')
-rw-r--r-- | lr-parser.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/lr-parser.c b/lr-parser.c index 3ab9af4..f7197c5 100644 --- a/lr-parser.c +++ b/lr-parser.c @@ -9,6 +9,9 @@ #include "parts/grammar.h" #include "parts/table.h" #include "parts/toklist.h" +// and +typedef int (*semantic_action_fn)(int *stack_head); +extern semantic_action_fn *semantic_actions; typedef int stack_item; @@ -32,10 +35,12 @@ int lr_parser() switch(a.type) { case ACTION_SHIFT: push(eat()); + push(-10000000); // the semantic action push(a.arg); break; case ACTION_REDUCE: - for(size_t i = 0; i < 2*grammar[a.arg].nRHS; i++) pop(); + int semantic_value = semantic_actions[a.arg](stack_head); + for(size_t i = 0; i < 3*grammar[a.arg].nRHS; i++) pop(); symbol lhs = grammar[a.arg].LHS; struct action a_goto = table[(size_t)*stack_head][lhs]; @@ -47,10 +52,11 @@ int lr_parser() } push(lhs); + push(semantic_value); push(a_goto.arg); break; case ACTION_ACCEPT: - return 0; + return *(stack_head-1); case ACTION_NOT_SET: default: fprintf(stderr, @@ -124,6 +130,9 @@ static symbol *tok = toklist; symbol toklist_eat() { return *(tok++); } // unsafe symbol toklist_peek() { return *tok; } // unsafe +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(); |