@@ -48,21 +48,27 @@ class Parser(object):
4848 'expref' : 0 ,
4949 'colon' : 0 ,
5050 'pipe' : 1 ,
51- 'eq' : 2 ,
52- 'gt' : 2 ,
53- 'lt' : 2 ,
54- 'gte' : 2 ,
55- 'lte' : 2 ,
56- 'ne' : 2 ,
57- 'or' : 5 ,
58- 'flatten' : 6 ,
51+ 'or' : 2 ,
52+ 'and' : 3 ,
53+ 'eq' : 5 ,
54+ 'gt' : 5 ,
55+ 'lt' : 5 ,
56+ 'gte' : 5 ,
57+ 'lte' : 5 ,
58+ 'ne' : 5 ,
59+ 'flatten' : 9 ,
60+ # Everything above stops a projection.
5961 'star' : 20 ,
6062 'filter' : 21 ,
6163 'dot' : 40 ,
64+ 'not' : 45 ,
6265 'lbrace' : 50 ,
6366 'lbracket' : 55 ,
6467 'lparen' : 60 ,
6568 }
69+ # The maximum binding power for a token that can stop
70+ # a projection.
71+ _PROJECTION_STOP = 10
6672 # The _MAX_SIZE most recent expressions are cached in
6773 # _CACHE dict.
6874 _CACHE = {}
@@ -161,12 +167,21 @@ def _token_nud_filter(self, token):
161167 def _token_nud_lbrace (self , token ):
162168 return self ._parse_multi_select_hash ()
163169
170+ def _token_nud_lparen (self , token ):
171+ expression = self ._expression ()
172+ self ._match ('rparen' )
173+ return expression
174+
164175 def _token_nud_flatten (self , token ):
165176 left = ast .flatten (ast .identity ())
166177 right = self ._parse_projection_rhs (
167178 self .BINDING_POWER ['flatten' ])
168179 return ast .projection (left , right )
169180
181+ def _token_nud_not (self , token ):
182+ expr = self ._expression (self .BINDING_POWER ['not' ])
183+ return ast .not_expression (expr )
184+
170185 def _token_nud_lbracket (self , token ):
171186 if self ._current_token () in ['number' , 'colon' ]:
172187 right = self ._parse_index_expression ()
@@ -254,15 +269,15 @@ def _token_led_or(self, left):
254269 right = self ._expression (self .BINDING_POWER ['or' ])
255270 return ast .or_expression (left , right )
256271
272+ def _token_led_and (self , left ):
273+ right = self ._expression (self .BINDING_POWER ['and' ])
274+ return ast .and_expression (left , right )
275+
257276 def _token_led_lparen (self , left ):
258277 name = left ['value' ]
259278 args = []
260279 while not self ._current_token () == 'rparen' :
261- if self ._current_token () == 'current' :
262- expression = ast .current_node ()
263- self ._advance ()
264- else :
265- expression = self ._expression ()
280+ expression = self ._expression ()
266281 if self ._current_token () == 'comma' :
267282 self ._match ('comma' )
268283 args .append (expression )
@@ -370,7 +385,7 @@ def _parse_multi_select_hash(self):
370385
371386 def _parse_projection_rhs (self , binding_power ):
372387 # Parse the right hand side of the projection.
373- if self .BINDING_POWER [self ._current_token ()] < 10 :
388+ if self .BINDING_POWER [self ._current_token ()] < self . _PROJECTION_STOP :
374389 # BP of 10 are all the tokens that stop a projection.
375390 right = ast .identity ()
376391 elif self ._current_token () == 'lbracket' :
0 commit comments