U
    M8ÚcJ  ã                   @   sp   d Z ddlZddlmZ ddlmZ ddlmZ ddlmZ ddlmZ G dd	„ d	e	ƒZ
eG d
d„ de	ƒƒZdS )a‹  Top down operator precedence parser.

This is an implementation of Vaughan R. Pratt's
"Top Down Operator Precedence" parser.
(http://dl.acm.org/citation.cfm?doid=512927.512931).

These are some additional resources that help explain the
general idea behind a Pratt parser:

* http://effbot.org/zone/simple-top-down-parsing.htm
* http://javascript.crockford.com/tdop/tdop.html

A few notes on the implementation.

* All the nud/led tokens are on the Parser class itself, and are dispatched
  using getattr().  This keeps all the parsing logic contained to a single
  class.
* We use two passes through the data.  One to create a list of token,
  then one pass through the tokens to create the AST.  While the lexer actually
  yields tokens, we convert it to a list so we can easily implement two tokens
  of lookahead.  A previous implementation used a fixed circular buffer, but it
  was significantly slower.  Also, the average jmespath expression typically
  does not have a large amount of token so this is not an issue.  And
  interestingly enough, creating a token list first is actually faster than
  consuming from the token iterator one token at a time.

é    N)Úlexer)Úwith_repr_method)Úast)Ú
exceptions)Úvisitorc                   @   sú  e Zd Zddddddddddddddddddddddddd	d
ddddœZdZi ZdZdxdd„Zdd„ Zdd„ Z	dd„ Z
dydd„Zdd„ Zdd„ Zdd „ Zd!d"„ Zd#d$„ Zd%d&„ Zd'd(„ Zd)d*„ Zd+d,„ Zd-d.„ Zd/d0„ Zd1d2„ Zd3d4„ Zd5d6„ Zd7d8„ Zd9d:„ Zd;d<„ Zd=d>„ Zd?d@„ ZdAdB„ ZdCdD„ Z dEdF„ Z!dGdH„ Z"dIdJ„ Z#dKdL„ Z$dMdN„ Z%dOdP„ Z&dQdR„ Z'dSdT„ Z(dUdV„ Z)dWdX„ Z*dYdZ„ Z+d[d\„ Z,d]d^„ Z-d_d`„ Z.dadb„ Z/dzddde„Z0dfdg„ Z1dhdi„ Z2djdk„ Z3dldm„ Z4dndo„ Z5dpdq„ Z6drds„ Z7dtdu„ Z8e9dvdw„ ƒZ:dcS ){ÚParserr   é   é   é   é   é	   é   é   é(   é-   é2   é7   é<   )ÚeofÚunquoted_identifierÚquoted_identifierÚliteralÚrbracketÚrparenÚcommaÚrbraceÚnumberÚcurrentÚexprefÚcolonÚpipeÚorÚandÚeqÚgtÚltÚgteÚlteÚneÚflattenÚstarÚfilterÚdotÚnotÚlbraceÚlbracketÚlparené
   é€   c                 C   s"   d | _ d g| | _|| _d| _d S ©Nr   )Ú	tokenizerÚ_tokensZ_buffer_sizeÚ_index)ÚselfÚ	lookahead© r9   ú3/tmp/pip-unpacked-wheel-dwe9sm7_/jmespath/parser.pyÚ__init__N   s    zParser.__init__c                 C   sH   | j  |¡}|d k	r|S |  |¡}|| j |< t| j ƒ| jkrD|  ¡  |S ©N)Ú_CACHEÚgetÚ	_do_parseÚlenÚ	_MAX_SIZEÚ_free_cache_entries)r7   Ú
expressionÚcachedÚparsed_resultr9   r9   r:   ÚparseT   s    

zParser.parsec              
   C   s–   z|   |¡W S  tjk
r8 } z||_‚ W 5 d }~X Y nZ tjk
rf } z| |¡ ‚ W 5 d }~X Y n, tjk
r } z||_‚ W 5 d }~X Y nX d S r<   )Ú_parser   Z
LexerErrorrC   ÚIncompleteExpressionErrorZset_expressionÚ
ParseError)r7   rC   Úer9   r9   r:   r?   ^   s    
zParser._do_parsec                 C   sr   t  ¡  |¡| _t| jƒ| _d| _| jdd}|  ¡ dksh|  	d¡}t
 |d |d |d d|d  ¡‚t||ƒS )Nr   )Úbinding_powerr   ÚstartÚvalueÚtypezUnexpected token: %s)r   ZLexerÚtokenizer4   Úlistr5   r6   Ú_expressionÚ_current_tokenÚ_lookahead_tokenr   rI   ÚParsedResult)r7   rC   ÚparsedÚtr9   r9   r:   rG   k   s    

ÿzParser._parsec                 C   s’   |   d¡}|  ¡  t| d|d  | jƒ}||ƒ}|  ¡ }|| j| k rŽt| d| d ƒ}|d krt|   d¡}|  |¡ q8|  ¡  ||ƒ}|  ¡ }q8|S )Nr   z_token_nud_%srN   z_token_led_%s)rS   Ú_advanceÚgetattrÚ_error_nud_tokenrR   ÚBINDING_POWERÚ_error_led_token)r7   rK   Z
left_tokenZnud_functionÚleftÚcurrent_tokenZledZerror_tokenr9   r9   r:   rQ   v   s$    
 
þ

zParser._expressionc                 C   s   t  |d ¡S ©NrM   )r   r   ©r7   Útokenr9   r9   r:   Ú_token_nud_literal‰   s    zParser._token_nud_literalc                 C   s   t  |d ¡S r^   )r   Úfieldr_   r9   r9   r:   Ú_token_nud_unquoted_identifierŒ   s    z%Parser._token_nud_unquoted_identifierc                 C   s@   t  |d ¡}|  ¡ dkr<|  d¡}t d|d |d d¡‚|S )NrM   r0   r   rN   z1Quoted identifier not allowed for function names.)r   rb   rR   rS   r   rI   )r7   r`   rb   rV   r9   r9   r:   Ú_token_nud_quoted_identifier   s    
  þz#Parser._token_nud_quoted_identifierc                 C   s:   t  ¡ }|  ¡ dkrt  ¡ }n|  | jd ¡}t  ||¡S )Nr   r*   )r   ÚidentityrR   Ú_parse_projection_rhsrZ   Úvalue_projection©r7   r`   r\   Úrightr9   r9   r:   Ú_token_nud_starš   s
    
zParser._token_nud_starc                 C   s   |   t ¡ ¡S r<   )Ú_token_led_filterr   re   r_   r9   r9   r:   Ú_token_nud_filter¢   s    zParser._token_nud_filterc                 C   s   |   ¡ S r<   )Ú_parse_multi_select_hashr_   r9   r9   r:   Ú_token_nud_lbrace¥   s    zParser._token_nud_lbracec                 C   s   |   ¡ }|  d¡ |S )Nr   )rQ   Ú_match©r7   r`   rC   r9   r9   r:   Ú_token_nud_lparen¨   s    
zParser._token_nud_lparenc                 C   s*   t  t  ¡ ¡}|  | jd ¡}t  ||¡S ©Nr)   )r   r)   re   rf   rZ   Ú
projectionrh   r9   r9   r:   Ú_token_nud_flatten­   s
    ÿzParser._token_nud_flattenc                 C   s   |   | jd ¡}t |¡S )Nr-   )rQ   rZ   r   Znot_expression)r7   r`   Úexprr9   r9   r:   Ú_token_nud_not³   s    zParser._token_nud_notc                 C   sz   |   ¡ dkr$|  ¡ }|  t ¡ |¡S |   ¡ dkrn|  d¡dkrn|  ¡  |  ¡  |  | jd ¡}t 	t ¡ |¡S |  
¡ S d S )N©r   r   r*   r   r   )rR   Ú_parse_index_expressionÚ_project_if_slicer   re   Ú
_lookaheadrW   rf   rZ   rs   Ú_parse_multi_select_list)r7   r`   ri   r9   r9   r:   Ú_token_nud_lbracket·   s    ÿzParser._token_nud_lbracketc                 C   sR   |   d¡dks|   d¡dkr$|  ¡ S t |  d¡d ¡}|  ¡  |  d¡ |S d S )Nr   r   r   rM   r   )rz   Ú_parse_slice_expressionr   ÚindexrS   rW   ro   )r7   Únoder9   r9   r:   rx   È   s    ÿ
zParser._parse_index_expressionc                 C   s®   d d d g}d}|   ¡ }|dksš|dk rš|dkrZ|d7 }|dkrP|  |  d¡d¡ |  ¡  n6|dkr~|  d¡d ||< |  ¡  n|  |  d¡d¡ |   ¡ }q|  d¡ tj|Ž S )	Nr   r   r
   r   r   úsyntax errorr   rM   )rR   Ú_raise_parse_error_for_tokenrS   rW   ro   r   Úslice)r7   Úpartsr~   r]   r9   r9   r:   r}   ×   s,    
 ÿ

 ÿ

zParser._parse_slice_expressionc                 C   s   t  ¡ S r<   )r   Zcurrent_noder_   r9   r9   r:   Ú_token_nud_currentï   s    zParser._token_nud_currentc                 C   s   |   | jd ¡}t |¡S )Nr   )rQ   rZ   r   r   rp   r9   r9   r:   Ú_token_nud_exprefò   s    zParser._token_nud_exprefc                 C   sr   |   ¡ dksJ|  | jd ¡}|d dkr:|d  |¡ |S t ||g¡S n$|  ¡  |  | jd ¡}t ||¡S d S )Nr*   r,   rN   ÚsubexpressionÚchildren)	rR   Ú_parse_dot_rhsrZ   Úappendr   r†   rW   rf   rg   ©r7   r\   ri   r9   r9   r:   Ú_token_led_dotö   s    ÿzParser._token_led_dotc                 C   s   |   | jd ¡}t ||¡S )Nr    )rQ   rZ   r   r    rŠ   r9   r9   r:   Ú_token_led_pipe  s    zParser._token_led_pipec                 C   s   |   | jd ¡}t ||¡S )Nr!   )rQ   rZ   r   Zor_expressionrŠ   r9   r9   r:   Ú_token_led_or	  s    zParser._token_led_orc                 C   s   |   | jd ¡}t ||¡S )Nr"   )rQ   rZ   r   Zand_expressionrŠ   r9   r9   r:   Ú_token_led_and  s    zParser._token_led_andc                 C   s–   |d dkr:|   d¡}t |d |d |d d|d  ¡‚|d }g }|  ¡ dks||  ¡ }|  ¡ dkrp|  d¡ | |¡ qF|  d¡ t ||¡}|S )	NrN   rb   éþÿÿÿrL   rM   zInvalid function name '%s'r   r   )	rS   r   rI   rR   rQ   ro   r‰   r   Zfunction_expression)r7   r\   Zprev_tÚnameÚargsrC   Zfunction_noder9   r9   r:   Ú_token_led_lparen  s$    
  
þ

zParser._token_led_lparenc                 C   sH   |   d¡}|  d¡ |  ¡ dkr*t ¡ }n|  | jd ¡}t |||¡S )Nr   r   r)   r+   )rQ   ro   rR   r   re   rf   rZ   Zfilter_projection)r7   r\   Ú	conditionri   r9   r9   r:   rk   %  s    


zParser._token_led_filterc                 C   s   |   |d¡S )Nr#   ©Ú_parse_comparator©r7   r\   r9   r9   r:   Ú_token_led_eq/  s    zParser._token_led_eqc                 C   s   |   |d¡S )Nr(   r”   r–   r9   r9   r:   Ú_token_led_ne2  s    zParser._token_led_nec                 C   s   |   |d¡S )Nr$   r”   r–   r9   r9   r:   Ú_token_led_gt5  s    zParser._token_led_gtc                 C   s   |   |d¡S )Nr&   r”   r–   r9   r9   r:   Ú_token_led_gte8  s    zParser._token_led_gtec                 C   s   |   |d¡S )Nr%   r”   r–   r9   r9   r:   Ú_token_led_lt;  s    zParser._token_led_ltc                 C   s   |   |d¡S )Nr'   r”   r–   r9   r9   r:   Ú_token_led_lte>  s    zParser._token_led_ltec                 C   s&   t  |¡}|  | jd ¡}t  ||¡S rr   )r   r)   rf   rZ   rs   rŠ   r9   r9   r:   Ú_token_led_flattenA  s
    
ÿzParser._token_led_flattenc                 C   s~   |   d¡}|d dkrJ|  ¡ }|d dkr<|d  |¡ |S |  ||¡S n0|  d¡ |  d¡ |  | jd ¡}t ||¡S d S )Nr   rN   rw   Úindex_expressionr‡   r*   r   )	rS   rx   r‰   ry   ro   rf   rZ   r   rs   )r7   r\   r`   ri   r9   r9   r:   Ú_token_led_lbracketG  s    


zParser._token_led_lbracketc                 C   s:   t  ||g¡}|d dkr2t  ||  | jd ¡¡S |S d S )NrN   r‚   r*   )r   rž   rs   rf   rZ   )r7   r\   ri   Z
index_exprr9   r9   r:   ry   Z  s    þzParser._project_if_slicec                 C   s   |   | j| ¡}t |||¡S r<   )rQ   rZ   r   Ú
comparator)r7   r\   r    ri   r9   r9   r:   r•   c  s    zParser._parse_comparatorc                 C   sF   g }|   ¡ }| |¡ |  ¡ dkr&q2q|  d¡ q|  d¡ t |¡S )Nr   r   )rQ   r‰   rR   ro   r   Zmulti_select_list)r7   ZexpressionsrC   r9   r9   r:   r{   g  s    

zParser._parse_multi_select_listc                 C   s   g }|   d¡}| jddgd |d }|  d¡ |  d¡}tj||d}| |¡ |  ¡ dkrj|  d¡ q|  ¡ d	kr|  d	¡ q„qtj|d
S )Nr   r   r   )Útoken_typesrM   r   )Úkey_namer   r   r   )Znodes)	rS   Ú_match_multiple_tokensro   rQ   r   Zkey_val_pairr‰   rR   Zmulti_select_dict)r7   ÚpairsZ	key_tokenr¢   rM   r   r9   r9   r:   rm   s  s     
ÿ



zParser._parse_multi_select_hashc                 C   s†   | j |  ¡  | jk rt ¡ }nd|  ¡ dkr6|  |¡}nL|  ¡ dkrN|  |¡}n4|  ¡ dkrp|  d¡ |  |¡}n|  |  	d¡d¡ |S )Nr/   r+   r,   r   r€   )
rZ   rR   Ú_PROJECTION_STOPr   re   rQ   ro   rˆ   r   rS   )r7   rK   ri   r9   r9   r:   rf   ‡  s    

ÿzParser._parse_projection_rhsc                 C   s„   |   ¡ }|dkr|  |¡S |dkr4|  d¡ |  ¡ S |dkrN|  d¡ |  ¡ S |  d¡}ddddg}d||d f }|  ||¡ d S )	N)r   r   r*   r/   r.   r   r   r   úExpecting: %s, got: %srN   )rR   rQ   ro   r{   rm   rS   r   )r7   rK   r8   rV   ÚallowedÚmsgr9   r9   r:   rˆ   ˜  s"    	



 ÿÿzParser._parse_dot_rhsc                 C   s6   |d dkr&t  |d |d |d ¡‚|  |d¡ d S )NrN   r   rL   rM   úinvalid token)r   rH   r   r_   r9   r9   r:   rY   ´  s      ÿzParser._error_nud_tokenc                 C   s   |   |d¡ d S )Nr©   )r   r_   r9   r9   r:   r[   º  s    zParser._error_led_tokenNc                 C   s,   |   ¡ |kr|  ¡  n|  ||  d¡¡ d S r3   )rR   rW   Ú_raise_parse_error_maybe_eofrS   )r7   Ú
token_typer9   r9   r:   ro   ½  s    
 ÿzParser._matchc                 C   s*   |   ¡ |kr|  ||  d¡¡ |  ¡  d S r3   )rR   rª   rS   rW   )r7   r¡   r9   r9   r:   r£   Æ  s     ÿzParser._match_multiple_tokensc                 C   s   |  j d7  _ d S )Nr   )r6   ©r7   r9   r9   r:   rW   Ì  s    zParser._advancec                 C   s   | j | j d S ©NrN   ©r5   r6   r¬   r9   r9   r:   rR   Ï  s    zParser._current_tokenc                 C   s   | j | j|  d S r­   r®   ©r7   r   r9   r9   r:   rz   Ò  s    zParser._lookaheadc                 C   s   | j | j|  S r<   r®   r¯   r9   r9   r:   rS   Õ  s    zParser._lookahead_tokenc                 C   s,   |d }|d }|d }t  ||||¡‚d S )NrL   rM   rN   )r   rI   )r7   r`   ÚreasonÚlex_positionÚactual_valueÚactual_typer9   r9   r:   r   Ø  s     ÿz#Parser._raise_parse_error_for_tokenc                 C   sN   |d }|d }|d }|dkr.t  |||¡‚d||f }t  ||||¡‚d S )NrL   rM   rN   r   r¦   )r   rH   rI   )r7   Zexpected_typer`   r±   r²   r³   Úmessager9   r9   r:   rª   ß  s$      ÿÿ   ÿz#Parser._raise_parse_error_maybe_eofc                 C   s8   t  t| j ¡ ƒt| jd ƒ¡D ]}| j |d ¡ q d S )Nr	   )ÚrandomÚsamplerP   r=   ÚkeysÚintrA   Úpop)r7   Úkeyr9   r9   r:   rB   ë  s    $zParser._free_cache_entriesc                 C   s   | j  ¡  dS )z'Clear the expression compilation cache.N)r=   Úclear)Úclsr9   r9   r:   Úpurgeï  s    zParser.purge)r	   )r   )N);Ú__name__Ú
__module__Ú__qualname__rZ   r¥   r=   rA   r;   rF   r?   rG   rQ   ra   rc   rd   rj   rl   rn   rq   rt   rv   r|   rx   r}   r„   r…   r‹   rŒ   r   rŽ   r’   rk   r—   r˜   r™   rš   r›   rœ   r   rŸ   ry   r•   r{   rm   rf   rˆ   rY   r[   ro   r£   rW   rR   rz   rS   r   rª   rB   Úclassmethodr½   r9   r9   r9   r:   r   %   sª   â"



	
	r   c                   @   s.   e Zd Zdd„ Zd
dd„Zdd„ Zdd	„ ZdS )rT   c                 C   s   || _ || _d S r<   )rC   rU   )r7   rC   rU   r9   r9   r:   r;   ÷  s    zParsedResult.__init__Nc                 C   s   t  |¡}| | j|¡}|S r<   )r   ZTreeInterpreterÚvisitrU   )r7   rM   ÚoptionsÚinterpreterÚresultr9   r9   r:   Úsearchû  s    
zParsedResult.searchc                 C   s   t  ¡ }| | j¡}|S )af  Render the parsed AST as a dot file.

        Note that this is marked as an internal method because
        the AST is an implementation detail and is subject
        to change.  This method can be used to help troubleshoot
        or for development purposes, but is not considered part
        of the public supported API.  Use at your own risk.

        )r   ZGraphvizVisitorrÂ   rU   )r7   ZrendererÚcontentsr9   r9   r:   Ú_render_dot_file   s    
zParsedResult._render_dot_filec                 C   s
   t | jƒS r<   )ÚreprrU   r¬   r9   r9   r:   Ú__repr__  s    zParsedResult.__repr__)N)r¾   r¿   rÀ   r;   rÆ   rÈ   rÊ   r9   r9   r9   r:   rT   õ  s   
rT   )Ú__doc__rµ   Zjmespathr   Zjmespath.compatr   r   r   r   Úobjectr   rT   r9   r9   r9   r:   Ú<module>   s      S