blob: c8a851865c5bb84590b7d8953d686eb247b7f983 [file] [log] [blame]
Greg Steinfd342bf2000-08-03 17:39:13 +00001#
2# Copyright (C) 1997-1998 Greg Stein. All Rights Reserved.
3#
4# This module is provided under a BSD-ish license. See
5# http://www.opensource.org/licenses/bsd-license.html
6# and replace OWNER, ORGANIZATION, and YEAR as appropriate.
7#
8#
9# Written by Greg Stein (gstein@lyra.org)
10# and Bill Tutt (rassilon@lima.mudlib.org)
11# February 1997.
12#
13# Support for ast.Node subclasses written and other revisions by
Jeremy Hylton8612f1c2000-08-04 16:54:54 +000014# Jeremy Hylton (jeremy@beopen.com)
Greg Steinfd342bf2000-08-03 17:39:13 +000015#
16
Jeremy Hyltonfa974a92000-03-06 18:50:48 +000017"""Parse tree transformation module.
18
19Transforms Python source code into an abstract syntax tree (AST)
20defined in the ast module.
21
22The simplest ways to invoke this module are via parse and parseFile.
23parse(buf) -> AST
24parseFile(path) -> AST
25"""
26
Jeremy Hyltonf968e852000-02-04 00:25:23 +000027#
28# The output tree has the following nodes:
29#
30# Source Python line #'s appear at the end of each of all of these nodes
31# If a line # doesn't apply, there will be a None instead.
32#
33# module: doc, node
34# stmt: [ node1, ..., nodeN ]
35# function: name, argnames, defaults, flags, doc, codeNode
36# lambda: argnames, defaults, flags, codeNode
37# classdef: name, bases, doc, codeNode
38# pass:
39# break:
40# continue:
41# for: assignNode, listNode, bodyNode, elseNode
42# while: testNode, bodyNode, elseNode
43# if: [ (testNode, suiteNode), ... ], elseNode
44# exec: expr1Node, expr2Node, expr3Node
45# from: modname, [ name1, ..., nameN ]
46# import: [ name1, ..., nameN ]
47# raise: expr1Node, expr2Node, expr3Node
48# tryfinally: trySuiteNode, finSuiteNode
49# tryexcept: trySuiteNode, [ (exprNode, assgnNode, suiteNode), ... ], elseNode
50# return: valueNode
51# const: value
52# print: [ node1, ..., nodeN ]
53# printnl: [ node1, ..., nodeN ]
54# discard: exprNode
55# assign: [ node1, ..., nodeN ], exprNode
56# ass_tuple: [ node1, ..., nodeN ]
57# ass_list: [ node1, ..., nodeN ]
58# ass_name: name, flags
59# ass_attr: exprNode, attrname, flags
60# list: [ node1, ..., nodeN ]
61# dict: [ (key1, val1), ..., (keyN, valN) ]
62# not: exprNode
63# compare: exprNode, [ (op, node), ..., (op, node) ]
64# name: name
65# global: [ name1, ..., nameN ]
66# backquote: node
67# getattr: exprNode, attrname
68# call_func: node, [ arg1, ..., argN ]
69# keyword: name, exprNode
70# subscript: exprNode, flags, [ sub1, ..., subN ]
71# ellipsis:
72# sliceobj: [ node1, ..., nodeN ]
73# slice: exprNode, flags, lowerNode, upperNode
74# assert: expr1, expr2
75#
76# Compiled as "binary" ops:
77# tuple: [ node1, ..., nodeN ]
78# or: [ node1, ..., nodeN ]
79# and: [ node1, ..., nodeN ]
80# bitor: [ node1, ..., nodeN ]
81# bitxor: [ node1, ..., nodeN ]
82# bitand: [ node1, ..., nodeN ]
83#
84# Operations easily evaluateable on constants:
85# <<: exprNode, shiftNode
86# >>: exprNode, shiftNode
87# +: leftNode, rightNode
88# -: leftNode, rightNode
89# *: leftNode, rightNode
90# /: leftNode, rightNode
91# %: leftNode, rightNode
92# power: leftNode, rightNode
93# unary+: node
94# unary-: node
95# invert: node
96#
97
Jeremy Hyltonf968e852000-02-04 00:25:23 +000098import ast
99import parser
100import symbol
101import token
102import string
103
104import pprint
105
106error = 'walker.error'
107
Jeremy Hylton9605c112000-02-08 18:57:32 +0000108from consts import CO_VARARGS, CO_VARKEYWORDS
109from consts import OP_ASSIGN, OP_DELETE, OP_APPLY
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000110
Jeremy Hyltonfa974a92000-03-06 18:50:48 +0000111def parseFile(path):
112 f = open(path)
113 src = f.read()
114 f.close()
115 return parse(src)
116
117def parse(buf):
118 return Transformer().parsesuite(buf)
119
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000120def asList(nodes):
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000121 l = []
122 for item in nodes:
123 if hasattr(item, "asList"):
124 l.append(item.asList())
125 else:
126 if type(item) is type( (None, None) ):
127 l.append(tuple(asList(item)))
128 elif type(item) is type( [] ):
129 l.append(asList(item))
130 else:
131 l.append(item)
132 return l
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000133
134def Node(*args):
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000135 kind = args[0]
136 if ast.nodes.has_key(kind):
137 try:
138 return apply(ast.nodes[kind], args[1:])
139 except TypeError:
140 print ast.nodes[kind], len(args), args
141 raise
142 else:
143 raise error, "Can't find appropriate Node type."
144 #return apply(ast.Node, args)
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000145
146class Transformer:
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000147 """Utility object for transforming Python parse trees.
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000148
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000149 Exposes the following methods:
150 tree = transform(ast_tree)
151 tree = parsesuite(text)
152 tree = parseexpr(text)
153 tree = parsefile(fileob | filename)
154 """
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000155
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000156 def __init__(self):
157 self._dispatch = { }
158 for value, name in symbol.sym_name.items():
159 if hasattr(self, name):
160 self._dispatch[value] = getattr(self, name)
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000161
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000162 def transform(self, tree):
163 """Transform an AST into a modified parse tree."""
164 if type(tree) != type(()) and type(tree) != type([]):
165 tree = parser.ast2tuple(tree,1)
166 return self.compile_node(tree)
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000167
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000168 def parsesuite(self, text):
169 """Return a modified parse tree for the given suite text."""
170 # Hack for handling non-native line endings on non-DOS like OSs.
171 text = string.replace(text, '\x0d', '')
172 return self.transform(parser.suite(text))
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000173
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000174 def parseexpr(self, text):
175 """Return a modified parse tree for the given expression text."""
176 return self.transform(parser.expr(text))
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000177
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000178 def parsefile(self, file):
179 """Return a modified parse tree for the contents of the given file."""
180 if type(file) == type(''):
181 file = open(file)
182 return self.parsesuite(file.read())
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000183
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000184 # --------------------------------------------------------------
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000185 #
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000186 # PRIVATE METHODS
187 #
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000188
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000189 def compile_node(self, node):
190 ### emit a line-number node?
191 n = node[0]
192 if n == symbol.single_input:
193 return self.single_input(node[1:])
194 if n == symbol.file_input:
195 return self.file_input(node[1:])
196 if n == symbol.eval_input:
197 return self.eval_input(node[1:])
198 if n == symbol.lambdef:
199 return self.lambdef(node[1:])
200 if n == symbol.funcdef:
201 return self.funcdef(node[1:])
202 if n == symbol.classdef:
203 return self.classdef(node[1:])
204
205 raise error, ('unexpected node type', n)
206
207 def single_input(self, node):
208 ### do we want to do anything about being "interactive" ?
209
210 # NEWLINE | simple_stmt | compound_stmt NEWLINE
211 n = node[0][0]
212 if n != token.NEWLINE:
213 return self.com_stmt(node[0])
214
215 return Node('pass')
216
217 def file_input(self, nodelist):
218 doc = self.get_docstring(nodelist, symbol.file_input)
219 stmts = [ ]
220 for node in nodelist:
221 if node[0] != token.ENDMARKER and node[0] != token.NEWLINE:
222 self.com_append_stmt(stmts, node)
223 return Node('module', doc, Node('stmt', stmts))
224
225 def eval_input(self, nodelist):
226 # from the built-in function input()
227 ### is this sufficient?
228 return self.com_node(nodelist[0])
229
230 def funcdef(self, nodelist):
231 # funcdef: 'def' NAME parameters ':' suite
232 # parameters: '(' [varargslist] ')'
233
234 lineno = nodelist[1][2]
235 name = nodelist[1][1]
236 args = nodelist[2][2]
237
238 if args[0] == symbol.varargslist:
239 names, defaults, flags = self.com_arglist(args[1:])
240 else:
241 names = defaults = ()
242 flags = 0
243 doc = self.get_docstring(nodelist[4])
244
245 # code for function
246 code = self.com_node(nodelist[4])
247
248 n = Node('function', name, names, defaults, flags, doc, code)
249 n.lineno = lineno
250 return n
251
252 def lambdef(self, nodelist):
253 # lambdef: 'lambda' [varargslist] ':' test
254 if nodelist[2][0] == symbol.varargslist:
255 names, defaults, flags = self.com_arglist(nodelist[2][1:])
256 else:
257 names = defaults = ()
258 flags = 0
259
260 # code for lambda
261 code = self.com_node(nodelist[-1])
262
263 n = Node('lambda', names, defaults, flags, code)
264 n.lineno = nodelist[1][2]
265 return n
266
267 def classdef(self, nodelist):
268 # classdef: 'class' NAME ['(' testlist ')'] ':' suite
269
270 name = nodelist[1][1]
271 doc = self.get_docstring(nodelist[-1])
272 if nodelist[2][0] == token.COLON:
273 bases = []
274 else:
275 bases = self.com_bases(nodelist[3])
276
277 # code for class
278 code = self.com_node(nodelist[-1])
279
280 n = Node('class', name, bases, doc, code)
281 n.lineno = nodelist[1][2]
282 return n
283
284 def stmt(self, nodelist):
285 return self.com_stmt(nodelist[0])
286
287 small_stmt = stmt
288 flow_stmt = stmt
289 compound_stmt = stmt
290
291 def simple_stmt(self, nodelist):
292 # small_stmt (';' small_stmt)* [';'] NEWLINE
293 stmts = [ ]
294 for i in range(0, len(nodelist), 2):
295 self.com_append_stmt(stmts, nodelist[i])
296 return Node('stmt', stmts)
297
298 def parameters(self, nodelist):
299 raise error
300
301 def varargslist(self, nodelist):
302 raise error
303
304 def fpdef(self, nodelist):
305 raise error
306
307 def fplist(self, nodelist):
308 raise error
309
310 def dotted_name(self, nodelist):
311 raise error
312
313 def comp_op(self, nodelist):
314 raise error
315
316 def trailer(self, nodelist):
317 raise error
318
319 def sliceop(self, nodelist):
320 raise error
321
322 def argument(self, nodelist):
323 raise error
324
325 # --------------------------------------------------------------
326 #
327 # STATEMENT NODES (invoked by com_node())
328 #
329
330 def expr_stmt(self, nodelist):
331 # testlist ('=' testlist)*
332 exprNode = self.com_node(nodelist[-1])
333 if len(nodelist) == 1:
334 return Node('discard', exprNode)
335 nodes = [ ]
336 for i in range(0, len(nodelist) - 2, 2):
337 nodes.append(self.com_assign(nodelist[i], OP_ASSIGN))
338 n = Node('assign', nodes, exprNode)
339 n.lineno = nodelist[1][2]
340 return n
341
342 def print_stmt(self, nodelist):
343 # print: (test ',')* [test]
344 items = [ ]
345 for i in range(1, len(nodelist), 2):
346 items.append(self.com_node(nodelist[i]))
347 if nodelist[-1][0] == token.COMMA:
348 n = Node('print', items)
349 n.lineno = nodelist[0][2]
350 return n
351 n = Node('printnl', items)
352 n.lineno = nodelist[0][2]
353 return n
354
355 def del_stmt(self, nodelist):
356 return self.com_assign(nodelist[1], OP_DELETE)
357
358 def pass_stmt(self, nodelist):
359 # pass:
360 n = Node('pass')
361 n.lineno = nodelist[0][2]
362 return n
363
364 def break_stmt(self, nodelist):
365 # break:
366 n = Node('break')
367 n.lineno = nodelist[0][2]
368 return n
369
370 def continue_stmt(self, nodelist):
371 # continue
372 n = Node('continue')
373 n.lineno = nodelist[0][2]
374 return n
375
376 def return_stmt(self, nodelist):
377 # return: [testlist]
378 if len(nodelist) < 2:
379 n = Node('return', Node('const', None))
380 n.lineno = nodelist[0][2]
381 return n
382 n = Node('return', self.com_node(nodelist[1]))
383 n.lineno = nodelist[0][2]
384 return n
385
386 def raise_stmt(self, nodelist):
387 # raise: [test [',' test [',' test]]]
388 if len(nodelist) > 5:
389 expr3 = self.com_node(nodelist[5])
390 else:
391 expr3 = None
392 if len(nodelist) > 3:
393 expr2 = self.com_node(nodelist[3])
394 else:
395 expr2 = None
396 if len(nodelist) > 1:
397 expr1 = self.com_node(nodelist[1])
398 else:
399 expr1 = None
400 n = Node('raise', expr1, expr2, expr3)
401 n.lineno = nodelist[0][2]
402 return n
403
404 def import_stmt(self, nodelist):
405 # import_stmt: 'import' dotted_as_name (',' dotted_as_name)* |
406 # from: 'from' dotted_name 'import'
407 # ('*' | import_as_name (',' import_as_name)*)
408 names = []
409 is_as = 0
410 if nodelist[0][1] == 'from':
411 for i in range(3, len(nodelist), 2):
412 names.append(self.com_import_as_name(nodelist[i][1]))
413 n = Node('from', self.com_dotted_name(nodelist[1]), names)
414 n.lineno = nodelist[0][2]
415 return n
416
417 for i in range(1, len(nodelist), 2):
418 names.append(self.com_dotted_as_name(nodelist[i]))
419 n = Node('import', names)
420 n.lineno = nodelist[0][2]
421 return n
422
423 def global_stmt(self, nodelist):
424 # global: NAME (',' NAME)*
425 names = [ ]
426 for i in range(1, len(nodelist), 2):
427 names.append(nodelist[i][1])
428 n = Node('global', names)
429 n.lineno = nodelist[0][2]
430 return n
431
432 def exec_stmt(self, nodelist):
433 # exec_stmt: 'exec' expr ['in' expr [',' expr]]
434 expr1 = self.com_node(nodelist[1])
435 if len(nodelist) >= 4:
436 expr2 = self.com_node(nodelist[3])
437 if len(nodelist) >= 6:
438 expr3 = self.com_node(nodelist[5])
439 else:
440 expr3 = None
441 else:
442 expr2 = expr3 = None
443
444 n = Node('exec', expr1, expr2, expr3)
445 n.lineno = nodelist[0][2]
446 return n
447
448 def assert_stmt(self, nodelist):
449 # 'assert': test, [',' test]
450 expr1 = self.com_node(nodelist[1])
451 if (len(nodelist) == 4):
452 expr2 = self.com_node(nodelist[3])
453 else:
454 expr2 = Node('name', 'None')
455 n = Node('assert', expr1, expr2)
456 n.lineno = nodelist[0][2]
457 return n
458
459 def if_stmt(self, nodelist):
460 # if: test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
461 tests = [ ]
462 for i in range(0, len(nodelist) - 3, 4):
463 testNode = self.com_node(nodelist[i + 1])
464 suiteNode = self.com_node(nodelist[i + 3])
465 tests.append((testNode, suiteNode))
466
467 if len(nodelist) % 4 == 3:
468 elseNode = self.com_node(nodelist[-1])
469## elseNode.lineno = nodelist[-1][1][2]
470 else:
471 elseNode = None
472 n = Node('if', tests, elseNode)
473 n.lineno = nodelist[0][2]
474 return n
475
476 def while_stmt(self, nodelist):
477 # 'while' test ':' suite ['else' ':' suite]
478
479 testNode = self.com_node(nodelist[1])
480 bodyNode = self.com_node(nodelist[3])
481
482 if len(nodelist) > 4:
483 elseNode = self.com_node(nodelist[6])
484 else:
485 elseNode = None
486
487 n = Node('while', testNode, bodyNode, elseNode)
488 n.lineno = nodelist[0][2]
489 return n
490
491 def for_stmt(self, nodelist):
492 # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite]
493
494 assignNode = self.com_assign(nodelist[1], OP_ASSIGN)
495 listNode = self.com_node(nodelist[3])
496 bodyNode = self.com_node(nodelist[5])
497
498 if len(nodelist) > 8:
499 elseNode = self.com_node(nodelist[8])
500 else:
501 elseNode = None
502
503 n = Node('for', assignNode, listNode, bodyNode, elseNode)
504 n.lineno = nodelist[0][2]
505 return n
506
507 def try_stmt(self, nodelist):
508 # 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
509 # | 'try' ':' suite 'finally' ':' suite
510 if nodelist[3][0] != symbol.except_clause:
511 return self.com_try_finally(nodelist)
512
513 return self.com_try_except(nodelist)
514
515 def suite(self, nodelist):
516 # simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT
517 if len(nodelist) == 1:
518 return self.com_stmt(nodelist[0])
519
520 stmts = [ ]
521 for node in nodelist:
522 if node[0] == symbol.stmt:
523 self.com_append_stmt(stmts, node)
524 return Node('stmt', stmts)
525
526 # --------------------------------------------------------------
527 #
528 # EXPRESSION NODES (invoked by com_node())
529 #
530
531 def testlist(self, nodelist):
532 # testlist: expr (',' expr)* [',']
533 # exprlist: expr (',' expr)* [',']
534 return self.com_binary('tuple', nodelist)
535
536 exprlist = testlist
537
538 def test(self, nodelist):
539 # and_test ('or' and_test)* | lambdef
540 if len(nodelist) == 1 and nodelist[0][0] == symbol.lambdef:
541 return self.lambdef(nodelist[0])
542 return self.com_binary('or', nodelist)
543
544 def and_test(self, nodelist):
545 # not_test ('and' not_test)*
546 return self.com_binary('and', nodelist)
547
548 def not_test(self, nodelist):
549 # 'not' not_test | comparison
550 result = self.com_node(nodelist[-1])
551 if len(nodelist) == 2:
552 n = Node('not', result)
553 n.lineno = nodelist[0][2]
554 return n
555 return result
556
557 def comparison(self, nodelist):
558 # comparison: expr (comp_op expr)*
559 node = self.com_node(nodelist[0])
560 if len(nodelist) == 1:
561 return node
562
563 results = [ ]
564 for i in range(2, len(nodelist), 2):
565 nl = nodelist[i-1]
566
567 # comp_op: '<' | '>' | '=' | '>=' | '<=' | '<>' | '!=' | '=='
568 # | 'in' | 'not' 'in' | 'is' | 'is' 'not'
569 n = nl[1]
570 if n[0] == token.NAME:
571 type = n[1]
572 if len(nl) == 3:
573 if type == 'not':
574 type = 'not in'
575 else:
576 type = 'is not'
577 else:
578 type = _cmp_types[n[0]]
579
580 lineno = nl[1][2]
581 results.append((type, self.com_node(nodelist[i])))
582
583 # we need a special "compare" node so that we can distinguish
584 # 3 < x < 5 from (3 < x) < 5
585 # the two have very different semantics and results (note that the
586 # latter form is always true)
587
588 n = Node('compare', node, results)
589 n.lineno = lineno
590 return n
591
592 def expr(self, nodelist):
593 # xor_expr ('|' xor_expr)*
594 return self.com_binary('bitor', nodelist)
595
596 def xor_expr(self, nodelist):
597 # xor_expr ('^' xor_expr)*
598 return self.com_binary('bitxor', nodelist)
599
600 def and_expr(self, nodelist):
601 # xor_expr ('&' xor_expr)*
602 return self.com_binary('bitand', nodelist)
603
604 def shift_expr(self, nodelist):
605 # shift_expr ('<<'|'>>' shift_expr)*
606 node = self.com_node(nodelist[0])
607 for i in range(2, len(nodelist), 2):
608 right = self.com_node(nodelist[i])
609 if nodelist[i-1][0] == token.LEFTSHIFT:
610 node = Node('<<', [node, right])
611 node.lineno = nodelist[1][2]
612 else:
613 node = Node('>>', [node, right])
614 node.lineno = nodelist[1][2]
615 return node
616
617 def arith_expr(self, nodelist):
618 node = self.com_node(nodelist[0])
619 for i in range(2, len(nodelist), 2):
620 right = self.com_node(nodelist[i])
621 if nodelist[i-1][0] == token.PLUS:
622 node = Node('+', [node, right])
623 node.lineno = nodelist[1][2]
624 else:
625 node = Node('-', [node, right])
626 node.lineno = nodelist[1][2]
627 return node
628
629 def term(self, nodelist):
630 node = self.com_node(nodelist[0])
631 for i in range(2, len(nodelist), 2):
632 right = self.com_node(nodelist[i])
633 if nodelist[i-1][0] == token.STAR:
634 node = Node('*', [node, right])
635 node.lineno = nodelist[1][2]
636 elif nodelist[i-1][0] == token.SLASH:
637 node = Node('/', [node, right])
638 node.lineno = nodelist[1][2]
639 else:
640 node = Node('%', [node, right])
641 node.lineno = nodelist[1][2]
642 return node
643
644 def factor(self, nodelist):
645 t = nodelist[0][0]
646 node = self.com_node(nodelist[-1])
647 if t == token.PLUS:
648 node = Node('unary+', node)
649 node.lineno = nodelist[0][2]
650 elif t == token.MINUS:
651 node = Node('unary-', node)
652 node.lineno = nodelist[0][2]
653 elif t == token.TILDE:
654 node = Node('invert', node)
655 node.lineno = nodelist[0][2]
656 return node
657
658 def power(self, nodelist):
659 # power: atom trailer* ('**' factor)*
660 node = self.com_node(nodelist[0])
661 for i in range(1, len(nodelist)):
662 if nodelist[i][0] == token.DOUBLESTAR:
663 n = Node('power', [node, self.com_node(nodelist[i+1])])
664 n.lineno = nodelist[i][2]
665 return n
666
667 node = self.com_apply_trailer(node, nodelist[i])
668
669 return node
670
671 def atom(self, nodelist):
672 t = nodelist[0][0]
673 if t == token.LPAR:
674 if nodelist[1][0] == token.RPAR:
675 n = Node('tuple', ())
676 n.lineno = nodelist[0][2]
677 return n
678 return self.com_node(nodelist[1])
679
680 if t == token.LSQB:
681 if nodelist[1][0] == token.RSQB:
682 n = Node('list', ())
683 n.lineno = nodelist[0][2]
684 return n
685 return self.com_list_constructor(nodelist[1])
686
687 if t == token.LBRACE:
688 if nodelist[1][0] == token.RBRACE:
689 return Node('dict', ())
690 return self.com_dictmaker(nodelist[1])
691
692 if t == token.BACKQUOTE:
693 n = Node('backquote', self.com_node(nodelist[1]))
694 n.lineno = nodelist[0][2]
695 return n
696
697 if t == token.NUMBER:
698 ### need to verify this matches compile.c
699 k = eval(nodelist[0][1])
700 n = Node('const', k)
701 n.lineno = nodelist[0][2]
702 return n
703
704 if t == token.STRING:
705 ### need to verify this matches compile.c
706 k = ''
707 for node in nodelist:
708 k = k + eval(node[1])
709 n = Node('const', k)
710 n.lineno = nodelist[0][2]
711 return n
712
713 if t == token.NAME:
714 ### any processing to do?
715 n = Node('name', nodelist[0][1])
716 n.lineno = nodelist[0][2]
717 return n
718
719 raise error, "unknown node type"
720
721 # --------------------------------------------------------------
722 #
723 # INTERNAL PARSING UTILITIES
724 #
725
726 def com_node(self, node):
727 # Note: compile.c has handling in com_node for del_stmt, pass_stmt,
728 # break_stmt, stmt, small_stmt, flow_stmt, simple_stmt,
729 # and compound_stmt.
730 # We'll just dispatch them.
731
732 #
733 # A ';' at the end of a line can make a NEWLINE token appear here,
734 # Render it harmless. (genc discards ('discard', ('const', xxxx)) Nodes)
735 #
736 if node[0] == token.NEWLINE:
737 return Node('discard', Node('const', None))
738
739 if node[0] not in _legal_node_types:
740 raise error, 'illegal node passed to com_node: %s' % node[0]
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000741
Jeremy Hylton20516082000-09-01 20:33:26 +0000742# print "dispatch", self._dispatch[node[0]].__name__, node
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000743 return self._dispatch[node[0]](node[1:])
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000744
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000745 def com_arglist(self, nodelist):
746 # varargslist:
747 # (fpdef ['=' test] ',')* ('*' NAME [',' ('**'|'*' '*') NAME]
748 # | fpdef ['=' test] (',' fpdef ['=' test])* [',']
749 # | ('**'|'*' '*') NAME)
750 # fpdef: NAME | '(' fplist ')'
751 # fplist: fpdef (',' fpdef)* [',']
752 names = [ ]
753 defaults = [ ]
754 flags = 0
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000755
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000756 i = 0
757 while i < len(nodelist):
758 node = nodelist[i]
759 if node[0] == token.STAR or node[0] == token.DOUBLESTAR:
760 if node[0] == token.STAR:
761 node = nodelist[i+1]
762 if node[0] == token.NAME:
763 names.append(node[1])
764 flags = flags | CO_VARARGS
765 i = i + 3
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000766
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000767 if i < len(nodelist):
768 # should be DOUBLESTAR or STAR STAR
769 if nodelist[i][0] == token.DOUBLESTAR:
770 node = nodelist[i+1]
771 else:
772 node = nodelist[i+2]
773 names.append(node[1])
774 flags = flags | CO_VARKEYWORDS
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000775
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000776 break
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000777
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000778 # fpdef: NAME | '(' fplist ')'
779 names.append(self.com_fpdef(node))
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000780
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000781 i = i + 1
782 if i >= len(nodelist):
783 break
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000784
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000785 if nodelist[i][0] == token.EQUAL:
786 defaults.append(self.com_node(nodelist[i + 1]))
787 i = i + 2
788 elif len(defaults):
789 # Treat "(a=1, b)" as "(a=1, b=None)"
790 defaults.append(Node('const', None))
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000791
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000792 i = i + 1
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000793
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000794 return names, defaults, flags
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000795
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000796 def com_fpdef(self, node):
797 # fpdef: NAME | '(' fplist ')'
798 if node[1][0] == token.LPAR:
799 return self.com_fplist(node[2])
800 return node[1][1]
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000801
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000802 def com_fplist(self, node):
803 # fplist: fpdef (',' fpdef)* [',']
804 if len(node) == 2:
805 return self.com_fpdef(node[1])
806 list = [ ]
807 for i in range(1, len(node), 2):
808 list.append(self.com_fpdef(node[i]))
809 return tuple(list)
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000810
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000811 def com_dotted_name(self, node):
812 # String together the dotted names and return the string
813 name = ""
814 for n in node:
815 if type(n) == type(()) and n[0] == 1:
816 name = name + n[1] + '.'
817 return name[:-1]
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000818
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000819 def com_dotted_as_name(self, node):
820 dot = self.com_dotted_name(node[1])
821 if len(node) == 2:
822 return dot, None
823 assert node[2][1] == 'as'
824 assert node[3][0] == token.NAME
825 return dot, node[3][1]
Jeremy Hylton20516082000-09-01 20:33:26 +0000826
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000827 def com_import_as_name(self, node):
Jeremy Hylton4e1be722000-10-12 20:23:23 +0000828 if node == '*':
829 return '*', None
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000830 if node[0] == token.NAME:
831 return node[1], None
832 assert len(node) == 4
833 assert node[2][1] == 'as'
834 assert node[3][0] == token.NAME
835 return node[1][1], node[3][1]
Jeremy Hylton20516082000-09-01 20:33:26 +0000836
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000837 def com_bases(self, node):
838 bases = [ ]
839 for i in range(1, len(node), 2):
840 bases.append(self.com_node(node[i]))
841 return bases
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000842
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000843 def com_try_finally(self, nodelist):
844 # try_fin_stmt: "try" ":" suite "finally" ":" suite
845 n = Node('tryfinally', self.com_node(nodelist[2]), self.com_node(nodelist[5]))
846 n.lineno = nodelist[0][2]
847 return n
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000848
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000849 def com_try_except(self, nodelist):
850 # try_except: 'try' ':' suite (except_clause ':' suite)* ['else' suite]
851 #tryexcept: [TryNode, [except_clauses], elseNode)]
852 stmt = self.com_node(nodelist[2])
853 clauses = []
854 elseNode = None
855 for i in range(3, len(nodelist), 3):
856 node = nodelist[i]
857 if node[0] == symbol.except_clause:
858 # except_clause: 'except' [expr [',' expr]] */
859 if len(node) > 2:
860 expr1 = self.com_node(node[2])
861 if len(node) > 4:
862 expr2 = self.com_assign(node[4], OP_ASSIGN)
863 else:
864 expr2 = None
865 else:
866 expr1 = expr2 = None
867 clauses.append((expr1, expr2, self.com_node(nodelist[i+2])))
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000868
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000869 if node[0] == token.NAME:
870 elseNode = self.com_node(nodelist[i+2])
871 n = Node('tryexcept', self.com_node(nodelist[2]), clauses, elseNode)
872 n.lineno = nodelist[0][2]
873 return n
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000874
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000875 def com_assign(self, node, assigning):
876 # return a node suitable for use as an "lvalue"
877 # loop to avoid trivial recursion
878 while 1:
879 t = node[0]
880 if t == symbol.exprlist or t == symbol.testlist:
881 if len(node) > 2:
882 return self.com_assign_tuple(node, assigning)
883 node = node[1]
884 elif t in _assign_types:
885 if len(node) > 2:
886 raise SyntaxError, "can't assign to operator"
887 node = node[1]
888 elif t == symbol.power:
889 if node[1][0] != symbol.atom:
890 raise SyntaxError, "can't assign to operator"
891 if len(node) > 2:
892 primary = self.com_node(node[1])
893 for i in range(2, len(node)-1):
894 ch = node[i]
895 if ch[0] == token.DOUBLESTAR:
896 raise SyntaxError, "can't assign to operator"
897 primary = self.com_apply_trailer(primary, ch)
898 return self.com_assign_trailer(primary, node[-1], assigning)
899 node = node[1]
900 elif t == symbol.atom:
901 t = node[1][0]
902 if t == token.LPAR:
903 node = node[2]
904 if node[0] == token.RPAR:
905 raise SyntaxError, "can't assign to ()"
906 elif t == token.LSQB:
907 node = node[2]
908 if node[0] == token.RSQB:
909 raise SyntaxError, "can't assign to []"
910 return self.com_assign_list(node, assigning)
911 elif t == token.NAME:
912 return self.com_assign_name(node[1], assigning)
913 else:
914 raise SyntaxError, "can't assign to literal"
915 else:
916 raise SyntaxError, "bad assignment"
917
918 def com_assign_tuple(self, node, assigning):
919 assigns = [ ]
920 for i in range(1, len(node), 2):
921 assigns.append(self.com_assign(node[i], assigning))
922 return Node('ass_tuple', assigns)
923
924 def com_assign_list(self, node, assigning):
925 assigns = [ ]
926 for i in range(1, len(node), 2):
927 assigns.append(self.com_assign(node[i], assigning))
928 return Node('ass_list', assigns)
929
930 def com_assign_name(self, node, assigning):
931 n = Node('ass_name', node[1], assigning)
932 n.lineno = node[2]
933 return n
934
935 def com_assign_trailer(self, primary, node, assigning):
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000936 t = node[1][0]
937 if t == token.LPAR:
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000938 raise SyntaxError, "can't assign to function call"
939 if t == token.DOT:
940 return self.com_assign_attr(primary, node[2], assigning)
941 if t == token.LSQB:
942 return self.com_subscriptlist(primary, node[2], assigning)
943 raise SyntaxError, "unknown trailer type: %s" % t
944
945 def com_assign_attr(self, primary, node, assigning):
946 return Node('ass_attr', primary, node[1], assigning)
947
948 def com_binary(self, type, nodelist):
949 "Compile 'NODE (OP NODE)*' into (type, [ node1, ..., nodeN ])."
950 if len(nodelist) == 1:
951 return self.com_node(nodelist[0])
952 items = [ ]
953 for i in range(0, len(nodelist), 2):
954 items.append(self.com_node(nodelist[i]))
955 return Node(type, items)
956
957 def com_stmt(self, node):
958 #pprint.pprint(node)
959 result = self.com_node(node)
960 try:
961 result[0]
962 except:
963 print node[0]
964 if result[0] == 'stmt':
965 return result
966 return Node('stmt', [ result ])
967
968 def com_append_stmt(self, stmts, node):
969 result = self.com_node(node)
970 try:
971 result[0]
972 except:
973 print node
974 if result[0] == 'stmt':
975 stmts[len(stmts):] = result[1]
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000976 else:
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000977 stmts.append(result)
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000978
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000979 def com_list_constructor(self, nodelist):
980 values = [ ]
981 for i in range(1, len(nodelist), 2):
982 values.append(self.com_node(nodelist[i]))
983 return Node('list', values)
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000984
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000985 def com_dictmaker(self, nodelist):
986 # dictmaker: test ':' test (',' test ':' value)* [',']
987 items = [ ]
988 for i in range(1, len(nodelist), 4):
989 items.append((self.com_node(nodelist[i]), self.com_node(nodelist[i+2])))
990 return Node('dict', items)
Jeremy Hyltonf968e852000-02-04 00:25:23 +0000991
Jeremy Hylton572bdce2000-09-20 02:47:28 +0000992 def com_apply_trailer(self, primaryNode, nodelist):
993 t = nodelist[1][0]
994 if t == token.LPAR:
995 return self.com_call_function(primaryNode, nodelist[2])
996 if t == token.DOT:
997 return self.com_select_member(primaryNode, nodelist[2])
998 if t == token.LSQB:
999 return self.com_subscriptlist(primaryNode, nodelist[2], OP_APPLY)
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001000
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001001 raise SyntaxError, 'unknown node type: %s' % t
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001002
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001003 def com_select_member(self, primaryNode, nodelist):
1004 if nodelist[0] != token.NAME:
1005 raise SyntaxError, "member must be a name"
1006 n = Node('getattr', primaryNode, nodelist[1])
1007 n.lineno = nodelist[2]
1008 return n
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001009
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001010 def com_call_function(self, primaryNode, nodelist):
1011 if nodelist[0] == token.RPAR:
1012 return Node('call_func', primaryNode, [ ])
1013 args = [ ]
1014 kw = 0
1015 len_nodelist = len(nodelist)
1016 for i in range(1, len_nodelist, 2):
1017 node = nodelist[i]
1018 if node[0] == token.STAR or node[0] == token.DOUBLESTAR:
1019 break
1020 kw, result = self.com_argument(node, kw)
1021 args.append(result)
Jeremy Hyltonbe317e62000-05-02 22:32:59 +00001022 else:
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001023 i = i + 1 # No broken by star arg, so skip the last one we processed.
1024 if i < len_nodelist and nodelist[i][0] == token.COMMA:
1025 # need to accept an application that looks like "f(a, b,)"
1026 i = i + 1
1027 star_node = dstar_node = None
1028 while i < len_nodelist:
1029 tok = nodelist[i]
1030 ch = nodelist[i+1]
1031 i = i + 3
1032 if tok[0]==token.STAR:
1033 if star_node is not None:
1034 raise SyntaxError, 'already have the varargs indentifier'
1035 star_node = self.com_node(ch)
1036 elif tok[0]==token.DOUBLESTAR:
1037 if dstar_node is not None:
1038 raise SyntaxError, 'already have the kwargs indentifier'
1039 dstar_node = self.com_node(ch)
1040 else:
1041 raise SyntaxError, 'unknown node type: %s' % tok
Jeremy Hyltonbe317e62000-05-02 22:32:59 +00001042
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001043 return Node('call_func', primaryNode, args, star_node, dstar_node)
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001044
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001045 def com_argument(self, nodelist, kw):
1046 if len(nodelist) == 2:
1047 if kw:
1048 raise SyntaxError, "non-keyword arg after keyword arg"
1049 return 0, self.com_node(nodelist[1])
1050 result = self.com_node(nodelist[3])
1051 n = nodelist[1]
1052 while len(n) == 2 and n[0] != token.NAME:
1053 n = n[1]
1054 if n[0] != token.NAME:
1055 raise SyntaxError, "keyword can't be an expression (%s)"%n[0]
1056 node = Node('keyword', n[1], result)
1057 node.lineno = n[2]
1058 return 1, node
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001059
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001060 def com_subscriptlist(self, primary, nodelist, assigning):
1061 # slicing: simple_slicing | extended_slicing
1062 # simple_slicing: primary "[" short_slice "]"
1063 # extended_slicing: primary "[" slice_list "]"
1064 # slice_list: slice_item ("," slice_item)* [","]
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001065
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001066 # backwards compat slice for '[i:j]'
1067 if len(nodelist) == 2:
1068 sub = nodelist[1]
1069 if (sub[1][0] == token.COLON or \
1070 (len(sub) > 2 and sub[2][0] == token.COLON)) and \
1071 sub[-1][0] != symbol.sliceop:
1072 return self.com_slice(primary, sub, assigning)
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001073
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001074 subscripts = [ ]
1075 for i in range(1, len(nodelist), 2):
1076 subscripts.append(self.com_subscript(nodelist[i]))
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001077
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001078 return Node('subscript', primary, assigning, subscripts)
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001079
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001080 def com_subscript(self, node):
1081 # slice_item: expression | proper_slice | ellipsis
1082 ch = node[1]
1083 if ch[0] == token.DOT and node[2][0] == token.DOT:
1084 return Node('ellipsis')
1085 if ch[0] == token.COLON or len(node) > 2:
1086 return self.com_sliceobj(node)
1087 return self.com_node(ch)
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001088
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001089 def com_sliceobj(self, node):
1090 # proper_slice: short_slice | long_slice
1091 # short_slice: [lower_bound] ":" [upper_bound]
1092 # long_slice: short_slice ":" [stride]
1093 # lower_bound: expression
1094 # upper_bound: expression
1095 # stride: expression
1096 #
1097 # Note: a stride may be further slicing...
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001098
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001099 items = [ ]
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001100
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001101 if node[1][0] == token.COLON:
1102 items.append(Node('const', None))
1103 i = 2
1104 else:
1105 items.append(self.com_node(node[1]))
1106 # i == 2 is a COLON
1107 i = 3
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001108
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001109 if i < len(node) and node[i][0] == symbol.test:
1110 items.append(self.com_node(node[i]))
1111 i = i + 1
1112 else:
1113 items.append(Node('const', None))
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001114
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001115 # a short_slice has been built. look for long_slice now by looking
1116 # for strides...
1117 for j in range(i, len(node)):
1118 ch = node[j]
1119 if len(ch) == 2:
1120 items.append(Node('const', None))
1121 else:
1122 items.append(self.com_node(ch[2]))
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001123
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001124 return Node('sliceobj', items)
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001125
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001126 def com_slice(self, primary, node, assigning):
1127 # short_slice: [lower_bound] ":" [upper_bound]
1128 lower = upper = None
1129 if len(node) == 3:
1130 if node[1][0] == token.COLON:
1131 upper = self.com_node(node[2])
1132 else:
1133 lower = self.com_node(node[1])
1134 elif len(node) == 4:
1135 lower = self.com_node(node[1])
1136 upper = self.com_node(node[3])
1137 return Node('slice', primary, assigning, lower, upper)
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001138
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001139 def get_docstring(self, node, n=None):
1140 if n is None:
1141 n = node[0]
1142 node = node[1:]
1143 if n == symbol.suite:
1144 if len(node) == 1:
1145 return self.get_docstring(node[0])
1146 for sub in node:
1147 if sub[0] == symbol.stmt:
1148 return self.get_docstring(sub)
1149 return None
1150 if n == symbol.file_input:
1151 for sub in node:
1152 if sub[0] == symbol.stmt:
1153 return self.get_docstring(sub)
1154 return None
1155 if n == symbol.atom:
1156 if node[0][0] == token.STRING:
1157 s = ''
1158 for t in node:
1159 s = s + eval(t[1])
1160 return s
1161 return None
1162 if n == symbol.stmt or n == symbol.simple_stmt or n == symbol.small_stmt:
1163 return self.get_docstring(node[0])
1164 if n in _doc_nodes and len(node) == 1:
1165 return self.get_docstring(node[0])
1166 return None
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001167
1168
1169_doc_nodes = [
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001170 symbol.expr_stmt,
1171 symbol.testlist,
1172 symbol.test,
1173 symbol.and_test,
1174 symbol.not_test,
1175 symbol.comparison,
1176 symbol.expr,
1177 symbol.xor_expr,
1178 symbol.and_expr,
1179 symbol.shift_expr,
1180 symbol.arith_expr,
1181 symbol.term,
1182 symbol.factor,
1183 symbol.power,
1184 ]
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001185
1186# comp_op: '<' | '>' | '=' | '>=' | '<=' | '<>' | '!=' | '=='
1187# | 'in' | 'not' 'in' | 'is' | 'is' 'not'
1188_cmp_types = {
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001189 token.LESS : '<',
1190 token.GREATER : '>',
1191 token.EQEQUAL : '==',
1192 token.EQUAL : '==',
1193 token.LESSEQUAL : '<=',
1194 token.GREATEREQUAL : '>=',
1195 token.NOTEQUAL : '!=',
1196 }
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001197
1198_legal_node_types = [
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001199 symbol.funcdef,
1200 symbol.classdef,
1201 symbol.stmt,
1202 symbol.small_stmt,
1203 symbol.flow_stmt,
1204 symbol.simple_stmt,
1205 symbol.compound_stmt,
1206 symbol.expr_stmt,
1207 symbol.print_stmt,
1208 symbol.del_stmt,
1209 symbol.pass_stmt,
1210 symbol.break_stmt,
1211 symbol.continue_stmt,
1212 symbol.return_stmt,
1213 symbol.raise_stmt,
1214 symbol.import_stmt,
1215 symbol.global_stmt,
1216 symbol.exec_stmt,
1217 symbol.assert_stmt,
1218 symbol.if_stmt,
1219 symbol.while_stmt,
1220 symbol.for_stmt,
1221 symbol.try_stmt,
1222 symbol.suite,
1223 symbol.testlist,
1224 symbol.test,
1225 symbol.and_test,
1226 symbol.not_test,
1227 symbol.comparison,
1228 symbol.exprlist,
1229 symbol.expr,
1230 symbol.xor_expr,
1231 symbol.and_expr,
1232 symbol.shift_expr,
1233 symbol.arith_expr,
1234 symbol.term,
1235 symbol.factor,
1236 symbol.power,
1237 symbol.atom,
1238 ]
Jeremy Hyltonf968e852000-02-04 00:25:23 +00001239
1240_assign_types = [
Jeremy Hylton572bdce2000-09-20 02:47:28 +00001241 symbol.test,
1242 symbol.and_test,
1243 symbol.not_test,
1244 symbol.comparison,
1245 symbol.expr,
1246 symbol.xor_expr,
1247 symbol.and_expr,
1248 symbol.shift_expr,
1249 symbol.arith_expr,
1250 symbol.term,
1251 symbol.factor,
1252 ]