MpjJT ddlmZmZmZmZmZmZmZmZm Z m Z ddl m Z ddl mZddlmZmZddlmZmZddlmZddlmZmZdd lmZmZed Zed Zed Zed Z edZ!edefZ"ee"e#fZ$GddZ%e%Z&GddZ'Gdde'e eeefZ(d;dZ)Gdde(Z*GddeeefZ+Gdde(eefZ,Gdde(eefZ-Gd d!e(eefZ.Gd"d#Z/Gd$d%e/e eeZ0Gd&d'e/eeZ1Gd(d)e'e eeefZ2eee2ege!fZ3d*e3d+e3fd,Z4d-Z5Gd.d/Z6d0Z7d1Z8d2Z9d3Z:dNO74dOdO O%c? QKD%s# (:t3<-d-D-5& 7 3d7m -7-b- 0-*r%rCNc *| t}|jD]s\}}t|D]`}t||}t |s|j ds|dk(r2|dz|z}t ||rtd|zt|||bu|S)abMerge a collection of transformers into the base_transformer, each into its own 'namespace'. When called, it will collect the methods from each transformer, and assign them to base_transformer, with their name prefixed with the given keyword, as ``prefix__methodname``. This function is especially useful for processing grammars that import other grammars, thereby creating some of their rules in a 'namespace'. (i.e with a consistent name prefix). In this case, the key for the transformer should match the name of the imported grammar. Parameters: base_transformer (Transformer, optional): The transformer that all other transformers will be added to. **transformers_to_merge: Keyword arguments, in the form of ``name_prefix = transformer``. Raises: AttributeError: In case of a name collision in the merged methods Example: :: class TBase(Transformer): def start(self, children): return children[0] + 'bar' class TImportedGrammar(Transformer): def foo(self, children): return "foo" composed_transformer = merge_transformers(TBase(), imported=TImportedGrammar()) t = Tree('start', [ Tree('imported__foo', []) ]) assert composed_transformer.transform(t) == 'foobar' r-rh__z0Cannot merge: method '%s' appears more than once) rCitemsdirrLr0r.hasattrrPr3)base_transformertransformers_to_mergeprefix transformer method_namemethodprefixed_methods r#merge_transformersrsF&=4::< ? {+ ?K[+6FF#%%c*k[.H$tmk9O'9$%WZi%ijj $ov > ? ? r%ceZdZddZy)InlineTransformerNc||n |j} t||j}||S#t$r*|j |j||j cYSwxYwr=)rKrLrMrPrQrN)r"rRrSrKrTs r#rWz InlineTransformer._call_userfuncsc#/#;< dii(Ah<  D##DIIxC C Ds-0A A r=)r&r'r(rWr!r%r#rrs r%rcJeZdZUded<d dZdeedefdZ d dZ y) rjz0Tuple[Union[Transformer, TransformerChain], ...] transformersrENc||_yr=)r)r"rs r#rHzTransformerChain.__init__s (r%rRcf|jD]}|j|}tt|Sr=)rrhr r)r"rRts r#rhzTransformerChain.transforms2"" %A;;t$D %It$$r%c.t|j|fzSr=)rjrrks r#rmzTransformerChain.__mul__ s !2!2eX!=>>r%)rz$Union[Transformer, TransformerChain]rEN)r"z(TransformerChain[_Leaf_T, Tree[_Leaf_U]]rlzLUnion[Transformer[_Leaf_U, _Return_V], TransformerChain[_Leaf_U, _Return_V]]rErq) r&r'r(__annotations__rHrrrrhrmr!r%r#rjrjsCDD)%d7m% % ?<?a? 0?r%rjc,eZdZdZdZdeedefdZy)Transformer_InPlacezSame as Transformer, but non-recursive, and changes the tree in-place instead of returning new instances Useful for huge trees. Conservative in memory. c$|j|Sr=)rWr"rRs r#r^z#Transformer_InPlace._transform_tree""4((r%rRrEc|jD]+}t|j|j|_-|j |Sr=) iter_subtreesrerbrKr^r"rRsubtrees r#rhzTransformer_InPlace.transformsM))+ PG#D$<$s r#r?zVisitorBase.__class_getitem__dr@r%N)r&r'r(rWrQr?r!r%r#rrYs@r%rcHeZdZdZdeedeefdZdeedeefdZy)VisitorzTree visitor, non-recursive (can handle huge trees). Visiting a node calls its methods (provided by the user via inheritance) according to ``tree.data`` rRrEcR|jD]}|j||SzJVisits the tree, starting with the leaves and finally the root (bottom-up))rrWrs r#visitz Visitor.visitns-))+ )G    ( ) r%cR|jD]}|j||SzIVisit the tree, starting at the root, and ending at the leaves (top-down))iter_subtrees_topdownrWrs r# visit_topdownzVisitor.visit_topdownts-113 )G    ( ) r%Nr&r'r(r)rrrrr!r%r#rrhs= $w-DM $w-DMr%rcHeZdZdZdeedeefdZdeedeefdZy)Visitor_RecursivezBottom-up visitor, recursive. Visiting a node calls its methods (provided by the user via inheritance) according to ``tree.data`` Slightly faster than the non-recursive version. rRrEc|jD]$}t|ts|j|&|j ||Sr)rKr1rrrWr"rRchilds r#rzVisitor_Recursive.visits@]] "E%& 5! " D! r%c|j||jD]$}t|ts|j |&|Sr)rWrKr1rrrs r#rzVisitor_Recursive.visit_topdownsB D!]] *E%&""5) * r%Nrr!r%r#rr{s=$w-DMg4=r%rcZeZdZdZdeedefdZdeefdZdeede fdZ dZ dZ y ) InterpreteraInterpreter walks the tree starting at the root. Visits the tree, starting with the root and finally the leaves (top-down) For each tree node, it calls its methods (provided by user via inheritance) according to ``tree.data``. Unlike ``Transformer`` and ``Visitor``, the Interpreter doesn't automatically visit its sub-branches. The user has to explicitly call ``visit``, ``visit_children``, or use the ``@visit_children_decor``. This allows the user to implement branching and loops. rRrEc$|j|Sr=) _visit_treers r#rzInterpreter.visits%%r%ct||j}t|dd}|2|j||j|j|jS||SrJ)rLrMr5rKrN)r"rRrTrUs r#rzInterpreter._visit_treesP D$)) $!_d3  ??1dii J JT7Nr%c|jDcgc]%}t|tr|j|n|'c}Scc}wr=)rKr1rrrs r#visit_childrenzInterpreter.visit_childrens?!]],,6eT+B  'M, ,,s*<c|jSr=)rQ)r"r8s r# __getattr__zInterpreter.__getattr__sr%c$|j|Sr=rrs r#rQzInterpreter.__default__rr%N) r&r'r(r)rrrrrrrrrQr!r%r#rrsO &$w-&I& W ,4=,T, )r%rfuncrEc.tfd}|S)zSee Interpreterc8|j|}||Sr=r)r4rRvaluesrs r#innerz#visit_children_decor..inners ##D)C  r%)r)rrs` r#visit_children_decorrs  4[!! Lr%cb |j}||S#t$rt||cYSwxYwr=)r;rPr2)objr5_applys r#r;r;s=%""m$$ 1S-001s ..cReZdZUdZeed<dedeeeeegeffdZ dZ d dZ d Z y) r2aQ A wrapper around a Callable. It delegates `__call__` to the Callable. If the Callable has a `__get__`, that is also delegate and the resulting function is wrapped. Otherwise, we use the original function mirroring the behaviour without a __get__. We also have the visit_wrapper attribute to be used by Transformers. base_funcrr5cpt|tr |j}||_||_t ||yr=)r1r2rr5r)r"rr5s r#rHz_VArgsWrapper.__init__s. dM *>>D*tT"r%c&|j|i|Sr=)r)r"rkwargss r#__call__z_VArgsWrapper.__call__st~~t.v..r%Nc t|jj}t||j|||jS#t $r|cYSwxYwr=)rYr__get__r2r5rP)r"instanceownergs r#rz_VArgsWrapper.__get__sV YT^^$,,A!4>>8U!CTEWEWX X K sA AAc t|jj}||j||y#t$rYywxYwr=)rYr __set_name__rP)r"rr8rTs r#rz_VArgsWrapper.__set_name__sA +T^^$11A dnneT *   s6 AAr=) r&r'r(r)rrstrrer rHrrrr!r%r#r2r2sG #X#h#tUX?Y[^?^6_#/Y+r%r2c ||Sr=r!)rT_datarK_metas r# _vargs_inliners h<r%c||g|Sr=r!rTrrKrNs r#_vargs_meta_inliners T H r%c|||Sr=r!rs r# _vargs_metars T8 r%c(|t|||Sr=ro)rTrMrKrNs r# _vargs_treers T$$ ' ((r%inlinerNrRrUc|r|s|r tdd|r|rtntn|rtn|rt| td|fd}|S)aA convenience decorator factory for modifying the behavior of user-supplied callback methods of ``Transformer`` classes. By default, transformer callback methods accept one argument - a list of the node's children. ``v_args`` can modify this behavior. When used on a ``Transformer`` class definition, it applies to all the callback methods inside it. ``v_args`` can be applied to a single method, or to an entire class. When applied to both, the options given to the method take precedence. Parameters: inline (bool, optional): Children are provided as ``*args`` instead of a list argument (not recommended for very long lists). meta (bool, optional): Provides two arguments: ``meta`` and ``children`` (instead of just the latter); ``meta`` isn't available for transformers supplied to Lark using the ``transformer`` parameter (aka internal transformers). tree (bool, optional): Provides the entire tree as the argument, instead of the children. wrapper (function, optional): Provide a function to decorate all methods. Example: :: @v_args(inline=True) class SolveArith(Transformer): def add(self, left, right): return left + right @v_args(meta=True) def mul(self, meta, children): logger.info(f'mul at line {meta.line}') left, right = children return left * right class ReverseNotation(Transformer_InPlace): @v_args(tree=True) def tree_node(self, tree): tree.children = tree.children[::-1] z@Visitor functions cannot combine 'tree' with 'meta' or 'inline'.Nz;Cannot use 'wrapper' along with 'tree', 'meta' or 'inline'.ct|Sr=)r;)rrs r#_visitor_args_decz!v_args.._visitor_args_dec9sS$''r%) ValueErrorrrrr)rrNrRrUrrs @r#v_argsrsfJ [\\ D %DD    Z[ [( r%c"eZdZdZdZdZdZy)CollapseAmbiguitiesa# Transforms a tree that contains any number of _ambig nodes into a list of trees, each one containing an unambiguous tree. The length of the resulting list is the product of the length of all _ambig nodes. Warning: This may quickly explode for highly ambiguous trees. ct|gSr=)sum)r"optionss r#_ambigzCollapseAmbiguities._ambigMs7Br%cTt|Dcgc]}t|||c}Scc}wr=)rr)r"rMchildren_listsrNrKs r#rQzCollapseAmbiguities.__default__Ps%;OP^;_`xT8T*```s%c|gSr=r!)r"rs r#rZz%CollapseAmbiguities.__default_token__Ss s r%N)r&r'r(r)rrQrZr!r%r#rrCs ar%rr=)FFFN)>typingrrrrrrr r r r abcr utilsrrRrr exceptionsrrlexerr functoolsrrinspectrrrrrrr_FUNCrY _DECORATEDrr_r+rCrrrjrrrrrrr _InterMethodrr;r2rrrrrrrrr!r%r#rs\\\'0,& K K )  )  T]i  5$;  '', .6q,WWi-?%@qh2j   ?ww 12?& *+gy&89 *,'{7I+=>,'^);w /A#B)  k3 0& WW%58"),WWi-?%@")Jk*I6:; | %#+#+L):4:t:4:RZ[cRd:px{EzFHRzRqS:D+r%