| @@ -129,3 +129,19 @@ This prints out: | |||||
| y d | y d | ||||
| While convenient, this should be used carefully, as highly ambiguous trees will soon create an exponential explosion of such unambiguous derivations. | While convenient, this should be used carefully, as highly ambiguous trees will soon create an exponential explosion of such unambiguous derivations. | ||||
| ## Keeping track of parents when visiting | |||||
| The following visitor assigns a `parent` attribute for every node in the tree. | |||||
| If your tree nodes aren't unique (if there is a shared Tree instance), the assert will fail. | |||||
| ```python | |||||
| class Parent(Visitor): | |||||
| def visit(self, tree): | |||||
| for subtree in tree.children: | |||||
| if isinstance(subtree, Tree): | |||||
| assert not hasattr(subtree, 'parent') | |||||
| subtree.parent = tree | |||||
| ``` | |||||
| @@ -97,6 +97,12 @@ class UnexpectedToken(ParseError, UnexpectedInput): | |||||
| super(UnexpectedToken, self).__init__(message) | super(UnexpectedToken, self).__init__(message) | ||||
| class VisitError(LarkError): | class VisitError(LarkError): | ||||
| """VisitError is raised when visitors are interrupted by an exception | |||||
| It provides the following attributes for inspection: | |||||
| - obj: the tree node or token it was processing when the exception was raised | |||||
| - orig_exc: the exception that cause it to fail | |||||
| """ | |||||
| def __init__(self, rule, obj, orig_exc): | def __init__(self, rule, obj, orig_exc): | ||||
| self.obj = obj | self.obj = obj | ||||
| self.orig_exc = orig_exc | self.orig_exc = orig_exc | ||||