U å€C^„Jã@spdZddlZddlmZddlmZddlmZddlmZddlmZGdd „d e ƒZ eGd d „d e ƒƒZ dS) 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úeZdZddddddddddddddddddddddddd d d d d dœZdZiZdZdxdd„Zdd„Zdd„Z dd„Z dydd„Z dd„Z dd„Z dd „Zd!d"„Zd#d$„Zd%d&„Zd'd(„Zd)d*„Zd+d,„Zd-d.„Zd/d0„Zd1d2„Zd3d4„Zd5d6„Zd7d8„Zd9d:„Zd;d<„Zd=d>„Zd?d@„ZdAdB„ZdCdD„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é é€cCs"d|_dg||_||_d|_dS©Nr)Ú tokenizerÚ_tokensZ _buffer_sizeÚ_index)ÚselfÚ lookahead©r9ú5/tmp/pip-install-6_kvzl1k/jmespath/jmespath/parser.pyÚ__init__Ns zParser.__init__cCsH|j |¡}|dk r|S| |¡}||j|<t|jƒ|jkrD| ¡|S©N)Ú_CACHEÚgetÚ _do_parseÚlenÚ _MAX_SIZEÚ_free_cache_entries)r7Ú expressionÚcachedÚ parsed_resultr9r9r:ÚparseTs   z Parser.parsec Cs–z | |¡WStjk r8}z ||_‚W5d}~XYnZtjk rf}z| |¡‚W5d}~XYn,tjk r}z ||_‚W5d}~XYnXdSr<)Ú_parserZ LexerErrorrCÚIncompleteExpressionErrorZset_expressionÚ ParseError)r7rCÚer9r9r:r?^s  zParser._do_parsecCsrt ¡ |¡|_t|jƒ|_d|_|jdd}| ¡dksh|  d¡}t   |d|d|dd|d¡‚t ||ƒS)Nr)Ú binding_powerrÚstartÚvalueÚtypezUnexpected token: %s) rZLexerÚtokenizer4Úlistr5r6Ú _expressionÚ_current_tokenÚ_lookahead_tokenrrIÚ ParsedResult)r7rCÚparsedÚtr9r9r:rGks     ÿz Parser._parsecCs’| d¡}| ¡t|d|d|jƒ}||ƒ}| ¡}||j|krŽt|d|dƒ}|dkrt| d¡}| |¡q8| ¡||ƒ}| ¡}q8|S)Nrz _token_nud_%srNz _token_led_%s)rSÚ_advanceÚgetattrÚ_error_nud_tokenrRÚ BINDING_POWERÚ_error_led_token)r7rKZ left_tokenZ nud_functionÚleftÚ current_tokenZledZ error_tokenr9r9r:rQvs$  þ   zParser._expressioncCst |d¡S©NrM)rr©r7Útokenr9r9r:Ú_token_nud_literal‰szParser._token_nud_literalcCst |d¡Sr^)rÚfieldr_r9r9r:Ú_token_nud_unquoted_identifierŒsz%Parser._token_nud_unquoted_identifiercCs@t |d¡}| ¡dkr<| d¡}t d|d|dd¡‚|S)NrMr0rrNz1Quoted identifier not allowed for function names.)rrbrRrSrrI)r7r`rbrVr9r9r:Ú_token_nud_quoted_identifiers  þz#Parser._token_nud_quoted_identifiercCs:t ¡}| ¡dkrt ¡}n| |jd¡}t ||¡S)Nrr*)rÚidentityrRÚ_parse_projection_rhsrZÚvalue_projection©r7r`r\Úrightr9r9r:Ú_token_nud_staršs   zParser._token_nud_starcCs| t ¡¡Sr<)Ú_token_led_filterrrer_r9r9r:Ú_token_nud_filter¢szParser._token_nud_filtercCs| ¡Sr<)Ú_parse_multi_select_hashr_r9r9r:Ú_token_nud_lbrace¥szParser._token_nud_lbracecCs| ¡}| d¡|S)Nr)rQÚ_match©r7r`rCr9r9r:Ú_token_nud_lparen¨s zParser._token_nud_lparencCs*t t ¡¡}| |jd¡}t ||¡S©Nr))rr)rerfrZÚ projectionrhr9r9r:Ú_token_nud_flatten­s ÿzParser._token_nud_flattencCs| |jd¡}t |¡S)Nr-)rQrZrZnot_expression)r7r`Úexprr9r9r:Ú_token_nud_not³szParser._token_nud_notcCsz| ¡dkr$| ¡}| t ¡|¡S| ¡dkrn| d¡dkrn| ¡| ¡| |jd¡}t  t ¡|¡S|  ¡SdS)N©rrr*rr) rRÚ_parse_index_expressionÚ_project_if_slicerreÚ _lookaheadrWrfrZrsÚ_parse_multi_select_list)r7r`rir9r9r:Ú_token_nud_lbracket·s   ÿzParser._token_nud_lbracketcCsR| d¡dks| d¡dkr$| ¡St | d¡d¡}| ¡| d¡|SdS)NrrrrMr)rzÚ_parse_slice_expressionrÚindexrSrWro)r7Únoder9r9r:rxÈs ÿ zParser._parse_index_expressioncCs®dddg}d}| ¡}|dksš|dkrš|dkrZ|d7}|dkrP| | d¡d¡| ¡n6|dkr~| d¡d||<| ¡n| | d¡d¡| ¡}q| d¡tj|ŽS) Nrrr rrú syntax errorrrM)rRÚ_raise_parse_error_for_tokenrSrWrorÚslice)r7Úpartsr~r]r9r9r:r}×s, ÿ  ÿ  zParser._parse_slice_expressioncCst ¡Sr<)rZ current_noder_r9r9r:Ú_token_nud_currentïszParser._token_nud_currentcCs| |jd¡}t |¡S)Nr)rQrZrrrpr9r9r:Ú_token_nud_exprefòszParser._token_nud_exprefcCsr| ¡dksJ| |jd¡}|ddkr:|d |¡|St ||g¡Sn$| ¡| |jd¡}t ||¡SdS)Nr*r,rNÚ subexpressionÚchildren) rRÚ_parse_dot_rhsrZÚappendrr†rWrfrg©r7r\rir9r9r:Ú_token_led_dotös  ÿzParser._token_led_dotcCs| |jd¡}t ||¡S)Nr )rQrZrr rŠr9r9r:Ú_token_led_pipeszParser._token_led_pipecCs| |jd¡}t ||¡S)Nr!)rQrZrZ or_expressionrŠr9r9r:Ú _token_led_or szParser._token_led_orcCs| |jd¡}t ||¡S)Nr")rQrZrZand_expressionrŠr9r9r:Ú_token_led_and szParser._token_led_andcCs–|ddkr:| d¡}t |d|d|dd|d¡‚|d}g}| ¡dks|| ¡}| ¡dkrp| d¡| |¡qF| d¡t ||¡}|S) NrNrbéþÿÿÿrLrMzInvalid function name '%s'rr) rSrrIrRrQror‰rZfunction_expression)r7r\Zprev_tÚnameÚargsrCZ function_noder9r9r:Ú_token_led_lparens$   þ      zParser._token_led_lparencCsH| d¡}| d¡| ¡dkr*t ¡}n| |jd¡}t |||¡S)Nrrr)r+)rQrorRrrerfrZZfilter_projection)r7r\Ú conditionrir9r9r:rk%s     zParser._token_led_filtercCs | |d¡S)Nr#©Ú_parse_comparator©r7r\r9r9r:Ú _token_led_eq/szParser._token_led_eqcCs | |d¡S)Nr(r”r–r9r9r:Ú _token_led_ne2szParser._token_led_necCs | |d¡S)Nr$r”r–r9r9r:Ú _token_led_gt5szParser._token_led_gtcCs | |d¡S)Nr&r”r–r9r9r:Ú_token_led_gte8szParser._token_led_gtecCs | |d¡S)Nr%r”r–r9r9r:Ú _token_led_lt;szParser._token_led_ltcCs | |d¡S)Nr'r”r–r9r9r:Ú_token_led_lte>szParser._token_led_ltecCs&t |¡}| |jd¡}t ||¡Srr)rr)rfrZrsrŠr9r9r:Ú_token_led_flattenAs  ÿzParser._token_led_flattencCs~| d¡}|ddkrJ| ¡}|ddkr<|d |¡|S| ||¡Sn0| d¡| d¡| |jd¡}t ||¡SdS)NrrNrwÚindex_expressionr‡r*r) rSrxr‰ryrorfrZrrs)r7r\r`rir9r9r:Ú_token_led_lbracketGs     zParser._token_led_lbracketcCs:t ||g¡}|ddkr2t || |jd¡¡S|SdS)NrNr‚r*)rržrsrfrZ)r7r\riZ index_exprr9r9r:ryZs þzParser._project_if_slicecCs| |j|¡}t |||¡Sr<)rQrZrÚ comparator)r7r\r rir9r9r:r•cszParser._parse_comparatorcCsFg}| ¡}| |¡| ¡dkr&q2q| d¡q| d¡t |¡S)Nrr)rQr‰rRrorZmulti_select_list)r7Z expressionsrCr9r9r:r{gs    zParser._parse_multi_select_listcCsg}| d¡}|jddgd|d}| d¡| d¡}tj||d}| |¡| ¡dkrj| d¡q| ¡d kr| d ¡q„qtj|d S) Nrrr)Ú token_typesrMr)Úkey_namerrr)Znodes) rSÚ_match_multiple_tokensrorQrZ key_val_pairr‰rRZmulti_select_dict)r7ÚpairsZ key_tokenr¢rMrr9r9r:rmss  ÿ       zParser._parse_multi_select_hashcCs†|j| ¡|jkrt ¡}nd| ¡dkr6| |¡}nL| ¡dkrN| |¡}n4| ¡dkrp| d¡| |¡}n| |  d¡d¡|S)Nr/r+r,rr€) rZrRÚ_PROJECTION_STOPrrerQrorˆrrS)r7rKrir9r9r:rf‡s         ÿzParser._parse_projection_rhscCs„| ¡}|dkr| |¡S|dkr4| d¡| ¡S|dkrN| d¡| ¡S| d¡}ddddg}d||df}| ||¡dS) N)rrr*r/r.rrrúExpecting: %s, got: %srN)rRrQror{rmrSr)r7rKr8rVÚallowedÚmsgr9r9r:rˆ˜s"     ÿÿzParser._parse_dot_rhscCs6|ddkr&t |d|d|d¡‚| |d¡dS)NrNrrLrMú invalid token)rrHrr_r9r9r:rY´s ÿzParser._error_nud_tokencCs| |d¡dS)Nr©)rr_r9r9r:r[ºszParser._error_led_tokenNcCs,| ¡|kr| ¡n| || d¡¡dSr3)rRrWÚ_raise_parse_error_maybe_eofrS)r7Ú token_typer9r9r:ro½s   ÿz Parser._matchcCs*| ¡|kr| || d¡¡| ¡dSr3)rRrªrSrW)r7r¡r9r9r:r£Æs  ÿzParser._match_multiple_tokenscCs|jd7_dS)Nr)r6©r7r9r9r:rWÌszParser._advancecCs|j|jdS©NrN©r5r6r¬r9r9r:rRÏszParser._current_tokencCs|j|j|dSr­r®©r7rr9r9r:rzÒszParser._lookaheadcCs|j|j|Sr<r®r¯r9r9r:rSÕszParser._lookahead_tokencCs,|d}|d}|d}t ||||¡‚dS)NrLrMrN)rrI)r7r`ÚreasonÚ lex_positionÚ actual_valueÚ actual_typer9r9r:rØsÿz#Parser._raise_parse_error_for_tokencCsN|d}|d}|d}|dkr.t |||¡‚d||f}t ||||¡‚dS)NrLrMrNrr¦)rrHrI)r7Z expected_typer`r±r²r³Úmessager9r9r:rªßs$ÿÿÿz#Parser._raise_parse_error_maybe_eofcCs.t |j ¡t|jdƒ¡D] }|j|=qdS)Nr )ÚrandomÚsampler=ÚkeysÚintrA)r7Úkeyr9r9r:rBës zParser._free_cache_entriescCs|j ¡dS)z'Clear the expression compilation cache.N)r=Úclear)Úclsr9r9r:Úpurgeïsz Parser.purge)r )r)N);Ú__name__Ú __module__Ú __qualname__rZr¥r=rAr;rFr?rGrQrarcrdrjrlrnrqrtrvr|rxr}r„r…r‹rŒrrŽr’rkr—r˜r™ršr›rœrrŸryr•r{rmrfrˆrYr[ror£rWrRrzrSrrªrBÚ classmethodr¼r9r9r9r:r%sªâ"          rc@s.eZdZdd„Zd dd„Zdd„Zdd „ZdS) rTcCs||_||_dSr<)rCrU)r7rCrUr9r9r:r;÷szParsedResult.__init__NcCst |¡}| |j|¡}|Sr<)rZTreeInterpreterÚvisitrU)r7rMÚoptionsZ interpreterÚresultr9r9r:Úsearchûs 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. )rZGraphvizVisitorrÁrU)r7ZrendererÚcontentsr9r9r:Ú_render_dot_files  zParsedResult._render_dot_filecCs t|jƒSr<)ÚreprrUr¬r9r9r:Ú__repr__szParsedResult.__repr__)N)r½r¾r¿r;rÄrÆrÈr9r9r9r:rTõs rT) Ú__doc__rµZjmespathrZjmespath.compatrrrrÚobjectrrTr9r9r9r:Ús     S