diff options
| author | kartofen <kartofen.mail.0@protonmail.com> | 2025-07-20 01:32:24 +0300 |
|---|---|---|
| committer | kartofen <kartofen.mail.0@protonmail.com> | 2025-07-20 01:32:24 +0300 |
| commit | 34357640c0676f33ad13aac1fe28effc6f6e47c7 (patch) | |
| tree | d656ee61da7d7a0b133aa57311266653ef100569 /demos/sample-files/gram-skeleton.c | |
| parent | 174e9b35ce3b6e99e500907f1bb24c6f31f481bf (diff) | |
start of grammar parsing
Diffstat (limited to 'demos/sample-files/gram-skeleton.c')
| -rw-r--r-- | demos/sample-files/gram-skeleton.c | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/demos/sample-files/gram-skeleton.c b/demos/sample-files/gram-skeleton.c new file mode 100644 index 0000000..89ef6b4 --- /dev/null +++ b/demos/sample-files/gram-skeleton.c @@ -0,0 +1,149 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +#define ARENA_IMPLEMENTATION +#include "util/arena.h" + +static char buf[1024]; +static struct arena_ctx global_arena = ARENA_CTX_INIT(buf, sizeof(buf)); +static void *xalloc(size_t sz) { + void *addr = arena_allocate(&global_arena, sz); + if(!addr) { + fprintf(stderr, "ERROR: Arena empty\n"); exit(1); + } + + return addr; +} + +// generated +#include "bin/gram.h" +#include "bin/gram.c" + +#include "parts/toklist.h" +struct token { + symbol s; + intptr_t v; +} tok; + +static char *next_token(char *str); + +symbol token_sym(struct token *t) { return t->s; } +intptr_t token_val(struct token *t) { return t->v; } + +static char *input = (char []){ + "-left B;" + "-right C;" + "-left D;" + "" + "A: B {a}" + " | C N {d}." +}; + +struct token *toklist_eat() +{ + static struct token t; + t = tok; + input = next_token(input); + return &t; +} + +struct token *toklist_peek() { return &tok; } + +#include "lr-parser.c" + +int main(void) +{ + input = next_token(input); + + intptr_t value; + if(lr_parser(&value)) { + return 1; + } + + printf("OUTPUT: %jd\n", value); + return 0; +} + +// STR UTIL + +#define strdup(...) _strdup(__VA_ARGS__) +static inline char *_strdup(char *str) +{ + return memcpy(xalloc(strlen(str) + 1), str, strlen(str)+1); +} + +static inline char *substring(char *str, size_t sub_end) +{ + static char sub[128]; + if(sub_end+1 > sizeof(sub)) return NULL; + + sub[sub_end] = '\0'; + return memcpy(sub, str, sub_end); +} + +// LEXER + +static inline int issep(char c) +{ + return isspace(c) || c == '\0' || c == ':' || c == '|' || c == ';' || c == '.' || c == '-' || c == '{'; +} + +static inline int tillsep(char *str) +{ + size_t i = 0; + while(!issep(str[i++])); + return i-1; +} + +static char *next_token(char *str) +{ + if(!str) return str; + + size_t off = 0; + char c0 = str[0]; + + if(c0 == '\0') tok.s = END_INPUT; + if(isspace(c0)) return next_token(str+1); + else { + off = tillsep(str); + if(off == 0) { // sep + switch(str[off++]) { + case ':': tok.s = COLON; break; + case '|': tok.s = PIPE; break; + case ';': tok.s = SEMICOL; break; + case '.': tok.s = DOT; break; + case '-': + off = tillsep(++str); + char *s = substring(str, off); + if(strcmp(s, "left") == 0) tok.s = D_LEFT; + else if(strcmp(s, "right") == 0) tok.s = D_RIGHT; + else if(strcmp(s, "terminal") == 0) tok.s = D_TERMINAL; + else if(strcmp(s, "nonterminal") == 0) tok.s = D_NONTERM; + else { fprintf(stderr, "ERROR: Unknown directive '-%s'\n", s); goto fail; } + break; + case '{': + for(int c = 1; c != 0; off++) + if(str[off] == '\0') { fprintf(stderr, "ERROR: No closing '{'\n"); goto fail; } + else if(str[off] == '{') c++; + else if(str[off] == '}') c--; + tok.s = ACTION; + tok.v = (intptr_t)strdup(substring(str, off)); + break; + } + } else if(isalpha(c0)) { // iden or named symbol + tok.s = IDEN; + tok.v = (intptr_t)strdup(substring(str, off)); + } else if(c0 >= '0' && c0 <= '9') { // num + tok.s = NUM; + tok.v = (intptr_t)atoi(substring(str, off)); + } + } + + return str+off; + +fail: + tok.s = END_INPUT; + return NULL; +} |
