diff --git a/cfg_utils.py b/cfg_utils.py index a04bc79ca1f43d93e6052abd5e6b62e1797cede1..ad2d14c018a07901955c9f13e510a96de2ce3b0a 100644 --- a/cfg_utils.py +++ b/cfg_utils.py @@ -17,7 +17,7 @@ def walk_the_tree(tree, level = 1): if tree == None: return - print(" " * (level -1) + "|---" + hex(tree.language_element) + " with " + str(len(tree.subnodes)) + " subnodes") + print(" " * (level -1) + "|---" + str(tree.language_element) + " with " + str(len(tree.subnodes)) + " subnodes") for subnode in tree.subnodes: walk_the_tree(subnode, level + 1) @@ -56,6 +56,8 @@ CFG = collections.namedtuple("CFG", "nonterminals terminals rules start") symbols = Enum("Symbols", "EXPRESSION TERM FACTOR INTEGER ADDOP MULTOP OPENPAREN CLOSEPAREN") start = symbols.EXPRESSION + + # The rules are a list of tuples, each of which represents a rule, as follows: # (Nonterminal symbol, [ordered list of symbols (terminal or nonterminal) that are reduced to aforementioned nonterminal]) @@ -69,7 +71,7 @@ rules = [ (symbols.FACTOR, [symbols.INTEGER ]) ] -#print(rules) +print(rules) @@ -88,7 +90,7 @@ rules = [ -def apply_rule(tree, location, rule_number, ruleset): +def apply_rule(tree, location, ruleset, rule_number): # first, we isolate the place on the tree that we are going to do the graft. opsite = tree @@ -99,12 +101,30 @@ def apply_rule(tree, location, rule_number, ruleset): print(opsite) walk_the_tree(opsite) + # now we verify that we can legitimately apply the given rule here. + + the_rule = ruleset[rule_number] + + print("We will try applying the following rule:", the_rule) + + # We verify that the item at the operation site is: + # 1) a leaf (it has no subnodes) + # and + # 2) has the correct value + + print("Opsite language value", opsite.language_element) + print("Rule expects", the_rule[0]) + + assert(opsite.language_element == the_rule[0]) + + + -test_tree = TreeNode(0, [ - TreeNode(1,[]), - TreeNode(2,[ - TreeNode(3,[]), TreeNode(4,[]),TreeNode(5,[]) +test_tree = TreeNode(symbols.EXPRESSION, [ + TreeNode(symbols.ADDOP,[]), + TreeNode(symbols.MULTOP,[ + TreeNode(symbols.EXPRESSION,[]), TreeNode(symbols.TERM,[]),TreeNode(symbols.FACTOR,[]) ]) ]) @@ -114,7 +134,7 @@ walk_the_tree(test_tree) #def next_stage(derivation_tree_with_cached, language_definition): -apply_rule(test_tree,[1,1],None,None) +apply_rule(test_tree,[1,2],rules,5) # 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