From 572f1c8f9e14e521317c54045ee22639d65b5ffe Mon Sep 17 00:00:00 2001
From: "Sven M. Hallberg" <pesco@khjk.org>
Date: Wed, 19 Jun 2013 18:22:19 +0200
Subject: [PATCH] expand stub GLR backend

---
 src/backends/glr.c | 60 +++++++++++++++++++++++++++++++++++-----------
 1 file changed, 46 insertions(+), 14 deletions(-)

diff --git a/src/backends/glr.c b/src/backends/glr.c
index c57ffd6..429d06b 100644
--- a/src/backends/glr.c
+++ b/src/backends/glr.c
@@ -1,6 +1,25 @@
 #include "lr.h"
 
 
+/* GLR compilation (LALR w/o failing on conflict) */
+
+int h_glr_compile(HAllocator* mm__, HParser* parser, const void* params)
+{
+  int result = h_lalr_compile(mm__, parser, params);
+
+  if(result == -1 && parser->backend_data) {
+    // table is there, just has conflicts? nevermind, that's okay.
+    result = 0;
+  }
+
+  return result;
+}
+
+void h_glr_free(HParser *parser)
+{
+  h_lalr_free(parser);
+}
+
 
 /* GLR driver */
 
@@ -12,12 +31,28 @@ HParseResult *h_glr_parse(HAllocator* mm__, const HParser* parser, HInputStream*
 
   HArena *arena  = h_new_arena(mm__, 0);    // will hold the results
   HArena *tarena = h_new_arena(mm__, 0);    // tmp, deleted after parse
-  HLREngine *engine = h_lrengine_new(arena, tarena, table);
 
-  // iterate engine to completion
-  while(h_lrengine_step(engine, h_lrengine_action(engine, stream)));
+  HSlist *engines = h_slist_new(tarena);
+  h_slist_push(engines, h_lrengine_new(arena, tarena, table));
+
+  HParseResult *result = NULL;
+  while(result == NULL && !h_slist_empty(engines)) {
+    for(HSlistNode **x = &engines->head; *x; ) {
+      HLREngine *engine = (*x)->elem;
+
+      const HLRAction *action = h_lrengine_action(engine, stream);
+      // XXX handle conflicts -> fork engine
+      bool running = h_lrengine_step(engine, action);
+
+      if(running) {
+        x = &(*x)->next;    // go to next
+      } else {
+        *x = (*x)->next;    // remove from list
+        result = h_lrengine_result(engine);
+      }
+    }
+  }
 
-  HParseResult *result = h_lrengine_result(engine);
   if(!result)
     h_delete_arena(arena);
   h_delete_arena(tarena);
@@ -27,9 +62,9 @@ HParseResult *h_glr_parse(HAllocator* mm__, const HParser* parser, HInputStream*
 
 
 HParserBackendVTable h__glr_backend_vtable = {
-  .compile = h_lalr_compile,
+  .compile = h_glr_compile,
   .parse = h_glr_parse,
-  .free = h_lalr_free
+  .free = h_glr_free
 };
 
 
@@ -39,16 +74,13 @@ HParserBackendVTable h__glr_backend_vtable = {
 int test_glr(void)
 {
   /* 
-     E -> E '-' T
-        | T
-     T -> '(' E ')'
-        | 'n'               -- also try [0-9] for the charset paths
+     E -> E '+' E
+        | 'd'
   */
 
-  HParser *n = h_ch('n');
+  HParser *d = h_ch('d');
   HParser *E = h_indirect();
-  HParser *T = h_choice(h_sequence(h_ch('('), E, h_ch(')'), NULL), n, NULL);
-  HParser *E_ = h_choice(h_sequence(E, h_ch('-'), T, NULL), T, NULL);
+  HParser *E_ = h_choice(h_sequence(E, h_ch('+'), E, NULL), d, NULL);
   h_bind_indirect(E, E_);
   HParser *p = E;
 
@@ -83,7 +115,7 @@ int test_glr(void)
   h_pprint_lrtable(stdout, g, (HLRTable *)p->backend_data, 0);
 
   printf("\n==== P A R S E  R E S U L T ====\n");
-  HParseResult *res = h_parse(p, (uint8_t *)"n-(n-((n)))-n", 13);
+  HParseResult *res = h_parse(p, (uint8_t *)"d+d+d", 5);
   if(res)
     h_pprint(stdout, res->ast, 0, 2);
   else
-- 
GitLab