aboutsummaryrefslogtreecommitdiff
path: root/clr-table.c
diff options
context:
space:
mode:
Diffstat (limited to 'clr-table.c')
-rw-r--r--clr-table.c56
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 |