aboutsummaryrefslogtreecommitdiff
path: root/recursive-ascent.c
diff options
context:
space:
mode:
Diffstat (limited to 'recursive-ascent.c')
-rw-r--r--recursive-ascent.c316
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};
-}