
    s                         S r SSKrSSKJr  SSKJrJr  SSKJr  SSK	J
r
  SSKJrJrJr  S	 r " S
 S5      rS rS rS rS rS rS r " S S5      r " S S5      rg)z"Tree matcher based on Lark grammar    N)defaultdict   )TreeToken)
ParserConf)earley)RuleTerminalNonTerminalc                 @    U R                   =(       a    U R                  $ N)is_term
filter_out)ts    $lib/third_party/lark/tree_matcher.pyis_discarded_terminalr      s    99%%    c                        \ rS rSrS rS rSrg)_MakeTreeMatch   c                     Xl         X l        g r   )name	expansion)selfr   r   s      r   __init___MakeTreeMatch.__init__   s    	"r   c                     [        U R                  U5      nSUR                  l        U R                  UR                  l        U$ )NT)r   r   meta
match_treer   orig_expansion)r   argsr   s      r   __call___MakeTreeMatch.__call__   s3    D!  $r   )r   r   N)__name__
__module____qualname____firstlineno__r   r"   __static_attributes__ r   r   r   r      s    #r   r   c                     0 nU  H3  nU" U5      nXS;   a  U" U5      nU" X5   5      nXv:  a  XCU'   M-  M/  XCU'   M5     [        UR                  5       5      $ r   )listvalues)seq	group_keycmp_keyditemkeyv1v2s           r   _best_from_groupr5      s`    
Ao8BBw#  cF  
r   c                 D    [        U S S 5      n U R                  S S9  U $ )Nc                     U $ r   r)   rs    r   <lambda>(_best_rules_from_group.<locals>.<lambda>+   s    ar   c                 .    [        U R                  5      * $ r   lenr   r8   s    r   r:   r;   +   s    C<L;Lr   c                 ,    [        U R                  5      $ r   r=   r8   s    r   r:   r;   ,   s    S-r   )r2   )r5   sort)ruless    r   _best_rules_from_grouprB   *   s%    UK1LME	JJ-J.Lr   c                     [        U[        5      (       a&  [        U R                  5      u  p#UR                  U:H  $ [        U[
        5      (       a  U [        UR                  5      :H  $  X45       er   )
isinstancer   parse_rulenamer   datar   r
   type)termtokenr   _argss       r   _matchrK   0   s[    %$TYY/zzT!!	E5	!	!x

+++4-5r   c                 >    [        X[        U R                  U5      S9$ )N)alias)r	   r   r   )originr   old_expansions      r   make_recons_rulerP   9   s    ])STTr   c                 F    [        U [        UR                  5      /U/5      $ r   )rP   r
   r   )rN   rH   s     r   make_recons_rule_to_termrR   =   s    FXdii%8$9D6BBr   c                     [         R                  " SU 5      R                  5       u  pU=(       a/    UR                  S5       Vs/ s H  o3R	                  5       PM     snnX4$ s  snf )zJParse rule names that may contain a template syntax (like rule{a, b, ...})z(\w+)(?:{(.+)})?,)rematchgroupssplitstrip)sr   args_strar!   s        r   rE   rE   A   sT    XX115<<>ND@HNN3,?@,?q,?@D: As   A#c                        \ rS rSrS rS rSrg)ChildrenLexerI   c                     Xl         g r   children)r   rb   s     r   r   ChildrenLexer.__init__J   s     r   c                     U R                   $ r   ra   )r   parser_states     r   lexChildrenLexer.lexM   s    }}r   ra   N)r$   r%   r&   r'   r   rf   r(   r)   r   r   r^   r^   I   s    !r   r^   c                   *    \ rS rSrSrS rS rS rSrg)TreeMatcherP   zMatch the elements of a tree node, based on an ontology
provided by a Lark grammar.

Supports templates and inlined rules (`rule{a, b,..}` and `_rule`)

Initialize with an instance of Lark.
c                    UR                   R                  (       a   eUR                  R                  UR                   R                  [        5       5      u  U l        p#[        [        5      U l	        [        U R                  U5      5      U l        U R                  R                  5         [        U R                  5      U l        Xl        0 U l        g r   )optionsmaybe_placeholdersgrammarcompilestartsettokensr   r+   rules_for_root_build_recons_rulesrA   reverserB   parser_parser_cache)r   rv   rA   _extras       r   r   TreeMatcher.__init__Y   s    >>4444%+^^%;%;FNN<P<PRURW%X"U)$/$2259:


 ,DJJ7
r   c              #     #    U Vs1 s H+  o"R                   R                  (       d  M  UR                  iM-     nn[        [        5      nU H=  nUR
                  (       d  M  XBR                     R                  UR
                  5        M?     U Vs1 s H  o"R                  iM     nnU Vs1 s H1  nUR                  R                  S5      (       d  Xc;   d  Xd;   d  M/  UiM3     nn[        5       nU GH  nUR                   Vs/ s H1  n[        U5      (       a  M  Xg;   a  UO[        UR                  5      PM3     n	nXR                  /:X  a  UR
                  c  Mk  UR
                  (       a  [        UR
                  5      OUR                  n[        XiUR                  5      n
Xc;   au  [        U	5      S:w  af  U R                   UR                     R                  U
5        UR                  U;  a+  [#        Xf5      v   UR%                  UR                  5        GM*  GM-  UR                  R                  S5      (       d  Xc;   a  U
v   GMY  U R                   UR                     R                  U
5        GM     UR'                  5        H2  u  pU H  n[#        U[        U5      5      v   M     [#        X5      v   M4     gs  snf s  snf s  snf s  snf 7f)z>Convert tree-parsing/construction rules to tree-matching rules_Nr   )rl   expand1rN   r   r+   rM   appendr   
startswithrq   r   r   r
   r   rP   r>   rs   rR   additems)r   rA   r9   expand1saliases
rule_namessymnonterminalsseen
recons_exprulerN   rule_aliasesrM   s                 r   rt   TreeMatcher._build_recons_rulesj   s5    &+Aeyy/@/@HAHHeAd#Awww!((1  )..1hh
.'1 Zz88..s33s#. z Z uA%&[[T%0c8Mc8R M!4#(388:LL%0  T hhZ'AGGO*+''+agg&qxxC#CQ[[AD3z?a#7##CHH-44T:884'23<<HHSXX& ( 88&&s++sJ''188>+ . %,MMO F%.v{57IJJ &*6:: %4G B /Z
TsK   KJ?J?%K"/KK&K,.K	K	$ KK K<FKc                 <   U(       a   [        U5      u  p4UR                  U:X  d   eOUR                  n U R                  U   nUR                  [        UR                   5      U5      n
U
R                  U:X  d   eU
$ ! [         a    U R                  [        U R                  U   5      -   nU Vs0 s H  owUR                  _M     Os  snf nn[        XhU/5      n	[        R                  " U R                  R                  U	[        SS9nXPR                  U'    Nf = f)az  Match the elements of `tree` to the symbols of rule `rulename`.

Parameters:
    tree (Tree): the tree node to match
    rulename (str): The expected full rule name (including template args)

Returns:
    Tree: an unreduced tree that matches `rulename`

Raises:
    UnexpectedToken: If no match was found.

Note:
    It's the callers' responsibility match the tree recursively.
T)resolve_ambiguity)rE   rF   rw   KeyErrorrA   rB   rs   rM   r   r   Parserrv   
lexer_confrK   parser^   rb   )r   treerulenamer   rJ   rv   rA   r   	callbacksconfunreduced_trees              r   r   TreeMatcher.match_tree   s     (2KD99$$$yyH		2''1F  mDMM&BHM""h...  	2JJ!78K8KH8U!VVE 7<<edtzz)e<I<e
;D]]4;;#9#94[_`F+1x(	2s   A= =3D0CADD)rw   rv   rA   rs   rr   N)	r$   r%   r&   r'   __doc__r   rt   r   r(   r)   r   r   ri   ri   P   s     "(;T&r   ri   )r   rU   collectionsr    r   r   commonr   parsersr   rn   r	   r
   r   r   r   r5   rB   rK   rP   rR   rE   r^   ri   r)   r   r   <module>r      sb    ( 	 #    0 0&	 	 UC j jr   