diff options
Diffstat (limited to 'recursive-ascent.c')
-rw-r--r-- | recursive-ascent.c | 316 |
1 files changed, 0 insertions, 316 deletions
diff --git a/recursive-ascent.c b/recursive-ascent.c deleted file mode 100644 index 7f69e57..0000000 --- a/recursive-ascent.c +++ /dev/null @@ -1,316 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> - -/* - * For grammar: (https://en.wikipedia.org/wiki/Recursive_ascent_parser) - * expr : expr '+' term { $$ = $1 + $3; } - * | expr '-' term { $$ = $1 - $3; } - * | term { $$ = $1; } - * ; - * - * term : '(' expr ')' { $$ = $2; } - * | num { $$ = $1; } - * ; - * - * num : '0' { $$ = 0; } - * | '1' { $$ = 1; } - * ; - */ - -#pragma GCC diagnostic ignored "-Wunused-value" - -#define DIE(...) (printf("ERROR %s:%d\n", __FILE__, __LINE__), __VA_OPT__(exit(__VA_ARGS__),) exit(1), 1) - -enum nonterminal { EXPR, TERM, NUM }; -struct result { enum nonterminal nonterm; int value; int depth; char *s; }; - -struct args { int args[2]; }; -#define new_arg(...) (struct args){{__VA_ARGS__}} -#define get_arg(a, n) ((a).args[n]) - -struct result state0(char *s, struct args a); -struct result state1(char *s, struct args a); -struct result state2(char *s, struct args a); -struct result state3(char *s, struct args a); -struct result state4(char *s, struct args a); -struct result state5(char *s, struct args a); -struct result state6(char *s, struct args a); -struct result state7(char *s, struct args a); -struct result state8(char *s, struct args a); -struct result state9(char *s, struct args a); -struct result state10(char *s, struct args a); -struct result state11(char *s, struct args a); -struct result state12(char *s, struct args a); -struct result state13(char *s, struct args a); - -int main(void) -{ - char *s = "1-((0-1)+1+1+1+1+1)-0+1-(((1)))+1+1+1-1+0+(1-0+1)-1-0"; - struct result r = state0(s, new_arg(0)); - printf("%s = %d\n", s, r.value); - return 0; -} - -/* - * 0 $accept: . expr $end - * - * '(' shift, and go to state 1 - * '0' shift, and go to state 2 - * '1' shift, and go to state 3 - * - * expr go to state 4 - * term go to state 5 - * num go to state 6 - */ -struct result state0(char *s, struct args a) -{ - struct result r = {0}; - switch(*s) { - case '(': r = state1(s+1, a); break; - case '0': r = state2(s+1, a); break; - case '1': r = state3(s+1, a); break; - default: DIE(); - } - - while(r.depth == 0) { - switch(r.nonterm) { - case EXPR: r = state4(r.s, new_arg(r.value)); break; - case TERM: r = state5(r.s, new_arg(r.value)); break; - case NUM: r = state6(r.s, new_arg(r.value)); break; - default: DIE(); - } - } - - r.depth--; - return r; -} - -/* - * 4 term: '(' . expr ')' - * - * '(' shift, and go to state 1 - * '0' shift, and go to state 2 - * '1' shift, and go to state 3 - * - * expr go to state 7 - * term go to state 5 - * num go to state 6 - */ -struct result state1(char *s, struct args a) -{ - struct result r = {0}; - switch(*s) { - case '(': r = state1(s+1, a); break; - case '0': r = state2(s+1, a); break; - case '1': r = state3(s+1, a); break; - default: DIE(); - } - - while(r.depth == 0) { - switch(r.nonterm) { - case EXPR: r = state7(r.s, new_arg(r.value)); break; - case TERM: r = state5(r.s, new_arg(r.value)); break; - case NUM: r = state6(r.s, new_arg(r.value)); break; - default: DIE(); - } - } - - r.depth--; - return r; -} - -/* - * 6 num: '0' . - * - * $default reduce using rule 6 (num) - */ -struct result state2(char *s, struct args a) -{ - (void)a; - return (struct result){NUM, 0, 0, s}; -} - -/* - * 7 num: '1' . - * - * $default reduce using rule 7 (num) - */ -struct result state3(char *s, struct args a) -{ - (void)a; - return (struct result){NUM, 1, 0, s}; -} - -/* - * 0 $accept: expr . $end - * 1 expr: expr . '+' term - * 2 | expr . '-' term - * - * $end shift, and go to state 8 - * '+' shift, and go to state 9 - * '-' shift, and go to state 10 - */ -struct result state4(char *s, struct args a) -{ - struct result r = {0}; - switch(*s) { - case '\0': r = state8(s+1, a); break; - case '+': r = state9(s+1, a); break; - case '-': r = state10(s+1, a); break; - default: DIE(); - } - - (r.depth == 0) && DIE(); - - r.depth--; - return r; -} - -/* - * 3 expr: term . - * - * $default reduce using rule 3 (expr) - */ -struct result state5(char *s, struct args a) -{ - return (struct result){EXPR, get_arg(a, 0), 0, s}; -} - -/* - * 5 term: num . - * - * $default reduce using rule 5 (term) - */ -struct result state6(char *s, struct args a) -{ - return (struct result){TERM, get_arg(a, 0), 0, s}; -} - -/* - * 1 expr: expr . '+' term - * 2 | expr . '-' term - * 4 term: '(' expr . ')' - * - * '+' shift, and go to state 9 - * '-' shift, and go to state 10 - * ')' shift, and go to state 11 - */ -struct result state7(char *s, struct args a) -{ - struct result r = {0}; - switch(*s) { - case '+': r = state9(s+1, a); break; - case '-': r = state10(s+1, a); break; - case ')': r = state11(s+1, a); break; - default: DIE(); - } - - (r.depth == 0) && DIE(); - - r.depth--; - return r; -} - -/* - * 0 $accept: expr $end . - * - * $default accept - */ -struct result state8(char *s, struct args a) -{ - return (struct result){EXPR, a.args[0], 2, s}; -} - -/* - * 1 expr: expr '+' . term - * - * '(' shift, and go to state 1 - * '0' shift, and go to state 2 - * '1' shift, and go to state 3 - * - * term go to state 12 - * num go to state 6 - */ -struct result state9(char *s, struct args a) -{ - struct result r = {0}; - switch(*s) { - case '(': r = state1(s+1, a); break; - case '0': r = state2(s+1, a); break; - case '1': r = state3(s+1, a); break; - default: DIE(); - } - - while(r.depth == 0) { - switch(r.nonterm) { - case TERM: r = state12(r.s, new_arg(r.value, get_arg(a, 0))); break; - case NUM: r = state6(r.s, new_arg(r.value)); break; - default: DIE(); - } - } - - r.depth--; - return r; -} - -/* - * 2 expr: expr '-' . term - * - * '(' shift, and go to state 1 - * '0' shift, and go to state 2 - * '1' shift, and go to state 3 - * - * term go to state 13 - * num go to state 6 - */ -struct result state10(char *s, struct args a) -{ - struct result r = {0}; - switch(*s) { - case '(': r = state1(s+1, a); break; - case '0': r = state2(s+1, a); break; - case '1': r = state3(s+1, a); break; - default: DIE(); - } - - while(r.depth == 0) { - switch(r.nonterm) { - case TERM: r = state13(r.s, new_arg(get_arg(a, 0), r.value)); break; - case NUM: r = state6(r.s, new_arg(r.value)); break; - default: DIE(); - } - } - - r.depth--; - return r; -} - -/* - * 4 term: '(' expr ')' . - * - * $default reduce using rule 4 (term) - */ -struct result state11(char *s, struct args a) -{ - return (struct result){TERM, get_arg(a, 0), 2, s}; -} - -/* - * 1 expr: expr '+' term . - * - * $default reduce using rule 1 (expr) - */ -struct result state12(char *s, struct args a) -{ - return (struct result){EXPR, get_arg(a, 0) + get_arg(a, 1), 2, s}; -} - -/* - * 2 expr: expr '-' term . - * - * $default reduce using rule 2 (expr) - */ -struct result state13(char *s, struct args a) -{ - return (struct result){EXPR, get_arg(a, 0) - get_arg(a, 1), 2, s}; -} |