
                            S r SSKJrJrJrJrJrJr  SSKJ	r	J
r
  SSKJr  \\	\   \4   r\\	\   \4   r\\\	4   rSr " S S5      r " S S	\
\\	\   4   5      r " S
 S5      rS\S\S\4S jr " S S5      rS\S\\   4S jrg)zThis module defines utilities for matching and translation tree templates.

A tree templates is a tree that contains nodes that are template variables.

    )UnionOptionalMappingDictTupleIterator)TreeTransformer)MissingVariableError$c                       \ rS rSrSrSS jrS\\\   \4   S\	\   4S jr
S\S\\   4S	 jrS\\   SS
4S jrS\S\S\	\   4S jrSrg)TemplateConf   zrTemplate Configuration

Allows customization for different uses of Template

parse() must return a Tree instance.
Nc                     Xl         g N_parse)selfparses     &lib/third_party/lark/tree_templates.py__init__TemplateConf.__init__   s        varreturnc                 4   [        U[        5      (       a  [        U5      $ [        U[        5      (       ac  UR                  S:X  aS  [        UR                  5      S:  a:  [        UR                  S   [        5      (       a  [        UR                  S   5      $ g)zGiven a tree node, if it is a template variable return its name. Otherwise, return None.

This method may be overridden for customization

Parameters:
    var: Tree | str - The tree node to test

r   r   N)
isinstancestr_get_template_namer	   datalenchildren)r   r   s     r   test_varTemplateConf.test_var   ss     c3%c** sD!!E!CLL!A%3<<?C00%cll1o66r   templatec                     [        U[        5      (       a$  U R                  (       d   eU R                  U5      n[        U[        5      (       d  [	        S5      eU$ )Nz+template parser must return a Tree instance)r   r   r   r	   	TypeErrorr   r%   s     r   	_get_treeTemplateConf._get_tree3   sG    h$$;;;{{8,H(D))IJJr   Templatec                     [        XS9$ )N)conf)r+   r(   s     r   __call__TemplateConf.__call__=   s    ,,r   treec                 ^   U R                  U5      nU(       a'  [        U[        5      (       d  [        SU< 35      eX20$ [        U[        5      (       a  X:X  a  0 $ g[        U[        5      (       a  [        U[        5      (       d   SU SU 35       eUR
                  UR
                  :X  a  [        UR                  5      [        UR                  5      :X  aT  0 n[        UR                  UR                  5       H,  u  pVU R                  XV5      nUc    gUR                  U5        M.     U$ g)zAReturns dict of {var: match} if found a match, else None
        z6Template variables can only match Tree instances. Not Nz	template=z tree=)r#   r   r	   r'   r   r    r!   r"   zip_match_tree_templateupdate)r   r%   r0   template_varrest1t2matchess           r   r3   !TemplateConf._match_tree_template@   s    }}X.dD))"XY]X` abb ''h$$	(D))jt.D.Dh	RZQ[[abfagFhhD==DII%#h.?.?*@CDV*VCh//?33B;?

7# @ Jr   r   r   )__name__
__module____qualname____firstlineno____doc__r   r   r	   r   r   r#   
TreeOrCoder)   r.   BranchMatchResultr3   __static_attributes__ r   r   r   r      s~    E$s)S.1 hsm ,* c -c -z -Z v (S^J_ r   r   c                   b   ^  \ rS rSrS\S\\\\   4   SS4U 4S jjrS\\   4U 4S jjr	Sr
U =r$ )	_ReplaceVars^   r-   varsr   Nc                 :   > [         TU ]  5         Xl        X l        g r   )superr   _conf_vars)r   r-   rH   	__class__s      r   r   _ReplaceVars.__init___   s    

r   c                    > [         TU ]  XU5      nU R                  R                  U5      nU(       a   U R                  U   $ U$ ! [
         a    [        SU S35      ef = f)Nz"No mapping for template variable ())rJ   __default__rK   r#   rL   KeyErrorr   )r   r    r"   metar0   r   rM   s         r   rQ   _ReplaceVars.__default__d   sp    w"448jj!!$'Xzz#&   X*-OPSuTU+VWWXs   A A )rK   rL   )r;   r<   r=   r>   r   r   r   r	   r   rQ   rC   __classcell__)rM   s   @r   rF   rF   ^   s?    \ d3i1H T 
	49 	 	r   rF   c                       \ rS rSrSr\" 5       4S\\   S\4S jjrS\	S\
\   4S jrS\	S\\\\   \4      4S jrS	\\\\   4   S\\   4S
 jrSrg)r+   p   a
  Represents a tree template, tied to a specific configuration

A tree template is a tree that contains nodes that are template variables.
Those variables will match any tree.
(future versions may support annotations on the variables, to allow more complex templates)
r0   r-   c                 <    X l         UR                  U5      U l        g r   )r-   r)   r0   )r   r0   r-   s      r   r   Template.__init__x   s    	NN4(	r   r   c                     U R                   R                  U5      nU R                   R                  U R                  U5      $ )a  Match a tree template to a tree.

A tree template without variables will only match ``tree`` if it is equal to the template.

Parameters:
    tree (Tree): The tree to match to the template

Returns:
    Optional[Dict[str, Tree]]: If match is found, returns a dictionary mapping
        template variable names to their matching tree nodes.
        If no match was found, returns None.
)r-   r)   r3   r0   )r   r0   s     r   matchTemplate.match|   s3     yy""4(yy--dii>>r   c              #      #    U R                   R                  U5      nUR                  5        H"  nU R                  U5      nU(       d  M  X#4v   M$     g7f)zISearch for all occurrences of the tree template inside ``tree``.
        N)r-   r)   iter_subtreesr[   )r   r0   subtreer6   s       r   searchTemplate.search   sI      yy""4())+G**W%Csl" ,s   AA
ArH   c                 `    [        U R                  U5      R                  U R                  5      $ )z(Apply vars to the template tree
        )rF   r-   	transformr0   )r   rH   s     r   
apply_varsTemplate.apply_vars   s$     DIIt,66tyyAAr   )r-   r0   N)r;   r<   r=   r>   r?   r   r	   r   r   r@   r   rB   r[   r   r   r`   r   rd   rC   rD   r   r   r+   r+   p   s     >J^ )T#Y )l )?* ?+)> ? #: #(5cK9O3P*Q #BwsDI~6 B49 Br   r+   r7   r8   r0   c                     U R                   R                  U5      nU R                  U5       H<  u  p4UR                  U5      nUR	                  UR
                  UR                  5        M>     U$ )z=Search tree and translate each occurrence of t1 into t2.
    )r-   r)   r`   rd   setr    r"   )r7   r8   r0   r_   rH   r6   s         r   	translaterh      sW     77T"D4mmD!CHHcll+ ) Kr   c                   D    \ rS rSrSrS\\\4   4S jrS\\	   4S jr
Srg)	TemplateTranslator   z;Utility class for translating a collection of patterns
    translationsc                 ^    [        S UR                  5        5       5      (       d   eXl        g )Nc              3   t   #    U  H.  u  p[        U[        5      =(       a    [        U[        5      v   M0     g 7fr   )r   r+   ).0kvs      r   	<genexpr>.TemplateTranslator.__init__.<locals>.<genexpr>   s*     hSg41:a*Fz!X/FFSgs   68)allitemsrl   )r   rl   s     r   r   TemplateTranslator.__init__   s)    hS_SeSeSghhhhh(r   r0   c                 d    U R                   R                  5        H  u  p#[        X#U5      nM     U$ r   )rl   ru   rh   )r   r0   rp   rq   s       r   rh   TemplateTranslator.translate   s.    %%++-DAQ4(D .r   )rl   N)r;   r<   r=   r>   r?   r   r+   r   r	   r   rh   rC   rD   r   r   rj   rj      s-    )WXx-?%@ )d3i r   rj   valuer   c                 d    U R                  [        5      (       a  U R                  [        5      $ S $ r   )
startswith_TEMPLATE_MARKERlstrip)ry   s    r   r   r      s)    -2-=-=>N-O-O5<<()YUYYr   N)r?   typingr   r   r   r   r   r   larkr	   r
   lark.exceptionsr   r   rA   r@   rB   r|   r   rF   r+   rh   rj   r   rD   r   r   <module>r      s    C B " 0	tCy#~	49c>"
39o I IX;sDI~. $(B (BV(  
  Zc Zhsm Zr   