aboutsummaryrefslogtreecommitdiff
path: root/lr-parser.c
diff options
context:
space:
mode:
authorkartofen <mladenovnasko0@gmail.com>2025-07-06 17:35:06 +0300
committerkartofen <mladenovnasko0@gmail.com>2025-07-06 17:35:06 +0300
commitb65dd53885eabb8f39a3115039563edc08efb2b4 (patch)
tree75ec27e5cda989316b2498c913e0283c9ed08841 /lr-parser.c
parent0e0c0e0f26fcd669e45604fd5d9bcc2891a932a2 (diff)
quick and easy semantic actions
Diffstat (limited to 'lr-parser.c')
-rw-r--r--lr-parser.c13
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();