1Transformers & Visitors 2======================= 3 4Transformers & Visitors provide a convenient interface to process the 5parse-trees that Lark returns. 6 7They are used by inheriting from the correct class (visitor or transformer), 8and implementing methods corresponding to the rule you wish to process. Each 9method accepts the children as an argument. That can be modified using the 10``v_args`` decorator, which allows one to inline the arguments (akin to ``*args``), 11or add the tree ``meta`` property as an argument. 12 13See: `visitors.py`_ 14 15.. _visitors.py: https://github.com/lark-parser/lark/blob/master/lark/visitors.py 16 17Visitor 18------- 19 20Visitors visit each node of the tree, and run the appropriate method on it according to the node's data. 21 22They work bottom-up, starting with the leaves and ending at the root of the tree. 23 24There are two classes that implement the visitor interface: 25 26- ``Visitor``: Visit every node (without recursion) 27- ``Visitor_Recursive``: Visit every node using recursion. Slightly faster. 28 29Example: 30 :: 31 32 class IncreaseAllNumbers(Visitor): 33 def number(self, tree): 34 assert tree.data == "number" 35 tree.children[0] += 1 36 37 IncreaseAllNumbers().visit(parse_tree) 38 39.. autoclass:: lark.visitors.Visitor 40 :members: visit, visit_topdown, __default__ 41 42.. autoclass:: lark.visitors.Visitor_Recursive 43 :members: visit, visit_topdown, __default__ 44 45Interpreter 46----------- 47 48.. autoclass:: lark.visitors.Interpreter 49 50 51Example: 52 :: 53 54 class IncreaseSomeOfTheNumbers(Interpreter): 55 def number(self, tree): 56 tree.children[0] += 1 57 58 def skip(self, tree): 59 # skip this subtree. don't change any number node inside it. 60 pass 61 62 IncreaseSomeOfTheNumbers().visit(parse_tree) 63 64Transformer 65----------- 66 67.. autoclass:: lark.visitors.Transformer 68 :members: transform, __default__, __default_token__, __mul__ 69 70Example: 71 :: 72 73 from lark import Tree, Transformer 74 75 class EvalExpressions(Transformer): 76 def expr(self, args): 77 return eval(args[0]) 78 79 t = Tree('a', [Tree('expr', ['1+2'])]) 80 print(EvalExpressions().transform( t )) 81 82 # Prints: Tree(a, [3]) 83 84Example: 85 :: 86 87 class T(Transformer): 88 INT = int 89 NUMBER = float 90 def NAME(self, name): 91 return lookup_dict.get(name, name) 92 93 T(visit_tokens=True).transform(tree) 94 95.. autoclass:: lark.visitors.Transformer_NonRecursive 96 97.. autoclass:: lark.visitors.Transformer_InPlace 98 99.. autoclass:: lark.visitors.Transformer_InPlaceRecursive 100 101v_args 102------ 103 104.. autofunction:: lark.visitors.v_args 105 106merge_transformers 107------------------ 108 109.. autofunction:: lark.visitors.merge_transformers 110 111Discard 112------- 113 114.. autoclass:: lark.visitors.Discard 115 116VisitError 117---------- 118 119.. autoclass:: lark.exceptions.VisitError