B ㊇cJ@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 lookaheadr8j/private/var/folders/8c/hx9_v10d5x38qmnzt13b7b8j1k3n5b/T/pip-target-x6xd5gna/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) rLexertokenizer3listr4r5 _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)rR_advancegetattr_error_nud_tokenrQ BINDING_POWER_error_led_token)r6rIZ left_tokenZ nud_functionleft current_tokenZledZ error_tokenr8r8r9rPvs      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_rQrRrrG)r6r]r_rUr8r8r9_token_nud_quoted_identifiers  z#Parser._token_nud_quoted_identifiercCs:t}|dkrt}n||jd}t||S)Nrr*)ridentityrQ_parse_projection_rhsrYvalue_projection)r6r]r[rightr8r8r9_token_nud_stars   zParser._token_nud_starcCs|tS)N)_token_led_filterrrb)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)rP_match)r6r]rAr8r8r9_token_nud_lparens zParser._token_nud_lparencCs*tt}||jd}t||S)Nr))rr)rbrcrY projection)r6r]r[rer8r8r9_token_nud_flattens zParser._token_nud_flattencCs||jd}t|S)Nr-)rPrYrZnot_expression)r6r]exprr8r8r9_token_nud_notszParser._token_nud_notcCsz|dkr$|}|t|S|dkrn|ddkrn||||jd}t t|S| SdS)N)rrr*rr) rQ_parse_index_expression_project_if_slicerrb _lookaheadrVrcrYrm_parse_multi_select_list)r6r]rer8r8r9_token_nud_lbrackets  zParser._token_nud_lbracketcCsR|ddks|ddkr$|St|dd}||d|SdS)NrrrrKr)rs_parse_slice_expressionrindexrRrVrk)r6noder8r8r9rqs zParser._parse_index_expressioncCsdddg}d}|}x|dks|dkr|dkr\|d7}|dkrR||dd|n6|dkr|dd||<|n||dd|}qW|dtj|S) Nrrr rrz syntax errorrrK)rQ_raise_parse_error_for_tokenrRrVrkrslice)r6partsrwr\r8r8r9rvs$     zParser._parse_slice_expressioncCstS)N)rZ current_node)r6r]r8r8r9_token_nud_currentszParser._token_nud_currentcCs||jd}t|S)Nr)rPrYrr)r6r]rAr8r8r9_token_nud_exprefszParser._token_nud_exprefcCsr|dksJ||jd}|ddkr:|d||St||gSn$|||jd}t||SdS)Nr*r,rL subexpressionchildren) rQ_parse_dot_rhsrYappendrr~rVrcrd)r6r[rer8r8r9_token_led_dots   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|dt||}|S) NrLr_rJrKzInvalid function name '%s'rr) rRrrGrQrPrkrrZfunction_expression)r6r[Zprev_tnameargsrAZ 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 ||dS)Nr#)_parse_comparator)r6r[r8r8r9 _token_led_eq/szParser._token_led_eqcCs ||dS)Nr()r)r6r[r8r8r9 _token_led_ne2szParser._token_led_necCs ||dS)Nr$)r)r6r[r8r8r9 _token_led_gt5szParser._token_led_gtcCs ||dS)Nr&)r)r6r[r8r8r9_token_led_gte8szParser._token_led_gtecCs ||dS)Nr%)r)r6r[r8r8r9 _token_led_lt;szParser._token_led_ltcCs ||dS)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)rrindex_expressionrr*r) rRrqrrrrkrcrYrrm)r6r[r]rer8r8r9_token_led_lbracketGs     zParser._token_led_lbracketcCs:t||g}|ddkr2t|||jdS|SdS)NrLrzr*)rrrmrcrY)r6r[reZ index_exprr8r8r9rrZs  zParser._project_if_slicecCs||j|}t|||S)N)rPrYr comparator)r6r[rrer8r8r9rcszParser._parse_comparatorcCsJg}x0|}|||dkr(Pq|dqW|dt|S)Nrr)rPrrQrkrZmulti_select_list)r6Z expressionsrAr8r8r9rtgs   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_namerxrr)Znodes) rR_match_multiple_tokensrkrPrZ key_val_pairrrQZmulti_select_dict)r6pairsZ key_tokenrrKrxr8r8r9riss          zParser._parse_multi_select_hashcCs|j||jkrt}nd|dkr6||}nL|dkrN||}n4|dkrp|d||}n|| dd|S)Nr/r+r,rz syntax error) rYrQ_PROJECTION_STOPrrbrPrkrryrR)r6rIrer8r8r9rcs         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)r6rIr7rUallowedmsgr8r8r9rs     zParser._parse_dot_rhscCs6|ddkr&t|d|d|d||ddS)NrLrrJrKz invalid token)rrFry)r6r]r8r8r9rXs zParser._error_nud_tokencCs||ddS)Nz invalid token)ry)r6r]r8r8r9rZszParser._error_led_tokenNcCs,||kr|n|||ddS)Nr)rQrV_raise_parse_error_maybe_eofrR)r6 token_typer8r8r9rks  z Parser._matchcCs*||kr|||d|dS)Nr)rQrrRrV)r6rr8r8r9rs zParser._match_multiple_tokenscCs|jd7_dS)Nr)r5)r6r8r8r9rVszParser._advancecCs|j|jdS)NrL)r4r5)r6r8r8r9rQszParser._current_tokencCs|j|j|dS)NrL)r4r5)r6rr8r8r9rsszParser._lookaheadcCs|j|j|S)N)r4r5)r6rr8r8r9rRszParser._lookahead_tokencCs,|d}|d}|d}t||||dS)NrJrKrL)rrG)r6r]reason lex_position actual_value actual_typer8r8r9rys 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_eofcCs<x6tt|jt|jdD]}|j|dq"WdS)Nr )randomsamplerOr;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__rYrr;r?r:rDr=rErPr^r`rarfrhrjrlrnrprurqrvr|r}rrrrrrgrrrrrrrrrrrrtrircrrXrZrkrrVrQrsrRryrr@ classmethodrr8r8r8r9r%s          rc@s.eZdZddZd ddZddZdd ZdS) rScCs||_||_dS)N)rArT)r6rArTr8r8r9r:szParsedResult.__init__NcCst|}||j|}|S)N)rZTreeInterpretervisitrT)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. )rZGraphvizVisitorrrT)r6renderercontentsr8r8r9_render_dot_files  zParsedResult._render_dot_filecCs t|jS)N)reprrT)r6r8r8r9__repr__szParsedResult.__repr__)N)rrrr:rrrr8r8r8r9rSs rS) __doc__rjmespathrZjmespath.compatrrrrobjectrrSr8r8r8r9s     S