@@ -46,6 +46,7 @@ class Parser(object):
46
46
'number' : 0 ,
47
47
'current' : 0 ,
48
48
'expref' : 0 ,
49
+ 'colon' : 0 ,
49
50
'pipe' : 1 ,
50
51
'eq' : 2 ,
51
52
'gt' : 2 ,
@@ -165,7 +166,12 @@ def _token_nud_flatten(self, token):
165
166
166
167
def _token_nud_lbracket (self , token ):
167
168
if self ._current_token () in ['number' , 'colon' ]:
168
- return self ._parse_index_expression ()
169
+ right = self ._parse_index_expression ()
170
+ # We could optimize this and remove the identity() node.
171
+ # We don't really need an index_expression node, we can
172
+ # just use emit an index node here if we're not dealing
173
+ # with a slice.
174
+ return self ._project_if_slice (ast .identity (), right )
169
175
elif self ._current_token () == 'star' and \
170
176
self ._lookahead (1 ) == 'rbracket' :
171
177
self ._advance ()
@@ -300,17 +306,29 @@ def _token_led_lbracket(self, left):
300
306
if token ['type' ] in ['number' , 'colon' ]:
301
307
right = self ._parse_index_expression ()
302
308
if left ['type' ] == 'index_expression' :
309
+ # Optimization: if the left node is an index expr,
310
+ # we can avoid creating another node and instead just add
311
+ # the right node as a child of the left.
303
312
left ['children' ].append (right )
304
313
return left
305
314
else :
306
- return ast . index_expression ([ left , right ] )
315
+ return self . _project_if_slice ( left , right )
307
316
else :
308
317
# We have a projection
309
318
self ._match ('star' )
310
319
self ._match ('rbracket' )
311
320
right = self ._parse_projection_rhs (self .BINDING_POWER ['star' ])
312
321
return ast .projection (left , right )
313
322
323
+ def _project_if_slice (self , left , right ):
324
+ index_expr = ast .index_expression ([left , right ])
325
+ if right ['type' ] == 'slice' :
326
+ return ast .projection (
327
+ index_expr ,
328
+ self ._parse_projection_rhs (self .BINDING_POWER ['star' ]))
329
+ else :
330
+ return index_expr
331
+
314
332
def _parse_comparator (self , left , comparator ):
315
333
right = self ._expression (self .BINDING_POWER [comparator ])
316
334
return ast .comparator (comparator , left , right )
0 commit comments