From 7f796bc571941a9c14eeb3a65d349d628f022275 Mon Sep 17 00:00:00 2001 From: kartofen Date: Mon, 30 Jun 2025 00:26:51 +0300 Subject: CLR yesss --- recursive-ascent-descent.c | 197 --------------------------------------------- 1 file changed, 197 deletions(-) delete mode 100644 recursive-ascent-descent.c (limited to 'recursive-ascent-descent.c') 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 // printf(char *, ...) -#include // 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; -} - -- cgit v1.2.3