diff options
author | kartofen <mladenovnasko0@gmail.com> | 2025-07-05 12:14:27 +0300 |
---|---|---|
committer | kartofen <mladenovnasko0@gmail.com> | 2025-07-05 12:14:27 +0300 |
commit | 0e0c0e0f26fcd669e45604fd5d9bcc2891a932a2 (patch) | |
tree | f57eb9f80883bdab57d00a97ad97508ecdbb0c2d /clr-table.c | |
parent | f2bef76fb369d4c9c3e53dca60eb78b75bb02d97 (diff) |
lalr now acutally works
Diffstat (limited to 'clr-table.c')
-rw-r--r-- | clr-table.c | 56 |
1 files changed, 39 insertions, 17 deletions
diff --git a/clr-table.c b/clr-table.c index 82f553d..23345ec 100644 --- a/clr-table.c +++ b/clr-table.c @@ -1,5 +1,9 @@ #include <stdio.h> #include <stdlib.h> +#include <stdint.h> + +// TODO: idk but a good parser should just exit(1) +// like in itemset_handle() #ifndef XCALLOC_IMPLEMENTED #define XCALLOC_IMPLEMENTED @@ -34,9 +38,9 @@ struct item { symbol lookahead; }; -#ifndef _LAZY_LALR static int item_eq(struct item *i1, struct item *i2) { return (i1->dot == i2->dot && i1->prod_idx == i2->prod_idx && i1->lookahead == i2->lookahead) ? 1 : 0; } -#else + +#ifdef _LAZY_LALR static int item_core_eq(struct item *i1, struct item *i2) { return (i1->dot == i2->dot && i1->prod_idx == i2->prod_idx) ? 1 : 0; } #endif @@ -63,27 +67,31 @@ static void itemset_print(struct item *set, size_t nset) static size_t itemset_handle(struct item *set, size_t nset) { +#ifdef _LAZY_LALR + int use_state = SIZE_MAX; +#endif + // 1. is set in seen_sets for(size_t i = 0; i < nseen_sets; i++) { -#ifndef _LAZY_LALR - if(seen_sets[i].nitems != nset) continue; - - int _seen = 0; - for(size_t j = 0; j < nset; j++) { - _seen = 0; - for(size_t k = 0; k < nset; k++) - if(item_eq(&seen_sets[i].items[k], &set[j])) _seen = 1; - if(!_seen) break; + if(seen_sets[i].nitems == nset) { + int _seen = 0; + for(size_t j = 0; j < nset; j++) { + _seen = 0; + for(size_t k = 0; k < nset; k++) + if(item_eq(&seen_sets[i].items[k], &set[j])) _seen = 1; + if(!_seen) break; + } + if(_seen) return seen_sets[i].state; } - if(_seen) return seen_sets[i].state; -#else + +#ifdef _LAZY_LALR int _same_core = 1; for(size_t j = 0; j < nset; j++) { for(size_t k = 0; k < seen_sets[i].nitems; k++) if(!item_core_eq(&seen_sets[i].items[k], &set[j])) _same_core = 0; if(!_same_core) break; } - if(_same_core) return seen_sets[i].state; + if(_same_core) use_state = seen_sets[i].state; #endif } @@ -99,7 +107,11 @@ static size_t itemset_handle(struct item *set, size_t nset) seen_sets[nseen_sets].items[i] = set[i]; // 3. insert new state +#ifdef _LAZY_LALR + size_t new_state = seen_sets[nseen_sets++].state = (use_state != SIZE_MAX) ? use_state : table_states++; +#else size_t new_state = seen_sets[nseen_sets++].state = table_states++; +#endif if(new_state >= TABLE_CAP) { fprintf(stderr, "ERROR: TABLE_CAP exceeded\n"); exit(1); @@ -218,7 +230,12 @@ cleanup: static int table_insert(size_t state, symbol sym, struct action a) { - if(table[state][sym].type != ACTION_NOT_SET) { + if(table[state][sym].type != ACTION_NOT_SET) +#ifdef _LAZY_LALR + if(table[state][sym].type != a.type && + table[state][sym].arg != a.arg) +#endif + { fprintf(stderr, "TABLE COLLISION on state '%zu' sym '%d'\n", state, sym); fprintf(stderr, "\t{%d %zu} vs {%d %zu}\n", table[state][sym].type, table[state][sym].arg, @@ -301,6 +318,11 @@ int main(void) table_fill(); table_print(); + for(size_t i = 0; i < nseen_sets; i++) + { + printf("\nSTATE: %zu\n", i); + itemset_print(seen_sets[i].items, seen_sets[i].nitems); + } table_free(); util_tables_free(); @@ -332,8 +354,8 @@ int main(void) * +---+------------------------+ * | 0 | s1 s2 g4 g5 | * | 1 | s1 s2 g3 | - * | 2 | r3 r3 | - * | 3 | r2 r2 | + * | 2 | r3 r3 r3 | + * | 3 | r2 r2 r2 | * | 4 | a | * | 5 | s1 s2 g6 | * | 6 | r1 | |