B u޲_J@spdZddlZddlmZddlmZddlmZddlmZddlmZGdd d e Z eGd d d e Z dS) aTop 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@seZdZddddddddddddddddddddddddd d d d d dZdZiZdZdxddZddZddZ ddZ dyddZ ddZ ddZ dd Zd!d"Zd#d$Zd%d&Zd'd(Zd)d*Zd+d,Zd-d.Zd/d0Zd1d2Zd3d4Zd5d6Zd7d8Zd9d:Zd;d<Zd=d>Zd?d@ZdAdBZdCdDZ dEdFZ!dGdHZ"dIdJZ#dKdLZ$dMdNZ%dOdPZ&dQdRZ'dSdTZ(dUdVZ)dWdXZ*dYdZZ+d[d\Z,d]d^Z-d_d`Z.dadbZ/dzdddeZ0dfdgZ1dhdiZ2djdkZ3dldmZ4dndoZ5dpdqZ6drdsZ7dtduZ8e9dvdwZ:dcS){Parserr (-27<)eofunquoted_identifierquoted_identifierliteralrbracketrparencommarbracenumbercurrentexprefcolonpipeorandeqgtltgtelteneflattenstarfilterdotnotlbracelbracketlparen cCs"d|_dg||_||_d|_dS)Nr) tokenizer_tokensZ _buffer_size_index)self lookaheadr86/tmp/pip-target-kmdnttut/lib/python/jmespath/parser.py__init__Ns zParser.__init__cCsH|j|}|dk r|S||}||j|<t|j|jkrD||S)N)_CACHEget _do_parselen _MAX_SIZE_free_cache_entries)r6 expressioncached parsed_resultr8r8r9parseTs   z Parser.parsec Csy ||Stjk r6}z ||_Wdd}~XYnZtjk rd}z||Wdd}~XYn,tjk r}z ||_Wdd}~XYnXdS)N)_parserZ LexerErrorrAIncompleteExpressionErrorZset_expression ParseError)r6rAer8r8r9r=^s  zParser._do_parsecCsrt||_t|j|_d|_|jdd}|dksh| d}t |d|d|dd|dt ||S)Nr) binding_powerrstartvaluetypezUnexpected token: %s) rZLexertokenizer3listr4r5 _expression_current_token_lookahead_tokenrrG ParsedResult)r6rAparsedtr8r8r9rEks    z Parser._parsecCs|d}|t|d|d|j}||}|}xX||j|krt|d|d}|dkrv|d}||q:|||}|}q:W|S)Nrz _token_nud_%srLz _token_led_%s)rQ_advancegetattr_error_nud_tokenrP BINDING_POWER_error_led_token)r6rIZ left_tokenZ nud_functionleft current_tokenZledZ error_tokenr8r8r9rOvs      zParser._expressioncCst|dS)NrK)rr)r6tokenr8r8r9_token_nud_literalszParser._token_nud_literalcCst|dS)NrK)rfield)r6r\r8r8r9_token_nud_unquoted_identifiersz%Parser._token_nud_unquoted_identifiercCs@t|d}|dkr<|d}td|d|dd|S)NrKr0rrLz1Quoted identifier not allowed for function names.)rr^rPrQrrG)r6r\r^rTr8r8r9_token_nud_quoted_identifiers  z#Parser._token_nud_quoted_identifiercCs:t}|dkrt}n||jd}t||S)Nrr*)ridentityrP_parse_projection_rhsrXvalue_projection)r6r\rZrightr8r8r9_token_nud_stars   zParser._token_nud_starcCs|tS)N)_token_led_filterrra)r6r\r8r8r9_token_nud_filterszParser._token_nud_filtercCs|S)N)_parse_multi_select_hash)r6r\r8r8r9_token_nud_lbraceszParser._token_nud_lbracecCs|}|d|S)Nr)rO_match)r6r\rAr8r8r9_token_nud_lparens zParser._token_nud_lparencCs*tt}||jd}t||S)Nr))rr)rarbrX projection)r6r\rZrdr8r8r9_token_nud_flattens zParser._token_nud_flattencCs||jd}t|S)Nr-)rOrXrZnot_expression)r6r\exprr8r8r9_token_nud_notszParser._token_nud_notcCsz|dkr$|}|t|S|dkrn|ddkrn||||jd}t t|S| SdS)N)rrr*rr) rP_parse_index_expression_project_if_slicerra _lookaheadrUrbrXrl_parse_multi_select_list)r6r\rdr8r8r9_token_nud_lbrackets  zParser._token_nud_lbracketcCsR|ddks|ddkr$|St|dd}||d|SdS)NrrrrKr)rr_parse_slice_expressionrindexrQrUrj)r6noder8r8r9rps zParser._parse_index_expressioncCsdddg}d}|}x|dks|dkr|dkr\|d7}|dkrR||dd|n6|dkr|dd||<|n||dd|}qW|dtj|S) Nrrr rrz syntax errorrrK)rP_raise_parse_error_for_tokenrQrUrjrslice)r6partsrvr[r8r8r9rus$     zParser._parse_slice_expressioncCstS)N)rZ current_node)r6r\r8r8r9_token_nud_currentszParser._token_nud_currentcCs||jd}t|S)Nr)rOrXrr)r6r\rAr8r8r9_token_nud_exprefszParser._token_nud_exprefcCsr|dksJ||jd}|ddkr:|d||St||gSn$|||jd}t||SdS)Nr*r,rL subexpressionchildren) rP_parse_dot_rhsrXappendrr}rUrbrc)r6rZrdr8r8r9_token_led_dots   zParser._token_led_dotcCs||jd}t||S)Nr )rOrXrr )r6rZrdr8r8r9_token_led_pipeszParser._token_led_pipecCs||jd}t||S)Nr!)rOrXrZ or_expression)r6rZrdr8r8r9 _token_led_or szParser._token_led_orcCs||jd}t||S)Nr")rOrXrZand_expression)r6rZrdr8r8r9_token_led_and szParser._token_led_andcCs|ddkr:|d}t|d|d|dd|d|d}g}x8|dks~|}|dkrr|d||qHW|dt||}|S) NrLr^rJrKzInvalid function name '%s'rr) rQrrGrPrOrjrrZfunction_expression)r6rZZprev_tnameargsrAZ function_noder8r8r9_token_led_lparens      zParser._token_led_lparencCsH|d}|d|dkr*t}n||jd}t|||S)Nrrr)r+)rOrjrPrrarbrXZfilter_projection)r6rZ conditionrdr8r8r9rf%s     zParser._token_led_filtercCs ||dS)Nr#)_parse_comparator)r6rZr8r8r9 _token_led_eq/szParser._token_led_eqcCs ||dS)Nr()r)r6rZr8r8r9 _token_led_ne2szParser._token_led_necCs ||dS)Nr$)r)r6rZr8r8r9 _token_led_gt5szParser._token_led_gtcCs ||dS)Nr&)r)r6rZr8r8r9_token_led_gte8szParser._token_led_gtecCs ||dS)Nr%)r)r6rZr8r8r9 _token_led_lt;szParser._token_led_ltcCs ||dS)Nr')r)r6rZr8r8r9_token_led_lte>szParser._token_led_ltecCs&t|}||jd}t||S)Nr))rr)rbrXrl)r6rZrdr8r8r9_token_led_flattenAs  zParser._token_led_flattencCs~|d}|ddkrJ|}|ddkr<|d||S|||Sn0|d|d||jd}t||SdS)NrrL)rrindex_expressionr~r*r) rQrprrqrjrbrXrrl)r6rZr\rdr8r8r9_token_led_lbracketGs     zParser._token_led_lbracketcCs:t||g}|ddkr2t|||jdS|SdS)NrLryr*)rrrlrbrX)r6rZrdZ index_exprr8r8r9rqZs  zParser._project_if_slicecCs||j|}t|||S)N)rOrXr comparator)r6rZrrdr8r8r9rcszParser._parse_comparatorcCsJg}x0|}|||dkr(Pq|dqW|dt|S)Nrr)rOrrPrjrZmulti_select_list)r6Z expressionsrAr8r8r9rsgs   zParser._parse_multi_select_listcCsg}x|d}|jddgd|d}|d|d}tj||d}|||dkrl|dq|d kr|d PqWtj|d S) Nrrr) token_typesrKr)key_namerwrr)Znodes) rQ_match_multiple_tokensrjrOrZ key_val_pairrrPZmulti_select_dict)r6pairsZ key_tokenrrKrwr8r8r9rhss          zParser._parse_multi_select_hashcCs|j||jkrt}nd|dkr6||}nL|dkrN||}n4|dkrp|d||}n|| dd|S)Nr/r+r,rz syntax error) rXrP_PROJECTION_STOPrrarOrjrrxrQ)r6rIrdr8r8r9rbs         zParser._parse_projection_rhscCs|}|dkr||S|dkr4|d|S|dkrN|d|S|d}ddddg}d||df}|||dS) N)rrr*r/r.rrrzExpecting: %s, got: %srL)rPrOrjrsrhrQrx)r6rIr7rTallowedmsgr8r8r9rs     zParser._parse_dot_rhscCs6|ddkr&t|d|d|d||ddS)NrLrrJrKz invalid token)rrFrx)r6r\r8r8r9rWs zParser._error_nud_tokencCs||ddS)Nz invalid token)rx)r6r\r8r8r9rYszParser._error_led_tokenNcCs,||kr|n|||ddS)Nr)rPrU_raise_parse_error_maybe_eofrQ)r6 token_typer8r8r9rjs  z Parser._matchcCs*||kr|||d|dS)Nr)rPrrQrU)r6rr8r8r9rs zParser._match_multiple_tokenscCs|jd7_dS)Nr)r5)r6r8r8r9rUszParser._advancecCs|j|jdS)NrL)r4r5)r6r8r8r9rPszParser._current_tokencCs|j|j|dS)NrL)r4r5)r6rr8r8r9rrszParser._lookaheadcCs|j|j|S)N)r4r5)r6rr8r8r9rQszParser._lookahead_tokencCs,|d}|d}|d}t||||dS)NrJrKrL)rrG)r6r\reason lex_position actual_value actual_typer8r8r9rxs z#Parser._raise_parse_error_for_tokencCsN|d}|d}|d}|dkr.t|||d||f}t||||dS)NrJrKrLrzExpecting: %s, got: %s)rrFrG)r6 expected_typer\rrrmessager8r8r9rs z#Parser._raise_parse_error_maybe_eofcCs8x2t|jt|jdD]}|j|dqWdS)Nr )randomsampler;keysintr?pop)r6keyr8r8r9r@s"zParser._free_cache_entriescCs|jdS)z'Clear the expression compilation cache.N)r;clear)clsr8r8r9purgesz Parser.purge)r )r)N);__name__ __module__ __qualname__rXrr;r?r:rDr=rErOr]r_r`rergrirkrmrortrprur{r|rrrrrrfrrrrrrrrrqrrsrhrbrrWrYrjrrUrPrrrQrxrr@ classmethodrr8r8r8r9r%s          rc@s.eZdZddZd ddZddZdd ZdS) rRcCs||_||_dS)N)rArS)r6rArSr8r8r9r:szParsedResult.__init__NcCst|}||j|}|S)N)rZTreeInterpretervisitrS)r6rKoptions interpreterresultr8r8r9searchs zParsedResult.searchcCst}||j}|S)afRender 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. )rZGraphvizVisitorrrS)r6Zrenderercontentsr8r8r9_render_dot_files  zParsedResult._render_dot_filecCs t|jS)N)reprrS)r6r8r8r9__repr__szParsedResult.__repr__)N)rrrr:rrrr8r8r8r9rRs rR) __doc__rZjmespathrZjmespath.compatrrrrobjectrrRr8r8r8r9s     S