summaryrefslogtreecommitdiff
path: root/src/crf.c
diff options
context:
space:
mode:
authorJSDurand <mmemmew@gmail.com>2022-01-31 09:23:20 +0800
committerJSDurand <mmemmew@gmail.com>2022-01-31 09:23:20 +0800
commita8bd5e9d85ac9928bd29add82e887f82642af893 (patch)
tree74e377f9fccffc2779ff97fa0bd8ad180b9c865c /src/crf.c
parente555c88b8107caf886da229444c2bed1aaef6c2c (diff)
test/check_cnp: working algorithm
I now have a working algorithm in test/check_cnp. It can correctly parse the grammar for an esoteric language called "Brainfuck". This language does not matter. What matters is that it contains parentheses. So this shows that at least for grammars as complex as parentheses, this parser works well. Haha.
Diffstat (limited to 'src/crf.c')
-rw-r--r--src/crf.c68
1 files changed, 54 insertions, 14 deletions
diff --git a/src/crf.c b/src/crf.c
index dbcb050..1cff96f 100644
--- a/src/crf.c
+++ b/src/crf.c
@@ -134,6 +134,13 @@ destroy_spa(spa * const restrict spap)
free(spap);
}
+__attribute__((__pure__, __cold__))
+ht *
+spa_ht(CCR_MOD(spa *) spap)
+{
+ return spap->table;
+}
+
BOOL
spa_insert(spa * const restrict spap, pair3 label)
{
@@ -270,6 +277,7 @@ new_procr(NUM size, BOOL * const restrict errorp)
pr->len = size;
pr->array = NULL;
+ pr->mg = 0;
SAFE_MALLOC(procr_array_element, pr->array,
sizeof(procr_array_element) * size,
@@ -287,6 +295,8 @@ new_procr(NUM size, BOOL * const restrict errorp)
if (pr) free(pr);
+ pr = NULL;
+
success:
return pr;
@@ -320,12 +330,37 @@ new_procu(NUM size, BOOL * const restrict errorp)
if (pu) free(pu);
+ pu = NULL;
+
success:
return pu;
}
void
+print_procr(CCR_MOD(procr *) pr)
+{
+ eprintf("\n");
+ fleprintf0("Printing procr...\n");
+ fleprintf("LEN = %ld, MG = %ld\n", pr->len, pr->mg);
+ for (NUM i = 0; i < pr->len; i++) {
+ if ((pr->array+i)->initialized) {
+ if (list_length((pr->array+i)->ls)) eprintf("%ld: ", i);
+ for (NUM j = 0; j < list_length((pr->array+i)->ls); j++) {
+ fleprintf("(%ld, %ld, %ld, %ld)",
+ ((pair4 *) list_nth((pr->array+i)->ls, j))->x,
+ ((pair4 *) list_nth((pr->array+i)->ls, j))->y,
+ ((pair4 *) list_nth((pr->array+i)->ls, j))->z,
+ ((pair4 *) list_nth((pr->array+i)->ls, j))->w);
+ if (j+1==list_length((pr->array+i)->ls)) eprintf("\n");
+ else eprintf(", ");
+ }
+ }
+ }
+ eprintf("\n");
+}
+
+void
destroy_procr(procr * const restrict pr)
{
for (NUM i = 0; i < pr->len; i++)
@@ -353,13 +388,13 @@ BOOL
desc_add(procr * const restrict pr, procu * const restrict pu,
NUM grade, prodecor dec)
{
+ pair4 *p4 = NULL;
+
if (grade < 0 || grade >= pu->len) {
fleprintf("Invalid grade: %ld\n", grade);
goto cleanup;
}
- pair4 *p4 = NULL;
-
#define HELE (pu->array+grade)
#define LELE (pr->array+grade)
@@ -441,6 +476,8 @@ desc_add(procr * const restrict pr, procu * const restrict pu,
cleanup:
+ if (p4) free(p4);
+
return 1;
success:
@@ -457,13 +494,10 @@ pop_procr(procr * pr, procu * pu, NUM *gradep)
#define ELEMENT (pr->array+pr->mg)
- if (!(ELEMENT->initialized)) goto reset_mg;
-
- *gradep = pr->mg;
-
- result = pop_from_list(ELEMENT->ls);
+ if (ELEMENT->initialized && list_length(ELEMENT->ls))
+ goto no_reset_mg;
- if (list_length(ELEMENT->ls) == 0) {
+ if (ELEMENT->initialized && list_length(ELEMENT->ls) == 0) {
destroy_ht((pu->array+pr->mg)->table, DESTROY_KEY_SELF);
(pu->array+pr->mg)->initialized = 0;
(pu->array+pr->mg)->table = NULL;
@@ -471,17 +505,23 @@ pop_procr(procr * pr, procu * pu, NUM *gradep)
destroy_list(ELEMENT->ls, 1);
ELEMENT->initialized = 0;
ELEMENT->ls = NULL;
+ }
- /* REVIEW: Maybe we can just increment the minimal grade, as we
- won't jump over two steps? */
- reset_mg:
- while (++(pr->mg) < pr->len) {
- if (ELEMENT->initialized) break;
- }
+ while (++(pr->mg) < pr->len) {
+ if (ELEMENT->initialized) break;
}
+ if (pr->mg >= pr->len) goto success;
+
+ no_reset_mg:
+
+ result = pop_from_list(ELEMENT->ls);
+
+ *gradep = pr->mg;
+
#undef ELEMENT
success:
return result;
+
}