B Ðñ¢dJã@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©r8ú6/tmp/pip-target-jj3kjtpb/lib/python/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)r6Ú expressionÚcachedÚ parsed_resultr8r8r9ÚparseTs   z Parser.parsec Cs”y | |¡Stjk r6}z ||_‚Wdd}~XYnZtjk rd}z| |¡‚Wdd}~XYn,tjk rŽ}z ||_‚Wdd}~XYnXdS)N)Ú_parserZ LexerErrorrAÚIncompleteExpressionErrorZset_expressionÚ ParseError)r6rAÚer8r8r9r=^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) rÚLexerÚtokenizer3Úlistr4r5Ú _expressionÚ_current_tokenÚ_lookahead_tokenrrGÚ ParsedResult)r6rAÚparsedÚtr8r8r9rEks    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)rRÚ_advanceÚgetattrÚ_error_nud_tokenrQÚ BINDING_POWERÚ_error_led_token)r6rIZ left_tokenZ nud_functionÚleftÚ current_tokenZledZ error_tokenr8r8r9rPvs      zParser._expressioncCst |d¡S)NrK)rr)r6Útokenr8r8r9Ú_token_nud_literal‰szParser._token_nud_literalcCst |d¡S)NrK)rÚfield)r6r]r8r8r9Ú_token_nud_unquoted_identifierŒsz%Parser._token_nud_unquoted_identifiercCs@t |d¡}| ¡dkr<| d¡}t d|d|dd¡‚|S)NrKr0rrLz1Quoted identifier not allowed for function names.)rr_rQrRrrG)r6r]r_rUr8r8r9Ú_token_nud_quoted_identifiers  z#Parser._token_nud_quoted_identifiercCs:t ¡}| ¡dkrt ¡}n| |jd¡}t ||¡S)Nrr*)rÚidentityrQÚ_parse_projection_rhsrYÚvalue_projection)r6r]r[Úrightr8r8r9Ú_token_nud_staršs   zParser._token_nud_starcCs| t ¡¡S)N)Ú_token_led_filterrrb)r6r]r8r8r9Ú_token_nud_filter¢szParser._token_nud_filtercCs| ¡S)N)Ú_parse_multi_select_hash)r6r]r8r8r9Ú_token_nud_lbrace¥szParser._token_nud_lbracecCs| ¡}| d¡|S)Nr)rPÚ_match)r6r]rAr8r8r9Ú_token_nud_lparen¨s zParser._token_nud_lparencCs*t t ¡¡}| |jd¡}t ||¡S)Nr))rr)rbrcrYÚ projection)r6r]r[rer8r8r9Ú_token_nud_flatten­s zParser._token_nud_flattencCs| |jd¡}t |¡S)Nr-)rPrYrZnot_expression)r6r]Úexprr8r8r9Ú_token_nud_not³szParser._token_nud_notcCsz| ¡dkr$| ¡}| t ¡|¡S| ¡dkrn| d¡dkrn| ¡| ¡| |jd¡}t  t ¡|¡S|  ¡SdS)N)rrr*rr) rQÚ_parse_index_expressionÚ_project_if_slicerrbÚ _lookaheadrVrcrYrmÚ_parse_multi_select_list)r6r]rer8r8r9Ú_token_nud_lbracket·s  zParser._token_nud_lbracketcCsR| d¡dks| d¡dkr$| ¡St | d¡d¡}| ¡| d¡|SdS)NrrrrKr)rsÚ_parse_slice_expressionrÚindexrRrVrk)r6Únoder8r8r9rqÈs zParser._parse_index_expressioncCs²dddg}d}| ¡}x†|dksœ|dkrœ|dkr\|d7}|dkrR| | d¡d¡| ¡n6|dkr€| d¡d||<| ¡n| | d¡d¡| ¡}qW| d¡tj|ŽS) Nrrr rrz syntax errorrrK)rQÚ_raise_parse_error_for_tokenrRrVrkrÚslice)r6Úpartsrwr\r8r8r9rv×s$     zParser._parse_slice_expressioncCst ¡S)N)rZ current_node)r6r]r8r8r9Ú_token_nud_currentïszParser._token_nud_currentcCs| |jd¡}t |¡S)Nr)rPrYrr)r6r]rAr8r8r9Ú_token_nud_exprefòszParser._token_nud_exprefcCsr| ¡dksJ| |jd¡}|ddkr:|d |¡|St ||g¡Sn$| ¡| |jd¡}t ||¡SdS)Nr*r,rLÚ subexpressionÚchildren) rQÚ_parse_dot_rhsrYÚappendrr~rVrcrd)r6r[rer8r8r9Ú_token_led_dotös   zParser._token_led_dotcCs| |jd¡}t ||¡S)Nr )rPrYrr )r6r[rer8r8r9Ú_token_led_pipeszParser._token_led_pipecCs| |jd¡}t ||¡S)Nr!)rPrYrZ or_expression)r6r[rer8r8r9Ú _token_led_or szParser._token_led_orcCs| |jd¡}t ||¡S)Nr")rPrYrZand_expression)r6r[rer8r8r9Ú_token_led_and szParser._token_led_andcCsš|ddkr:| d¡}t |d|d|dd|d¡‚|d}g}x8| ¡dks~| ¡}| ¡dkrr| d¡| |¡qHW| d¡t ||¡}|S) NrLr_éþÿÿÿrJrKzInvalid function name '%s'rr) rRrrGrQrPrkrrZfunction_expression)r6r[Zprev_tÚnameÚargsrAZ function_noder8r8r9Ú_token_led_lparens      zParser._token_led_lparencCsH| d¡}| d¡| ¡dkr*t ¡}n| |jd¡}t |||¡S)Nrrr)r+)rPrkrQrrbrcrYZfilter_projection)r6r[Ú conditionrer8r8r9rg%s     zParser._token_led_filtercCs | |d¡S)Nr#)Ú_parse_comparator)r6r[r8r8r9Ú _token_led_eq/szParser._token_led_eqcCs | |d¡S)Nr()r‹)r6r[r8r8r9Ú _token_led_ne2szParser._token_led_necCs | |d¡S)Nr$)r‹)r6r[r8r8r9Ú _token_led_gt5szParser._token_led_gtcCs | |d¡S)Nr&)r‹)r6r[r8r8r9Ú_token_led_gte8szParser._token_led_gtecCs | |d¡S)Nr%)r‹)r6r[r8r8r9Ú _token_led_lt;szParser._token_led_ltcCs | |d¡S)Nr')r‹)r6r[r8r8r9Ú_token_led_lte>szParser._token_led_ltecCs&t |¡}| |jd¡}t ||¡S)Nr))rr)rcrYrm)r6r[rer8r8r9Ú_token_led_flattenAs  zParser._token_led_flattencCs~| d¡}|ddkrJ| ¡}|ddkr<|d |¡|S| ||¡Sn0| d¡| d¡| |jd¡}t ||¡SdS)NrrL)rrÚindex_expressionrr*r) rRrqrrrrkrcrYrrm)r6r[r]rer8r8r9Ú_token_led_lbracketGs     zParser._token_led_lbracketcCs:t ||g¡}|ddkr2t || |jd¡¡S|SdS)NrLrzr*)rr“rmrcrY)r6r[reZ index_exprr8r8r9rrZs  zParser._project_if_slicecCs| |j|¡}t |||¡S)N)rPrYrÚ comparator)r6r[r•rer8r8r9r‹cszParser._parse_comparatorcCsJg}x0| ¡}| |¡| ¡dkr(Pq| d¡qW| d¡t |¡S)Nrr)rPrrQrkrZmulti_select_list)r6Z expressionsrAr8r8r9rtgs   zParser._parse_multi_select_listcCs”g}x‚| d¡}|jddgd|d}| d¡| d¡}tj||d}| |¡| ¡dkrl| d¡q| ¡d kr| d ¡PqWtj|d S) Nrrr)Ú token_typesrKr)Úkey_namerxrr)Znodes) rRÚ_match_multiple_tokensrkrPrZ key_val_pairrrQZmulti_select_dict)r6ÚpairsZ key_tokenr—rKrxr8r8r9riss          zParser._parse_multi_select_hashcCs†|j| ¡|jkrt ¡}nd| ¡dkr6| |¡}nL| ¡dkrN| |¡}n4| ¡dkrp| d¡| |¡}n| |  d¡d¡|S)Nr/r+r,rz syntax error) rYrQÚ_PROJECTION_STOPrrbrPrkr€ryrR)r6rIrer8r8r9rc‡s         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)rQrPrkrtrirRry)r6rIr7rUÚallowedÚmsgr8r8r9r€˜s     zParser._parse_dot_rhscCs6|ddkr&t |d|d|d¡‚| |d¡dS)NrLrrJrKz invalid token)rrFry)r6r]r8r8r9rX´s zParser._error_nud_tokencCs| |d¡dS)Nz invalid token)ry)r6r]r8r8r9rZºszParser._error_led_tokenNcCs,| ¡|kr| ¡n| || d¡¡dS)Nr)rQrVÚ_raise_parse_error_maybe_eofrR)r6Ú token_typer8r8r9rk½s  z Parser._matchcCs*| ¡|kr| || d¡¡| ¡dS)Nr)rQrrRrV)r6r–r8r8r9r˜Æs zParser._match_multiple_tokenscCs|jd7_dS)Nr)r5)r6r8r8r9rVÌszParser._advancecCs|j|jdS)NrL)r4r5)r6r8r8r9rQÏszParser._current_tokencCs|j|j|dS)NrL)r4r5)r6rr8r8r9rsÒszParser._lookaheadcCs|j|j|S)N)r4r5)r6rr8r8r9rRÕszParser._lookahead_tokencCs,|d}|d}|d}t ||||¡‚dS)NrJrKrL)rrG)r6r]ÚreasonÚ lex_positionÚ actual_valueÚ actual_typer8r8r9ryØs z#Parser._raise_parse_error_for_tokencCsN|d}|d}|d}|dkr.t |||¡‚d||f}t ||||¡‚dS)NrJrKrLrzExpecting: %s, got: %s)rrFrG)r6Ú expected_typer]r r¡r¢Úmessager8r8r9rßs z#Parser._raise_parse_error_maybe_eofcCs<x6t t|j ¡ƒt|jdƒ¡D]}|j |d¡q"WdS)Nr )ÚrandomÚsamplerOr;ÚkeysÚintr?Úpop)r6Úkeyr8r8r9r@ës&zParser._free_cache_entriescCs|j ¡dS)z'Clear the expression compilation cache.N)r;Úclear)Úclsr8r8r9Úpurgeïsz Parser.purge)r )r)N);Ú__name__Ú __module__Ú __qualname__rYršr;r?r:rDr=rErPr^r`rarfrhrjrlrnrprurqrvr|r}r‚rƒr„r…r‰rgrŒrrŽrrr‘r’r”rrr‹rtrircr€rXrZrkr˜rVrQrsrRryrr@Ú classmethodr­r8r8r8r9r%s¦          rc@s.eZdZdd„Zd dd„Zdd„Zdd „ZdS) rScCs||_||_dS)N)rArT)r6rArTr8r8r9r:÷szParsedResult.__init__NcCst |¡}| |j|¡}|S)N)rZTreeInterpreterÚvisitrT)r6rKÚoptionsÚ interpreterÚresultr8r8r9Ú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²rT)r6ÚrendererÚcontentsr8r8r9Ú_render_dot_files  zParsedResult._render_dot_filecCs t|jƒS)N)ÚreprrT)r6r8r8r9Ú__repr__szParsedResult.__repr__)N)r®r¯r°r:r¶r¹r»r8r8r8r9rSõs rS) Ú__doc__r¥ZjmespathrZjmespath.compatrrrrÚobjectrrSr8r8r8r9Ús     S