g Vc@sdZddlZddlmZddlmZddlmZddlmZddlmZde fd YZ ed e fd YZ dS( sTop 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. iN(tlexer(twith_repr_method(tast(t exceptions(tvisitortParsercBseZidd6dd6dd6dd6dd6dd6dd6dd6dd 6dd 6dd 6d d 6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd 6d!d"6d#d$6d%d&6d'd(6Zd)ZiZd*Zdd+Zd,Zd-Zd.Z dd/Z d0Z d1Z d2Z d3Zd4Zd5Zd6Zd7Zd8Zd9Zd:Zd;Zd<Zd=Zd>Zd?Zd@ZdAZdBZdCZdDZdEZ dFZ!dGZ"dHZ#dIZ$dJZ%dKZ&dLZ'dMZ(dNZ)dOZ*dPZ+dQZ,dRZ-dSZ.dTZ/dUZ0d^dVZ2dWZ3dXZ4dYZ5dZZ6d[Z7d\Z8e9d]Z:RS(_iteoftunquoted_identifiertquoted_identifiertrbrackettrparentcommatrbracetnumbertcurrenttexpreftcolonitpipeitoritanditeqtgttlttgtetltetnei tflattenitstaritfilteri(tdoti-tnoti2tlbracei7tlbracketi<tlpareni icCs/d|_dg||_||_d|_dS(Ni(tNonet tokenizert_tokenst _buffer_sizet_index(tselft lookahead((s0/usr/lib/fence-agents/bundled/jmespath/parser.pyt__init__Ms  cCsg|jj|}|dk r"|S|j|}||j|Pq |jdq W|jdtj|S(NR R (tTrueRAR|RBRbRtmulti_select_list(R't expressionsR0((s0/usr/lib/fence-agents/bundled/jmespath/parser.pyRlbs    cCsg}xtr|jd}|jdddg|d}|jd|jd}tjd|d|}|j||jd kr|jd q |jd kr |jd Pq q Wtj d |S( Nit token_typesRRR<Rtkey_nameRpR R tnodes( RRCt_match_multiple_tokensRbRARt key_val_pairR|RBtmulti_select_dict(R'tpairst key_tokenRR<Rp((s0/usr/lib/fence-agents/bundled/jmespath/parser.pyR`ns        cCs|j|j|jkr+tj}n|jdkrO|j|}n|jdkrs|j|}nv|jdkr|jd|j|}nE|jd}|d}|d}|d}t j |||d|S( NR RRiR;R<R=s syntax error( RJRBt_PROJECTION_STOPRRYRARbR{RCRR8(R'R:R\RFRsRtRu((s0/usr/lib/fence-agents/bundled/jmespath/parser.pyRZs       cCs|j}|d kr%|j|S|dkrH|jd|jS|dkrk|jd|jS|jd}ddddg}|d}|d}|d }tj|||d ||fdS( NRRRR RiR;R<R=sExpecting: %s, got: %s(squoted_identifiersunquoted_identifiersstar(RBRARbRlR`RCRR8(R'R:R(RFtallowedRsRtRu((s0/usr/lib/fence-agents/bundled/jmespath/parser.pyR{s&              cGsh|j|krd|jd}|d}|d}|d}tj|||d||fndS(NiR;R<R=sToken %s not allowed to be: %s(RBRCRR8(R'RRFRsRtRu((s0/usr/lib/fence-agents/bundled/jmespath/parser.pyt_assert_not_tokens    cCs\|ddkr4tj|d|d|dntj|d|d|dddS(NR=RR;R<sInvalid token.(RR6R8(R'RS((s0/usr/lib/fence-agents/bundled/jmespath/parser.pyRIs cCs(tj|d|d|dddS(NR;R<R=s Invalid token(RR8(R'RS((s0/usr/lib/fence-agents/bundled/jmespath/parser.pyRKscCs|j|kr|jny|jd}|d}|d}|d}|dkrptj|||nd||f}tj||||dS(NiR;R<R=RsExpecting: %s, got: %s(RBRGRCRR6R8(R't token_typeRFRsRtRutmessage((s0/usr/lib/fence-agents/bundled/jmespath/parser.pyRbs      cCs|j|kr|jd}|d}|d}|d}|dkrctj|||nd||f}tj||||n|jdS(NiR;R<R=RsExpecting: %s, got: %s(RBRCRR6R8RG(R'RRFRsRtRuR((s0/usr/lib/fence-agents/bundled/jmespath/parser.pyRs     cCs|jd7_dS(Ni(R&(R'((s0/usr/lib/fence-agents/bundled/jmespath/parser.pyRGscCs|j|jdS(NR=(R$R&(R'((s0/usr/lib/fence-agents/bundled/jmespath/parser.pyRBscCs|j|j|dS(NR=(R$R&(R'R ((s0/usr/lib/fence-agents/bundled/jmespath/parser.pyRkscCs|j|j|S(N(R$R&(R'R ((s0/usr/lib/fence-agents/bundled/jmespath/parser.pyRCscCsAx:tj|jjt|jdD]}|j|=q)WdS(Ni(trandomtsampleR*tkeystintR.(R'tkey((s0/usr/lib/fence-agents/bundled/jmespath/parser.pyR/s/cCs|jjdS(s'Clear the expression compilation cache.N(R*tclear(tcls((s0/usr/lib/fence-agents/bundled/jmespath/parser.pytpurgesN(;t__name__t __module__RJRR*R.R)R3R,R4RARTRURWRXR]R_RaRcReRhRmRiRnRwRxR}R~RRRR^RRRRRRRRRjRRlR`RZR{RRIRKR"RbRRGRBRkRCR/t classmethodR(((s0/usr/lib/fence-agents/bundled/jmespath/parser.pyR%s                                          RDcBs/eZdZddZdZdZRS(cCs||_||_dS(N(R0RE(R'R0RE((s0/usr/lib/fence-agents/bundled/jmespath/parser.pyR)s cCs(tj|}|j|j|}|S(N(RtTreeInterpretertvisitRE(R'R<toptionst interpretertresult((s0/usr/lib/fence-agents/bundled/jmespath/parser.pytsearch scCs"tj}|j|j}|S(sfRender 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. (RtGraphvizVisitorRRE(R'trenderertcontents((s0/usr/lib/fence-agents/bundled/jmespath/parser.pyt_render_dot_files cCs t|jS(N(treprRE(R'((s0/usr/lib/fence-agents/bundled/jmespath/parser.pyt__repr__sN(RRR)R"RRR(((s0/usr/lib/fence-agents/bundled/jmespath/parser.pyRDs   ( t__doc__RtjmespathRtjmespath.compatRRRRtobjectRRD(((s0/usr/lib/fence-agents/bundled/jmespath/parser.pyts