o ^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@sBeZdZiddddddddddddddd dd dd dd dd dddddddddddddddddddddddd Zd ZiZd!Zdd"d#Zd$d%Zd&d'Z d(d)Z dd*d+Z d,d-Z d.d/Z d0d1Zd2d3Zd4d5Zd6d7Zd8d9Zd:d;Zdd?Zd@dAZdBdCZdDdEZdFdGZdHdIZdJdKZdLdMZdNdOZdPdQZdRdSZdTdUZ dVdWZ!dXdYZ"dZd[Z#d\d]Z$d^d_Z%d`daZ&dbdcZ'dddeZ(dfdgZ)dhdiZ*djdkZ+dldmZ,dndoZ-dpdqZ.drdsZ/ddudvZ0dwdxZ1dydzZ2d{d|Z3d}d~Z4ddZ5ddZ6ddZ7ddZ8e9ddZ:dtS)Parsereofrunquoted_identifierquoted_identifierliteralrbracketrparencommarbracenumbercurrentexprefcolonpipeorandeqgt (-27<) ltgtelteneflattenstarfilterdotnotlbracelbracketlparen cCs"d|_dg||_||_d|_dSNr) tokenizer_tokens _buffer_size_index)self lookaheadr:1/usr/lib/python3/dist-packages/jmespath/parser.py__init__Ns  zParser.__init__cCsH|j|}|dur |S||}||j|<t|j|jkr"||SN)_CACHEget _do_parselen _MAX_SIZE_free_cache_entries)r8 expressioncached parsed_resultr:r:r;parseTs   z Parser.parsec Cstz||WStjy}z||_d}~wtjy)}z||d}~wtjy9}z||_d}~wwr=)_parser LexerErrorrDIncompleteExpressionErrorset_expression ParseError)r8rDer:r:r;r@^s  zParser._do_parsecCsrt||_t|j|_d|_|jdd}|dks4| d}t |d|d|dd|dt ||S)Nr) binding_powerrstartvaluetypezUnexpected token: %s) rLexertokenizer4listr5r7 _expression_current_token_lookahead_tokenrrL ParsedResult)r8rDparsedtr:r:r;rHks      z Parser._parsecCs|d}|t|d|d|j}||}|}||j|krMt|d|d}|dur:|d}||n |||}|}||j|ks#|S)Nrz _token_nud_%srQz _token_led_%s)rW_advancegetattr_error_nud_tokenrV BINDING_POWER_error_led_token)r8rN left_token nud_functionleft current_tokenled error_tokenr:r:r;rUvs$     zParser._expressioncCt|dSNrP)rr r8tokenr:r:r;_token_nud_literalzParser._token_nud_literalcCrfrg)rfieldrhr:r:r;_token_nud_unquoted_identifierrkz%Parser._token_nud_unquoted_identifiercCs@t|d}|dkr|d}td|d|dd|S)NrPr0rrQz1Quoted identifier not allowed for function names.)rrlrVrWrrL)r8rirlrZr:r:r;_token_nud_quoted_identifiers  z#Parser._token_nud_quoted_identifiercCs:t}|dkrt}n||jd}t||S)Nr r*)ridentityrV_parse_projection_rhsr^value_projectionr8rirbrightr:r:r;_token_nud_stars    zParser._token_nud_starcCs|tSr=)_token_led_filterrrorhr:r:r;_token_nud_filterrkzParser._token_nud_filtercCs|Sr=)_parse_multi_select_hashrhr:r:r;_token_nud_lbracezParser._token_nud_lbracecCs|}|d|S)Nr )rU_matchr8rirDr:r:r;_token_nud_lparens zParser._token_nud_lparencCs*tt}||jd}t||SNr))rr)rorpr^ projectionrrr:r:r;_token_nud_flattens  zParser._token_nud_flattencC||jd}t|S)Nr-)rUr^rnot_expression)r8riexprr:r:r;_token_nud_not zParser._token_nud_notcCsv|dvr|}|t|S|dkr7|ddkr7||||jd}t t|S| S)Nrrr*rr ) rV_parse_index_expression_project_if_slicerro _lookaheadr[rpr^r~_parse_multi_select_list)r8rirsr:r:r;_token_nud_lbrackets  zParser._token_nud_lbracketcCsN|ddks|ddkr|St|dd}||d|S)NrrrrPr )r_parse_slice_expressionrindexrWr[rz)r8noder:r:r;rs zParser._parse_index_expressioncCsgd}d}|}|dksS|dkrS|dkr,|d7}|dkr'||dd|n|dkr>|dd ||<|n ||dd|}|dksS|dks|dtj|S) N)NNNrr rrr syntax errorrrP)rV_raise_parse_error_for_tokenrWr[rzrslice)r8partsrrcr:r:r;rs*      zParser._parse_slice_expressioncCstSr=)r current_noderhr:r:r;_token_nud_currentryzParser._token_nud_currentcCr)Nr)rUr^rrr{r:r:r;_token_nud_exprefrzParser._token_nud_exprefcCsl|dks$||jd}|ddkr|d||St||gS|||jd}t||S)Nr*r,rQ subexpressionchildren) rV_parse_dot_rhsr^appendrrr[rprqr8rbrsr:r:r;_token_led_dots   zParser._token_led_dotcC||jd}t||S)Nr)rUr^rrrr:r:r;_token_led_pipe zParser._token_led_pipecCr)Nr)rUr^r or_expressionrr:r:r; _token_led_or rzParser._token_led_orcCr)Nr)rUr^rand_expressionrr:r:r;_token_led_and rzParser._token_led_andcCs|ddkr|d}t|d|d|dd|d|d}g}|dksC|}|dkr8|d|||dkr)|dt||}|S) NrQrlrOrPzInvalid function name '%s'r r) rWrrLrVrUrzrrfunction_expression)r8rbprev_tnameargsrD function_noder:r:r;_token_led_lparens"         zParser._token_led_lparencCsH|d}|d|dkrt}n||jd}t|||S)Nrr r)r+)rUrzrVrrorpr^filter_projection)r8rb conditionrsr:r:r;ru%s    zParser._token_led_filtercC ||dS)Nr_parse_comparatorr8rbr:r:r; _token_led_eq/ zParser._token_led_eqcCr)Nr(rrr:r:r; _token_led_ne2rzParser._token_led_necCr)Nrrrr:r:r; _token_led_gt5rzParser._token_led_gtcCr)Nr&rrr:r:r;_token_led_gte8rzParser._token_led_gtecCr)Nr%rrr:r:r; _token_led_lt;rzParser._token_led_ltcCr)Nr'rrr:r:r;_token_led_lte>rzParser._token_led_ltecCs&t|}||jd}t||Sr})rr)rpr^r~rr:r:r;_token_led_flattenAs  zParser._token_led_flattencCsx|d}|ddvr$|}|ddkr|d||S|||S|d|d||jd}t||S)NrrQrindex_expressionrr*r ) rWrrrrzrpr^rr~)r8rbrirsr:r:r;_token_led_lbracketGs       zParser._token_led_lbracketcCs6t||g}|ddkrt|||jdS|S)NrQrr*)rrr~rpr^)r8rbrs index_exprr:r:r;rZs zParser._project_if_slicecCs||j|}t|||Sr=)rUr^r comparator)r8rbrrsr:r:r;rcszParser._parse_comparatorcCsFg} |}|||dkrn|dq|dt|S)NTr r)rUrrVrzrmulti_select_list)r8 expressionsrDr:r:r;rgs     zParser._parse_multi_select_listcCsg} |d}|jddgd|d}|d|d}tj||d}|||d kr6|d n |d krB|d nqtj|d S) NTrr r ) token_typesrPr)key_namerrr)nodes) rW_match_multiple_tokensrzrUr key_val_pairrrVmulti_select_dict)r8pairs key_tokenrrPrr:r:r;rwss$         zParser._parse_multi_select_hashcCs|j||jkrt}|S|dkr||}|S|dkr*||}|S|dkr<|d||}|S|| dd|S)Nr/r+r,rr) r^rV_PROJECTION_STOPrrorUrzrrrW)r8rNrsr:r:r;rps"     zParser._parse_projection_rhscCs|}|dvr ||S|dkr|d|S|dkr'|d|S|d}gd}d||df}|||dS)N)r r r*r/r.r)r r r/r.Expecting: %s, got: %srQ)rVrUrzrrwrWr)r8rNr9rZallowedmsgr:r:r;rs     zParser._parse_dot_rhscCs6|ddkrt|d|d|d||ddS)NrQrrOrP invalid token)rrJrrhr:r:r;r]s zParser._error_nud_tokencCs||ddS)Nr)rrhr:r:r;r_zParser._error_led_tokenNcCs.||kr |dS|||ddSr3)rVr[_raise_parse_error_maybe_eofrW)r8 token_typer:r:r;rzs   z Parser._matchcCs*||vr|||d|dSr3)rVrrWr[)r8rr:r:r;rs   zParser._match_multiple_tokenscCs|jd7_dS)Nr)r7r8r:r:r;r[szParser._advancecCs|j|jdSNrQr5r7rr:r:r;rVrzParser._current_tokencCs|j|j|dSrrr8rr:r:r;rszParser._lookaheadcCs|j|j|Sr=rrr:r:r;rWrzParser._lookahead_tokencCs(|d}|d}|d}t||||)NrOrPrQ)rrL)r8rireason lex_position actual_value actual_typer:r:r;rs z#Parser._raise_parse_error_for_tokencCsJ|d}|d}|d}|dkrt|||d||f}t||||)NrOrPrQrr)rrJrL)r8 expected_typerirrrmessager:r:r;rsz#Parser._raise_parse_error_maybe_eofcCs4t|jt|jdD] }|j|dqdS)Nr)randomsampler>keysintrBpop)r8keyr:r:r;rCs zParser._free_cache_entriescCs|jdS)z'Clear the expression compilation cache.N)r>clear)clsr:r:r;purgesz Parser.purge)r)rr=);__name__ __module__ __qualname__r^rr>rBr<rGr@rHrUrjrmrnrtrvrxr|rrrrrrrrrrrrrurrrrrrrrrrrrwrprr]r_rzrr[rVrrWrrrC classmethodrr:r:r:r;r%s     "          rc@s.eZdZddZd ddZddZdd ZdS) rXcCs||_||_dSr=)rDrY)r8rDrYr:r:r;r<s zParsedResult.__init__NcCst|}||j|}|Sr=)rTreeInterpretervisitrY)r8rPoptions interpreterresultr:r:r;searchs 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. )rGraphvizVisitorrrY)r8renderercontentsr:r:r;_render_dot_files zParsedResult._render_dot_filecCs t|jSr=)reprrYrr:r:r;__repr__s zParsedResult.__repr__r=)rrrr<rrrr:r:r:r;rXs   rX) __doc__rjmespathrjmespath.compatrrrrobjectrrXr:r:r:r;s     S