aboutsummaryrefslogtreecommitdiff
path: root/recursive-ascent-descent.c
diff options
context:
space:
mode:
Diffstat (limited to 'recursive-ascent-descent.c')
-rw-r--r--recursive-ascent-descent.c197
1 files changed, 0 insertions, 197 deletions
diff --git a/recursive-ascent-descent.c b/recursive-ascent-descent.c
deleted file mode 100644
index 628540d..0000000
--- a/recursive-ascent-descent.c
+++ /dev/null
@@ -1,197 +0,0 @@
-#include <stdio.h> // printf(char *, ...)
-#include <stdlib.h> // exit(int)
-
-/*
- * For grammar: (https://en.wikipedia.org/wiki/Recursive_ascent_parser)
- * (R1) expr : expr _ '+' term { $$ = $1 + $3; }
- * (R2) | expr _ '-' term { $$ = $1 - $3; }
- * (R3) | _ term { $$ = $1; }
- * ;
- *
- * (R4) term : _ '(' expr ')' { $$ = $2; }
- * (R5) | _ num { $$ = $1; }
- * ;
- *
- * (R6) num : _ '0' { $$ = 0; }
- * (R7) | _ '1' { $$ = 1; }
- * ;
- */
-
-#pragma GCC diagnostic ignored "-Wunused-value"
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-
-#define DIE(...) (printf("ERROR %s:%d\n", __FILE__, __LINE__), __VA_OPT__(exit(__VA_ARGS__),) exit(1), 1)
-
-enum nonterminal { INVAILID, 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])
-
-// top-down
-struct result rule0(char *s, struct args a);
-struct result rule1(char *s, struct args a);
-struct result rule2(char *s, struct args a);
-struct result rule3(char *s, struct args a);
-struct result rule4(char *s, struct args a);
-struct result rule5(char *s, struct args a);
-struct result rule6(char *s, struct args a);
-struct result rule7(char *s, struct args a);
-
-// bottom-up
-struct result accept(char *s, struct args a);
-struct result expr(char *s, struct args a);
-struct result expr2(char *s, struct args a);
-struct result term(char *s, struct args a);
-struct result num(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 = accept(s, new_arg(0));
- printf("%s = %d\n", s, r.value);
- return 0;
-}
-
-char *eat(char *s, char c)
-{
- if(*s == c)
- return s + 1;
- else DIE();
-}
-
-struct result rule0(char *s, struct args a)
-{
- struct result r = {0, 0, 0, s};
- r = expr(r.s, a);
- r.s = eat(r.s, '\0');
- return r;
-}
-
-struct result rule1(char *s, struct args a)
-{
- struct result r = {0, 0, 0, s};
- r.s = eat(r.s, '+');
- r = term(r.s, a);
- return (struct result){EXPR, get_arg(a, 0) + r.value, 0, r.s};
-}
-
-struct result rule2(char *s, struct args a)
-{
- struct result r = {0, 0, 0, s};
- r.s = eat(r.s, '-');
- r = term(r.s, a);
- return (struct result){EXPR, get_arg(a, 0) - r.value, 0, r.s};
-}
-
-struct result rule3(char *s, struct args a)
-{
- struct result r = {0, 0, 0, s};
- r = term(r.s, a);
- return (struct result){EXPR, r.value, 0, r.s};
-}
-
-struct result rule4(char *s, struct args a)
-{
- struct result r = {0, 0, 0, s};
- r.s = eat(r.s, '(');
- r = expr(r.s, a);
- r.s = eat(r.s, ')');
- return (struct result){EXPR, r.value, 1, r.s};
-}
-
-struct result rule5(char *s, struct args a)
-{
- struct result r = {0, 0, 0, s};
- r = num(r.s, a);
- return (struct result){TERM, r.value, 0, r.s};
-}
-
-struct result rule6(char *s, struct args a)
-{
- struct result r = {0, 0, 0, s};
- r.s = eat(r.s, '0');
- return (struct result){NUM, 0, 0, r.s};
-}
-
-struct result rule7(char *s, struct args a)
-{
- struct result r = {0, 0, 0, s};
- r.s = eat(r.s, '1');
- return (struct result){NUM, 1, 0, r.s};
-}
-
-struct result accept(char *s, struct args a)
-{
- struct result r = {0};
- switch(*s) {
- case '(':
- case '0':
- case '1': r = rule0(s, a); break;
- default: DIE();
- }
-
- return r;
-}
-
-struct result expr(char *s, struct args a)
-{
- struct result r = {0};
- switch(*s) {
- case '(':
- case '0':
- case '1': r = rule3(s, a); break;
- default: DIE();
- }
-
- struct result r2 = r;
- while(r2.depth == 0) {
- r = r2;
- switch(r.nonterm) {
- case EXPR: r2 = expr2(r.s, new_arg(r.value)); break;
- default: DIE();
- }
- }
-
- r.depth--;
- return r;
-}
-
-struct result expr2(char *s, struct args a)
-{
- struct result r = {0};
- switch(*s) {
- case '+': r = rule1(s, a); break;
- case '-': r = rule2(s, a); break;
- default: r.depth = 1;
- }
-
- return r;
-}
-
-struct result term(char *s, struct args a)
-{
- struct result r = {0};
- switch(*s) {
- case '(': r = rule4(s, a); break;
- case '0': r = rule5(s, a); break;
- case '1': r = rule5(s, a); break;
- default: DIE();
- }
-
- return r;
-}
-
-struct result num(char *s, struct args a)
-{
- struct result r = {0};
- switch(*s) {
- case '0': r = rule6(s, a); break;
- case '1': r = rule7(s, a); break;
- default: DIE();
- }
-
- return r;
-}
-