aboutsummaryrefslogtreecommitdiff
path: root/lr-parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'lr-parser.c')
-rw-r--r--lr-parser.c60
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