
    )               	       \   d dl Z d dlmZ d dlmZmZmZmZmZm	Z	m
Z
mZ er)ddlmZmZ 	 d dlZe j"                  dk\  rd dlmZ nd dlmZ d dlmZ  G d	 d
      Z e
d      Zeedf   Z G d de	e         Zed   Z G d de      ZddededdddfdZddefdZddefdZy# e$ r Y |w xY w)    N)deepcopy)ListCallableIteratorUnionOptionalGenericTypeVarTYPE_CHECKING   )TerminalDefToken)      )Literal)OrderedDictc                   n    e Zd ZU eed<   eed<   eed<   eed<   eed<   eed<   eed<   ded	<   eed
<   d Zy)Metaemptylinecolumn	start_posend_line
end_columnend_poszList[TerminalDef]orig_expansion
match_treec                     d| _         y )NT)r   selfs    lib/third_party/lark/tree.py__init__zMeta.__init__    s	    
    N)__name__
__module____qualname__bool__annotations__intr"    r#   r!   r   r      s6    K
IKNMOL''r#   r   _Leaf_TTree[_Leaf_T]c            	          e Zd ZU dZeed<   ded<   d"dedddee   ddfdZe	defd	       Z
d
 Zd Zd Zd#dedefdZd"ded   ddfdZd Zd Zd ZdefdZd$dZd Zd%dZdeddfdZd Zdddee   fdZd Zd&d Zdeddddfd!Zy)'Treea  The main tree class.

    Creates a new tree, and stores "data" and "children" in attributes of the same name.
    Trees can be hashed and compared.

    Parameters:
        data: The name of the rule or alias
        children: List of matched sub-rules and terminals
        meta: Line & Column numbers (if ``propagate_positions`` is enabled).
            meta attributes: line, column, start_pos, end_line, end_column, end_pos
    datazList[Branch[_Leaf_T]]childrenNmetareturnc                 .    || _         || _        || _        y N)r/   r0   _meta)r    r/   r0   r1   s       r!   r"   zTree.__init__8   s    	 
r#   c                 P    | j                   t               | _         | j                   S r4   )r5   r   r   s    r!   r1   z	Tree.meta=   s    ::DJzzr#   c                 <    d| j                   d| j                  dS )NzTree(z, )r/   r0   r   s    r!   __repr__zTree.__repr__C   s    !%DMM::r#   c                     | j                   S r4   r/   r   s    r!   _pretty_labelzTree._pretty_labelF   s    yyr#   c              #   |  K   ||z   | j                           t        | j                        dk(  r3t        | j                  d   t              sd| j                  d    d y d | j                  D ]?  }t        |t              r|j                  |dz   |      E d {    1||dz   z   | d A y 7 w)Nr   r   	
)r=   lenr0   
isinstancer.   _pretty)r    level
indent_strns       r!   rC   zTree._prettyI   s     E!"4#5#5#7"899t}}":dmmA6F+Mt}}Q'(++J]]a& yyq*==='q121#R88	 #=s   B B<"B:#B<rE   c                 D    dj                  | j                  d|            S )z]Returns an indented string representation of the tree.

        Great for debugging.
         r   )joinrC   )r    rE   s     r!   prettyzTree.prettyU   s    
 wwt||Az233r#   parentzrich.tree.Treec                 $    | j                  |      S )zReturns a tree widget for the 'rich' library.

        Example:
            ::
                from rich import print
                from lark import Tree

                tree = Tree('root', ['node1', 'node2'])
                print(tree)
        )_rich)r    rK   s     r!   __rich__zTree.__rich__\   s     zz&!!r#   c                 ,   |r |j                  d| j                   d      }n)dd l}|j                  j	                  | j                        }| j
                  D ]9  }t        |t              r|j                  |       %|j                  d| d       ; |S )Nz[bold]z[/bold]r   z[green]z[/green])addr/   	rich.treetreer.   r0   rB   rM   )r    rK   rR   richcs        r!   rM   z
Tree._richi   sx    ::tyyk9:D99>>$)),DA!T"71#X./	  r#   c                     	 | j                   |j                   k(  xr | j                  |j                  k(  S # t        $ r Y yw xY w)NF)r/   r0   AttributeErrorr    others     r!   __eq__zTree.__eq__x   s>    	99

*Nt}}/NN 		s   36 	AAc                     | |k(   S r4   r*   rW   s     r!   __ne__zTree.__ne__~   s    EM""r#   c                 V    t        | j                  t        | j                        f      S r4   )hashr/   tupler0   r   s    r!   __hash__zTree.__hash__   s    TYYdmm 4566r#   Iterator[Tree[_Leaf_T]]c           	         | g}t               }|D ]S  }||t        |      <   |t        |j                        D cg c]!  }t	        |t
              rt        |      |vr|# c}z  }U ~t        t        |j                                     S c c}w )zDepth-first iteration.

        Iterates over all the subtrees, never returning to the same node twice (Lark's parse-tree is actually a DAG).
        )r   idreversedr0   rB   r.   listvalues)r    queuesubtreessubtreerT   s        r!   iter_subtreeszTree.iter_subtrees   s    
 =G$+HR[!'*:*:!; H!;A#At,Ah1F !; H HE  X__./00	Hs   &B	c              #      K   | g}|j                   }|j                  }|rB |       }t        |t              s| t	        |j
                        D ]
  } ||        |rAyyw)ztBreadth-first iteration.

        Iterates over all the subtrees, return nodes in order like pretty() does.
        N)appendpoprB   r.   rc   r0   )r    stackstack_append	stack_popnodechilds         r!   iter_subtrees_topdownzTree.iter_subtrees_topdown   s]     
 ||II	;DdD)J!$--0U# 1 s   AA#!A#predc                 6    t        || j                               S )z?Returns all nodes of the tree that evaluate pred(node) as true.)filterri   )r    rs   s     r!   	find_predzTree.find_pred   s    dD..011r#   c                 ,    | j                  fd      S )z?Returns all nodes of the tree whose data equals the given data.c                 "    | j                   k(  S r4   r<   )tr/   s    r!   <lambda>z Tree.find_data.<locals>.<lambda>   s    $r#   )rv   )r    r/   s    `r!   	find_datazTree.find_data   s    ~~677r#   c                     d}t        t        | j                        dz
  dd      D ]O  }| j                  |   }t        |t              s#|j
                  |v s2|j                  | j                  ||dz    d}Q |S )z\Expand (inline) children with any of the given data values. Returns True if anything changedFr   T)rangerA   r0   rB   r.   r/   )r    data_valueschangedirq   s        r!   expand_kids_by_datazTree.expand_kids_by_data   so    s4==)!+R4AMM!$E%&5::+D',~~a!$	 5
 r#   z!Callable[[Branch[_Leaf_T]], bool]c              #      K   | j                   D ]:  }t        |t              r|j                  |      D ]  }|  . ||      s7| < yw)zReturn all values in the tree that evaluate pred(value) as true.

        This can be used to find all the tokens in the tree.

        Example:
            >>> all_tokens = tree.scan_values(lambda v: isinstance(v, Token))
        N)r0   rB   r.   scan_values)r    rs   rT   ry   s       r!   r   zTree.scan_values   sF      A!T"t,AG - 7G s   AAAc                 z     t        |       | j                  t        | j                  |      | j                        S )N)r1   )typer/   r   r0   r5   )r    memos     r!   __deepcopy__zTree.__deepcopy__   s*    tDz$))XdmmT%BTTr#   c                 N     t        |       | j                  | j                        S r4   )r   r/   r0   r   s    r!   copyz	Tree.copy   s    tDz$))T]]33r#   c                      || _         || _        y r4   r9   )r    r/   r0   s      r!   setzTree.set   s    	 r#   r4   )z  )r2   r`   )rs   zCallable[[Tree[_Leaf_T]], bool]r2   r`   )r2   r,   ) r$   r%   r&   __doc__strr(   r   r   r"   propertyr1   r:   r=   rC   rJ   rN   rM   rY   r[   r)   r_   ri   rr   rv   r{   r   r   r+   r   r   r   r   r*   r#   r!   r.   r.   (   s   
 I%%S ,C 8TX> cg 
 d  
;
94 4c 4"h'78 "BR "#7# 71 $ 28c 8&? 8 C QXHY  U4! !'> !4 !r#   r.   r   c                       e Zd ZdZy)SlottedTree)r/   r0   ruler5   N)r$   r%   r&   	__slots__r*   r#   r!   r   r      s    3Ir#   r   rR   filenamerankdirzLiteral["TB", "LR", "BT", "RL"]r2   c                 @    t        | |fi |}|j                  |       y r4   )pydot__tree_to_graph	write_pngrR   r   r   kwargsgraphs        r!   pydot__tree_to_pngr      s     w9&9E	OOHr#   c                 @    t        | |fi |}|j                  |       y r4   )r   writer   s        r!   pydot__tree_to_dotr      s     w9&9E	KKr#   c                 x    ddl  j                  dd|d|dgfdfd |        S )a  Creates a colorful image that represents the tree (data+children, without meta)

    Possible values for `rankdir` are "TB", "LR", "BT", "RL", corresponding to
    directed graphs drawn from top to bottom, from left to right, from bottom to
    top, and from right to left, respectively.

    `kwargs` can be any graph attribute (e. g. `dpi=200`). For a list of
    possible attributes, see https://www.graphviz.org/doc/info/attrs.html.
    r   Ndigraph)
graph_typer   c                     j                  d   t        |             }dxx   dz  cc<   j                  |       |S )Nr   )labelr   )Noderepradd_node)leafrp   r   r   pydots     r!   new_leafz&pydot__tree_to_graph.<locals>.new_leaf   s;    zz!A$d4jz1	!	tr#   c                    t        | j                        dz  }|dz  }| j                  D cg c]"  }t        |t              r |      n 	|      $ }}
j                  d   dd|z  | j                        }dxx   dz  cc<   j                  |       |D ]#  }j                  
j                  ||             % |S c c}w )Ni i r   filledz#%x)style	fillcolorr   r   )	r]   r/   r0   rB   r.   r   r   add_edgeEdge)rh   colorrq   subnodesrp   subnode	_to_pydotr   r   r   r   s         r!   r   z'pydot__tree_to_graph.<locals>._to_pydot   s    W\\"X- ")!1!13!1 )35$(?Ie$Xe_T!1 	 3zz!A$h%%-w||z\	!	tGNN5::dG45   3s   'Cr*   )r   Dot)rR   r   r   r   r   r   r   r   s      @@@@@r!   r   r      sF     EIIFGFvFE	
A  dOLr#   )LR) sysr   r   typingr   r   r   r   r   r	   r
   r   lexerr   r   rS   ImportErrorversion_infor   typing_extensionscollectionsr   r   r+   Branchr.   	ParseTreer   r   r   r   r   r*   r#   r!   <module>r      s    
  ] ] ]) 6!"- $   )
	w'	(i!77 i!X M	4$ 4T S ;\ pt 
T 
&t &w  s   B# #B+*B+