From 2447ede937f4b3044db3ddc2d6f36ec5bee1bb45 Mon Sep 17 00:00:00 2001
From: Kia <kia@special-circumstanc.es>
Date: Tue, 21 Jul 2020 22:38:44 -0600
Subject: [PATCH] starting implementation of CFG-handling/generation/sampling
 machinery

---
 cfg_utils.py       | 59 ++++++++++++++++++++++++++++++++++++++++++++++
 gearbox.py         | 37 -----------------------------
 python_arborist.py |  5 ++++
 3 files changed, 64 insertions(+), 37 deletions(-)
 create mode 100644 cfg_utils.py

diff --git a/cfg_utils.py b/cfg_utils.py
new file mode 100644
index 0000000..2a8becb
--- /dev/null
+++ b/cfg_utils.py
@@ -0,0 +1,59 @@
+
+
+class TreeNode:
+    def __init__(self, language_element, subnodes):
+        self.language_element = language_element
+        self.subnodes = subnodes
+
+    def __str__(self):
+        return str(self.language_element) + str(self.subnodes)
+
+
+
+
+# We define a context-free grammar as:
+# 1. A list of nonterminal symbols
+# 2. A list of terminal symbols
+# 3. A list of production rules
+# 4. A start symbol.
+
+
+
+
+
+
+# Once we have a CFG's definition, we can use Boltzmann sampling in order to generate random strings
+# from that CFG.
+
+
+
+# Furthermore, we also note that the description of a context-free grammar is *itself* context-free
+# so if we take the CFG-description grammar (BNF or something isomorphic to it), and use Boltzmann
+# sampling on *it*, we will generate candidate grammars; which will be used to test the FPGA-based
+# parser generator against a reference LR parser generator implementation. Naturally, this procedure 
+# may not produce LR-parseable grammars or even deterministic context-free grammars; but if the grammar
+# is rejected by both the FPGA parser generator and reference parser generator; this is fine, we just
+# move on to the next one.
+
+
+# Once we randomly generate a CFG, we randomly generate strings that are valid strings, but also
+# generate exemplars that are potentially *invalid* strings (both by mutating valid strings but
+# also by generating random sequences ab initio from the terminal symbols). The potentially invalid
+# strings are tested against the reference parser, those that are accidentally valid are discarded,
+# and those that are invalid are used in the automatic equivalence testing.
+
+
+# We fail our candidate parser generator if:
+#
+# 1. During the generation phase, it rejects a grammar the reference generator doesn't reject, or
+#    accepts a grammar the reference generator rejects.
+
+# 2. During the execution phase, it rejects a string the reference generated parser doesn't reject,
+#    or accepts a string the reference generated parser rejects.
+
+# 3. During the execution phase, it accepts a string that the reference generated parser accepts; but
+#    the parse tree it generates is not identical to the parse tree that the reference generated parser
+#    produced.
+
+
+
diff --git a/gearbox.py b/gearbox.py
index b809678..8f03f8a 100644
--- a/gearbox.py
+++ b/gearbox.py
@@ -19,43 +19,6 @@ class ArbitraryGearbox(Elaboratable): # non-registered
             write_ptr = Signal(range(len_storage))
             read_ptr = Signal(range(len_storage))
 
-            # we signal ready to upstream if and only if the skid buffer is empty
-            m.d.comb += self.upstream_ready_out.eq(~skid_buffer_frozen)
-
-
-            # should we capture a value in the skid buffer?
-            # we should if upstream has data for us *and* downstream cannot accept
-
-            # If we want to fill our skid buffer, we need:
-            # 1. valid input data       (upstream_valid_in   == 1)
-            # 2. a buffer that is empty (skid_buffer_frozen  == 0)
-            # 3. stalled downstream     (downstream_ready_in == 0)
-
-            with m.If(self.upstream_valid_in & (~skid_buffer_frozen)  & (~self.downstream_ready_in)):
-                m.d.sync += skid_buffer_frozen.eq(1)
-
-            # if downstream is accepting data again, we will flush our skid buffer
-            with m.If(self.downstream_ready_in == 1):
-                m.d.sync += skid_buffer_frozen.eq(0)
-
-
-            m.d.comb += self.downstream_valid_out.eq(self.upstream_valid_in | skid_buffer_frozen)
-
-
-            # data path
-
-            # always clock data into the skid buffer as long as the buffer isn't frozen
-
-            with m.If(skid_buffer_frozen == 0):
-                m.d.sync += skid_buffer.eq(self.upstream_data_in)
-
-            with m.If(skid_buffer_frozen == 1):
-                m.d.comb += self.downstream_data_out.eq(skid_buffer)
-
-            # NON registered
-            with m.Elif(self.upstream_valid_in == 1):
-                m.d.comb += self.downstream_data_out.eq(self.upstream_data_in)
-
             return m
 
 
diff --git a/python_arborist.py b/python_arborist.py
index 937c616..1a540a2 100644
--- a/python_arborist.py
+++ b/python_arborist.py
@@ -379,6 +379,11 @@ def deserializer(serialized_array):
 
 
 
+def string_generator(grammar):
+
+
+
+def treechecker(derivation, parse_tree):
 
 
 
-- 
GitLab