diff --git a/cfg_utils.py b/cfg_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..2a8becb68483392a0dc1d152f90581fdd1dab1a8 --- /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 b8096789e476ab3aa8b4db4dac8093e441f43891..8f03f8a23a707ba7b3552714d8fd4cab11dbd392 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 937c616cd1b9bd3e835ae027a853784515cd3219..1a540a2ae4d9ea432069ec85c30ded7d2727121a 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):