@@ -160,7 +160,7 @@ class AmbiguousExpander: | |||||
"""Deal with the case where we're expanding children ('_rule') into a parent but the children | """Deal with the case where we're expanding children ('_rule') into a parent but the children | ||||
are ambiguous. i.e. (parent->_ambig->_expand_this_rule). In this case, make the parent itself | are ambiguous. i.e. (parent->_ambig->_expand_this_rule). In this case, make the parent itself | ||||
ambiguous with as many copies as their are ambiguous children, and then copy the ambiguous children | ambiguous with as many copies as their are ambiguous children, and then copy the ambiguous children | ||||
into the right parents in the right places, essentially shifting the ambiguiuty up the tree.""" | |||||
into the right parents in the right places, essentially shifting the ambiguity up the tree.""" | |||||
def __init__(self, to_expand, tree_class, node_builder): | def __init__(self, to_expand, tree_class, node_builder): | ||||
self.node_builder = node_builder | self.node_builder = node_builder | ||||
self.tree_class = tree_class | self.tree_class = tree_class | ||||
@@ -297,6 +297,10 @@ class Parser: | |||||
# symbol should have been completed in the last step of the Earley cycle, and will be in | # symbol should have been completed in the last step of the Earley cycle, and will be in | ||||
# this column. Find the item for the start_symbol, which is the root of the SPPF tree. | # this column. Find the item for the start_symbol, which is the root of the SPPF tree. | ||||
solutions = [n.node for n in columns[-1] if n.is_complete and n.node is not None and n.s == start_symbol and n.start == 0] | solutions = [n.node for n in columns[-1] if n.is_complete and n.node is not None and n.s == start_symbol and n.start == 0] | ||||
if not solutions: | |||||
expected_tokens = [t.expect for t in to_scan] | |||||
raise UnexpectedEOF(expected_tokens) | |||||
if self.debug: | if self.debug: | ||||
from .earley_forest import ForestToPyDotVisitor | from .earley_forest import ForestToPyDotVisitor | ||||
try: | try: | ||||
@@ -307,10 +311,7 @@ class Parser: | |||||
debug_walker.visit(solutions[0], "sppf.png") | debug_walker.visit(solutions[0], "sppf.png") | ||||
if not solutions: | |||||
expected_tokens = [t.expect for t in to_scan] | |||||
raise UnexpectedEOF(expected_tokens) | |||||
elif len(solutions) > 1: | |||||
if len(solutions) > 1: | |||||
assert False, 'Earley should not generate multiple start symbol items!' | assert False, 'Earley should not generate multiple start symbol items!' | ||||
if self.tree_class is not None: | if self.tree_class is not None: | ||||
@@ -679,7 +679,10 @@ class ForestToPyDotVisitor(ForestVisitor): | |||||
def visit(self, root, filename): | def visit(self, root, filename): | ||||
super(ForestToPyDotVisitor, self).visit(root) | super(ForestToPyDotVisitor, self).visit(root) | ||||
self.graph.write_png(filename) | |||||
try: | |||||
self.graph.write_png(filename) | |||||
except FileNotFoundError as e: | |||||
logger.error("Could not write png: ", e) | |||||
def visit_token_node(self, node): | def visit_token_node(self, node): | ||||
graph_node_id = str(id(node)) | graph_node_id = str(id(node)) | ||||