ยปCore Development>Code coverage>Lib/compiler/transformer.py

Python code coverage for Lib/compiler/transformer.py

#countcontent
1n/a"""Parse tree transformation module.
2n/a
3n/aTransforms Python source code into an abstract syntax tree (AST)
4n/adefined in the ast module.
5n/a
6n/aThe simplest ways to invoke this module are via parse and parseFile.
7n/aparse(buf) -> AST
8n/aparseFile(path) -> AST
92"""
10n/a
11n/a# Original version written by Greg Stein (gstein@lyra.org)
12n/a# and Bill Tutt (rassilon@lima.mudlib.org)
13n/a# February 1997.
14n/a#
15n/a# Modifications and improvements for Python 2.0 by Jeremy Hylton and
16n/a# Mark Hammond
17n/a#
18n/a# Some fixes to try to have correct line number on almost all nodes
19n/a# (except Module, Discard and Stmt) added by Sylvain Thenault
20n/a#
21n/a# Portions of this file are:
22n/a# Copyright (C) 1997-1998 Greg Stein. All Rights Reserved.
23n/a#
24n/a# This module is provided under a BSD-ish license. See
25n/a# http://www.opensource.org/licenses/bsd-license.html
26n/a# and replace OWNER, ORGANIZATION, and YEAR as appropriate.
27n/a
282from compiler.ast import *
292import parser
302import symbol
312import token
32n/a
334class WalkerError(StandardError):
342 pass
35n/a
362from compiler.consts import CO_VARARGS, CO_VARKEYWORDS
372from compiler.consts import OP_ASSIGN, OP_DELETE, OP_APPLY
38n/a
392def parseFile(path):
401 f = open(path, "U")
41n/a # XXX The parser API tolerates files without a trailing newline,
42n/a # but not strings without a trailing newline. Always add an extra
43n/a # newline to the file contents, since we're going through the string
44n/a # version of the API.
451 src = f.read() + "\n"
461 f.close()
471 return parse(src)
48n/a
492def parse(buf, mode="exec"):
5038 if mode == "exec" or mode == "single":
5129 return Transformer().parsesuite(buf)
529 elif mode == "eval":
539 return Transformer().parseexpr(buf)
54n/a else:
550 raise ValueError("compile() arg 3 must be"
56n/a " 'exec' or 'eval' or 'single'")
57n/a
582def asList(nodes):
590 l = []
600 for item in nodes:
610 if hasattr(item, "asList"):
620 l.append(item.asList())
63n/a else:
640 if type(item) is type( (None, None) ):
650 l.append(tuple(asList(item)))
660 elif type(item) is type( [] ):
670 l.append(asList(item))
68n/a else:
690 l.append(item)
700 return l
71n/a
722def extractLineNo(ast):
7348570 if not isinstance(ast[1], tuple):
74n/a # get a terminal node
753837 return ast[2]
7644733 for child in ast[1:]:
7744733 if isinstance(child, tuple):
7844733 lineno = extractLineNo(child)
7944733 if lineno is not None:
8044733 return lineno
81n/a
822def Node(*args):
830 kind = args[0]
840 if kind in nodes:
850 try:
860 return nodes[kind](*args[1:])
870 except TypeError:
880 print nodes[kind], len(args), args
890 raise
90n/a else:
910 raise WalkerError, "Can't find appropriate Node type: %s" % str(args)
92n/a #return apply(ast.Node, args)
93n/a
944class Transformer:
95n/a """Utility object for transforming Python parse trees.
96n/a
97n/a Exposes the following methods:
98n/a tree = transform(ast_tree)
99n/a tree = parsesuite(text)
100n/a tree = parseexpr(text)
101n/a tree = parsefile(fileob | filename)
1022 """
103n/a
1042 def __init__(self):
10538 self._dispatch = {}
1063306 for value, name in symbol.sym_name.items():
1073268 if hasattr(self, name):
1082508 self._dispatch[value] = getattr(self, name)
10938 self._dispatch[token.NEWLINE] = self.com_NEWLINE
11038 self._atom_dispatch = {token.LPAR: self.atom_lpar,
11138 token.LSQB: self.atom_lsqb,
11238 token.LBRACE: self.atom_lbrace,
11338 token.BACKQUOTE: self.atom_backquote,
11438 token.NUMBER: self.atom_number,
11538 token.STRING: self.atom_string,
11638 token.NAME: self.atom_name,
117n/a }
11838 self.encoding = None
119n/a
1202 def transform(self, tree):
121n/a """Transform an AST into a modified parse tree."""
12238 if not (isinstance(tree, tuple) or isinstance(tree, list)):
12338 tree = parser.st2tuple(tree, line_info=1)
12438 return self.compile_node(tree)
125n/a
1262 def parsesuite(self, text):
127n/a """Return a modified parse tree for the given suite text."""
12829 return self.transform(parser.suite(text))
129n/a
1302 def parseexpr(self, text):
131n/a """Return a modified parse tree for the given expression text."""
1329 return self.transform(parser.expr(text))
133n/a
1342 def parsefile(self, file):
135n/a """Return a modified parse tree for the contents of the given file."""
1360 if type(file) == type(''):
1370 file = open(file)
1380 return self.parsesuite(file.read())
139n/a
140n/a # --------------------------------------------------------------
141n/a #
142n/a # PRIVATE METHODS
143n/a #
144n/a
1452 def compile_node(self, node):
146n/a ### emit a line-number node?
14738 n = node[0]
148n/a
14938 if n == symbol.encoding_decl:
1500 self.encoding = node[2]
1510 node = node[1]
1520 n = node[0]
153n/a
15438 if n == symbol.single_input:
1550 return self.single_input(node[1:])
15638 if n == symbol.file_input:
15729 return self.file_input(node[1:])
1589 if n == symbol.eval_input:
1599 return self.eval_input(node[1:])
1600 if n == symbol.lambdef:
1610 return self.lambdef(node[1:])
1620 if n == symbol.funcdef:
1630 return self.funcdef(node[1:])
1640 if n == symbol.classdef:
1650 return self.classdef(node[1:])
166n/a
1670 raise WalkerError, ('unexpected node type', n)
168n/a
1692 def single_input(self, node):
170n/a ### do we want to do anything about being "interactive" ?
171n/a
172n/a # NEWLINE | simple_stmt | compound_stmt NEWLINE
1730 n = node[0][0]
1740 if n != token.NEWLINE:
1750 return self.com_stmt(node[0])
176n/a
1770 return Pass()
178n/a
1792 def file_input(self, nodelist):
18029 doc = self.get_docstring(nodelist, symbol.file_input)
18129 if doc is not None:
1825 i = 1
183n/a else:
18424 i = 0
18529 stmts = []
186304 for node in nodelist[i:]:
187278 if node[0] != token.ENDMARKER and node[0] != token.NEWLINE:
188226 self.com_append_stmt(stmts, node)
18926 return Module(doc, Stmt(stmts))
190n/a
1912 def eval_input(self, nodelist):
192n/a # from the built-in function input()
193n/a ### is this sufficient?
1949 return Expression(self.com_node(nodelist[0]))
195n/a
1962 def decorator_name(self, nodelist):
19719 listlen = len(nodelist)
19819 assert listlen >= 1 and listlen % 2 == 1
199n/a
20019 item = self.atom_name(nodelist)
20119 i = 1
20237 while i < listlen:
20318 assert nodelist[i][0] == token.DOT
20418 assert nodelist[i + 1][0] == token.NAME
20518 item = Getattr(item, nodelist[i + 1][1])
20618 i += 2
207n/a
20819 return item
209n/a
2102 def decorator(self, nodelist):
211n/a # '@' dotted_name [ '(' [arglist] ')' ]
21219 assert len(nodelist) in (3, 5, 6)
21319 assert nodelist[0][0] == token.AT
21419 assert nodelist[-1][0] == token.NEWLINE
215n/a
21619 assert nodelist[1][0] == symbol.dotted_name
21719 funcname = self.decorator_name(nodelist[1][1:])
218n/a
21919 if len(nodelist) > 3:
2207 assert nodelist[2][0] == token.LPAR
2217 expr = self.com_call_function(funcname, nodelist[3])
222n/a else:
22312 expr = funcname
224n/a
22519 return expr
226n/a
2272 def decorators(self, nodelist):
228n/a # decorators: decorator ([NEWLINE] decorator)* NEWLINE
22919 items = []
23038 for dec_nodelist in nodelist:
23119 assert dec_nodelist[0] == symbol.decorator
23219 items.append(self.decorator(dec_nodelist[1:]))
23319 return Decorators(items)
234n/a
2352 def decorated(self, nodelist):
23619 assert nodelist[0][0] == symbol.decorators
23719 if nodelist[1][0] == symbol.funcdef:
23819 n = [nodelist[0]] + list(nodelist[1][1:])
23919 return self.funcdef(n)
2400 elif nodelist[1][0] == symbol.classdef:
2410 decorators = self.decorators(nodelist[0][1:])
2420 cls = self.classdef(nodelist[1][1:])
2430 cls.decorators = decorators
2440 return cls
2450 raise WalkerError()
246n/a
2472 def funcdef(self, nodelist):
248n/a # -6 -5 -4 -3 -2 -1
249n/a # funcdef: [decorators] 'def' NAME parameters ':' suite
250n/a # parameters: '(' [varargslist] ')'
251n/a
252649 if len(nodelist) == 6:
25319 assert nodelist[0][0] == symbol.decorators
25419 decorators = self.decorators(nodelist[0][1:])
255n/a else:
256630 assert len(nodelist) == 5
257630 decorators = None
258n/a
259649 lineno = nodelist[-4][2]
260649 name = nodelist[-4][1]
261649 args = nodelist[-3][2]
262n/a
263649 if args[0] == symbol.varargslist:
264615 names, defaults, flags = self.com_arglist(args[1:])
265n/a else:
26634 names = defaults = ()
26734 flags = 0
268648 doc = self.get_docstring(nodelist[-1])
269n/a
270n/a # code for function
271648 code = self.com_node(nodelist[-1])
272n/a
273648 if doc is not None:
27421 assert isinstance(code, Stmt)
27521 assert isinstance(code.nodes[0], Discard)
27621 del code.nodes[0]
277648 return Function(decorators, name, names, defaults, flags, doc, code,
278648 lineno=lineno)
279n/a
2802 def lambdef(self, nodelist):
281n/a # lambdef: 'lambda' [varargslist] ':' test
28218 if nodelist[2][0] == symbol.varargslist:
28317 names, defaults, flags = self.com_arglist(nodelist[2][1:])
284n/a else:
2851 names = defaults = ()
2861 flags = 0
287n/a
288n/a # code for lambda
28918 code = self.com_node(nodelist[-1])
290n/a
29118 return Lambda(names, defaults, flags, code, lineno=nodelist[1][2])
2922 old_lambdef = lambdef
293n/a
2942 def classdef(self, nodelist):
295n/a # classdef: 'class' NAME ['(' [testlist] ')'] ':' suite
296n/a
297395 name = nodelist[1][1]
298395 doc = self.get_docstring(nodelist[-1])
299395 if nodelist[2][0] == token.COLON:
30035 bases = []
301360 elif nodelist[3][0] == token.RPAR:
3021 bases = []
303n/a else:
304359 bases = self.com_bases(nodelist[3])
305n/a
306n/a # code for class
307395 code = self.com_node(nodelist[-1])
308n/a
309395 if doc is not None:
3108 assert isinstance(code, Stmt)
3118 assert isinstance(code.nodes[0], Discard)
3128 del code.nodes[0]
313n/a
314395 return Class(name, bases, doc, code, lineno=nodelist[1][2])
315n/a
3162 def stmt(self, nodelist):
3179851 return self.com_stmt(nodelist[0])
318n/a
3192 small_stmt = stmt
3202 flow_stmt = stmt
3212 compound_stmt = stmt
322n/a
3232 def simple_stmt(self, nodelist):
324n/a # small_stmt (';' small_stmt)* [';'] NEWLINE
3253395 stmts = []
3266793 for i in range(0, len(nodelist), 2):
3273400 self.com_append_stmt(stmts, nodelist[i])
3283393 return Stmt(stmts)
329n/a
3302 def parameters(self, nodelist):
3310 raise WalkerError
332n/a
3332 def varargslist(self, nodelist):
3340 raise WalkerError
335n/a
3362 def fpdef(self, nodelist):
3370 raise WalkerError
338n/a
3392 def fplist(self, nodelist):
3400 raise WalkerError
341n/a
3422 def dotted_name(self, nodelist):
3430 raise WalkerError
344n/a
3452 def comp_op(self, nodelist):
3460 raise WalkerError
347n/a
3482 def trailer(self, nodelist):
3490 raise WalkerError
350n/a
3512 def sliceop(self, nodelist):
3520 raise WalkerError
353n/a
3542 def argument(self, nodelist):
3550 raise WalkerError
356n/a
357n/a # --------------------------------------------------------------
358n/a #
359n/a # STATEMENT NODES (invoked by com_node())
360n/a #
361n/a
3622 def expr_stmt(self, nodelist):
363n/a # augassign testlist | testlist ('=' testlist)*
3642651 en = nodelist[-1]
3652651 exprNode = self.lookup_node(en)(en[1:])
3662649 if len(nodelist) == 1:
3671592 return Discard(exprNode, lineno=exprNode.lineno)
3681057 if nodelist[1][0] == token.EQUAL:
3691038 nodesl = []
3702080 for i in range(0, len(nodelist) - 2, 2):
3711042 nodesl.append(self.com_assign(nodelist[i], OP_ASSIGN))
3721038 return Assign(nodesl, exprNode, lineno=nodelist[1][2])
373n/a else:
37419 lval = self.com_augassign(nodelist[0])
37519 op = self.com_augassign_op(nodelist[1])
37619 return AugAssign(lval, op[1], exprNode, lineno=op[2])
3770 raise WalkerError, "can't get here"
378n/a
3792 def print_stmt(self, nodelist):
380n/a # print ([ test (',' test)* [','] ] | '>>' test [ (',' test)+ [','] ])
38112 items = []
38212 if len(nodelist) == 1:
3830 start = 1
3840 dest = None
38512 elif nodelist[1][0] == token.RIGHTSHIFT:
3865 assert len(nodelist) == 3 \
3875 or nodelist[3][0] == token.COMMA
3885 dest = self.com_node(nodelist[2])
3895 start = 4
390n/a else:
3917 dest = None
3927 start = 1
39327 for i in range(start, len(nodelist), 2):
39415 items.append(self.com_node(nodelist[i]))
39512 if nodelist[-1][0] == token.COMMA:
3960 return Print(items, dest, lineno=nodelist[0][2])
39712 return Printnl(items, dest, lineno=nodelist[0][2])
398n/a
3992 def del_stmt(self, nodelist):
40055 return self.com_assign(nodelist[1], OP_DELETE)
401n/a
4022 def pass_stmt(self, nodelist):
403266 return Pass(lineno=nodelist[0][2])
404n/a
4052 def break_stmt(self, nodelist):
4060 return Break(lineno=nodelist[0][2])
407n/a
4082 def continue_stmt(self, nodelist):
4095 return Continue(lineno=nodelist[0][2])
410n/a
4112 def return_stmt(self, nodelist):
412n/a # return: [testlist]
413281 if len(nodelist) < 2:
4141 return Return(Const(None), lineno=nodelist[0][2])
415280 return Return(self.com_node(nodelist[1]), lineno=nodelist[0][2])
416n/a
4172 def yield_stmt(self, nodelist):
4182 expr = self.com_node(nodelist[0])
4192 return Discard(expr, lineno=expr.lineno)
420n/a
4212 def yield_expr(self, nodelist):
4222 if len(nodelist) > 1:
4231 value = self.com_node(nodelist[1])
424n/a else:
4251 value = Const(None)
4262 return Yield(value, lineno=nodelist[0][2])
427n/a
4282 def raise_stmt(self, nodelist):
429n/a # raise: [test [',' test [',' test]]]
43030 if len(nodelist) > 5:
4310 expr3 = self.com_node(nodelist[5])
432n/a else:
43330 expr3 = None
43430 if len(nodelist) > 3:
43512 expr2 = self.com_node(nodelist[3])
436n/a else:
43718 expr2 = None
43830 if len(nodelist) > 1:
43927 expr1 = self.com_node(nodelist[1])
440n/a else:
4413 expr1 = None
44230 return Raise(expr1, expr2, expr3, lineno=nodelist[0][2])
443n/a
4442 def import_stmt(self, nodelist):
445n/a # import_stmt: import_name | import_from
44669 assert len(nodelist) == 1
44769 return self.com_node(nodelist[0])
448n/a
4492 def import_name(self, nodelist):
450n/a # import_name: 'import' dotted_as_names
45150 return Import(self.com_dotted_as_names(nodelist[1]),
45250 lineno=nodelist[0][2])
453n/a
4542 def import_from(self, nodelist):
455n/a # import_from: 'from' ('.'* dotted_name | '.') 'import' ('*' |
456n/a # '(' import_as_names ')' | import_as_names)
45719 assert nodelist[0][1] == 'from'
45819 idx = 1
45919 while nodelist[idx][1] == '.':
4600 idx += 1
46119 level = idx - 1
46219 if nodelist[idx][0] == symbol.dotted_name:
46319 fromname = self.com_dotted_name(nodelist[idx])
46419 idx += 1
465n/a else:
4660 fromname = ""
46719 assert nodelist[idx][1] == 'import'
46819 if nodelist[idx + 1][0] == token.STAR:
4691 return From(fromname, [('*', None)], level,
4701 lineno=nodelist[0][2])
471n/a else:
47218 node = nodelist[idx + 1 + (nodelist[idx + 1][0] == token.LPAR)]
47318 return From(fromname, self.com_import_as_names(node), level,
47418 lineno=nodelist[0][2])
475n/a
4762 def global_stmt(self, nodelist):
477n/a # global: NAME (',' NAME)*
4788 names = []
47920 for i in range(1, len(nodelist), 2):
48012 names.append(nodelist[i][1])
4818 return Global(names, lineno=nodelist[0][2])
482n/a
4832 def exec_stmt(self, nodelist):
484n/a # exec_stmt: 'exec' expr ['in' expr [',' expr]]
48518 expr1 = self.com_node(nodelist[1])
48618 if len(nodelist) >= 4:
48715 expr2 = self.com_node(nodelist[3])
48815 if len(nodelist) >= 6:
4891 expr3 = self.com_node(nodelist[5])
490n/a else:
49114 expr3 = None
492n/a else:
4933 expr2 = expr3 = None
494n/a
49518 return Exec(expr1, expr2, expr3, lineno=nodelist[0][2])
496n/a
4972 def assert_stmt(self, nodelist):
498n/a # 'assert': test, [',' test]
4993 expr1 = self.com_node(nodelist[1])
5003 if (len(nodelist) == 4):
5011 expr2 = self.com_node(nodelist[3])
502n/a else:
5032 expr2 = None
5043 return Assert(expr1, expr2, lineno=nodelist[0][2])
505n/a
5062 def if_stmt(self, nodelist):
507n/a # if: test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
508125 tests = []
509252 for i in range(0, len(nodelist) - 3, 4):
510127 testNode = self.com_node(nodelist[i + 1])
511127 suiteNode = self.com_node(nodelist[i + 3])
512127 tests.append((testNode, suiteNode))
513n/a
514125 if len(nodelist) % 4 == 3:
51528 elseNode = self.com_node(nodelist[-1])
516n/a## elseNode.lineno = nodelist[-1][1][2]
517n/a else:
51897 elseNode = None
519125 return If(tests, elseNode, lineno=nodelist[0][2])
520n/a
5212 def while_stmt(self, nodelist):
522n/a # 'while' test ':' suite ['else' ':' suite]
523n/a
52412 testNode = self.com_node(nodelist[1])
52512 bodyNode = self.com_node(nodelist[3])
526n/a
52712 if len(nodelist) > 4:
5280 elseNode = self.com_node(nodelist[6])
529n/a else:
53012 elseNode = None
531n/a
53212 return While(testNode, bodyNode, elseNode, lineno=nodelist[0][2])
533n/a
5342 def for_stmt(self, nodelist):
535n/a # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite]
536n/a
53793 assignNode = self.com_assign(nodelist[1], OP_ASSIGN)
53893 listNode = self.com_node(nodelist[3])
53993 bodyNode = self.com_node(nodelist[5])
540n/a
54193 if len(nodelist) > 8:
5420 elseNode = self.com_node(nodelist[8])
543n/a else:
54493 elseNode = None
545n/a
54693 return For(assignNode, listNode, bodyNode, elseNode,
54793 lineno=nodelist[0][2])
548n/a
5492 def try_stmt(self, nodelist):
550146 return self.com_try_except_finally(nodelist)
551n/a
5522 def with_stmt(self, nodelist):
5537 return self.com_with(nodelist)
554n/a
5552 def with_var(self, nodelist):
5560 return self.com_with_var(nodelist)
557n/a
5582 def suite(self, nodelist):
559n/a # simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT
5601706 if len(nodelist) == 1:
561116 return self.com_stmt(nodelist[0])
562n/a
5631590 stmts = []
56410840 for node in nodelist:
5659250 if node[0] == symbol.stmt:
5664480 self.com_append_stmt(stmts, node)
5671590 return Stmt(stmts)
568n/a
569n/a # --------------------------------------------------------------
570n/a #
571n/a # EXPRESSION NODES (invoked by com_node())
572n/a #
573n/a
5742 def testlist(self, nodelist):
575n/a # testlist: expr (',' expr)* [',']
576n/a # testlist_safe: test [(',' test)+ [',']]
577n/a # exprlist: expr (',' expr)* [',']
5783600 return self.com_binary(Tuple, nodelist)
579n/a
5802 testlist_safe = testlist # XXX
5812 testlist1 = testlist
5822 exprlist = testlist
583n/a
5842 def testlist_comp(self, nodelist):
585n/a # test ( comp_for | (',' test)* [','] )
586534 assert nodelist[0][0] == symbol.test
587534 if len(nodelist) == 2 and nodelist[1][0] == symbol.comp_for:
5881 test = self.com_node(nodelist[0])
5891 return self.com_generator_expression(test, nodelist[1])
590533 return self.testlist(nodelist)
591n/a
5922 def test(self, nodelist):
593n/a # or_test ['if' or_test 'else' test] | lambdef
59410618 if len(nodelist) == 1 and nodelist[0][0] == symbol.lambdef:
59518 return self.lambdef(nodelist[0])
59610600 then = self.com_node(nodelist[0])
59710598 if len(nodelist) > 1:
5980 assert len(nodelist) == 5
5990 assert nodelist[1][1] == 'if'
6000 assert nodelist[3][1] == 'else'
6010 test = self.com_node(nodelist[2])
6020 else_ = self.com_node(nodelist[4])
6030 return IfExp(test, then, else_, lineno=nodelist[1][2])
60410598 return then
605n/a
6062 def or_test(self, nodelist):
607n/a # and_test ('or' and_test)* | lambdef
60810659 if len(nodelist) == 1 and nodelist[0][0] == symbol.lambdef:
6090 return self.lambdef(nodelist[0])
61010659 return self.com_binary(Or, nodelist)
6112 old_test = or_test
612n/a
6132 def and_test(self, nodelist):
614n/a # not_test ('and' not_test)*
61510644 return self.com_binary(And, nodelist)
616n/a
6172 def not_test(self, nodelist):
618n/a # 'not' not_test | comparison
61910688 result = self.com_node(nodelist[-1])
62010686 if len(nodelist) == 2:
62134 return Not(result, lineno=nodelist[0][2])
62210652 return result
623n/a
6242 def comparison(self, nodelist):
625n/a # comparison: expr (comp_op expr)*
62610654 node = self.com_node(nodelist[0])
62710652 if len(nodelist) == 1:
62810413 return node
629n/a
630239 results = []
631481 for i in range(2, len(nodelist), 2):
632242 nl = nodelist[i-1]
633n/a
634n/a # comp_op: '<' | '>' | '=' | '>=' | '<=' | '<>' | '!=' | '=='
635n/a # | 'in' | 'not' 'in' | 'is' | 'is' 'not'
636242 n = nl[1]
637242 if n[0] == token.NAME:
638137 type = n[1]
639137 if len(nl) == 3:
64017 if type == 'not':
64113 type = 'not in'
642n/a else:
6434 type = 'is not'
644n/a else:
645105 type = _cmp_types[n[0]]
646n/a
647242 lineno = nl[1][2]
648242 results.append((type, self.com_node(nodelist[i])))
649n/a
650n/a # we need a special "compare" node so that we can distinguish
651n/a # 3 < x < 5 from (3 < x) < 5
652n/a # the two have very different semantics and results (note that the
653n/a # latter form is always true)
654n/a
655239 return Compare(node, results, lineno=lineno)
656n/a
6572 def expr(self, nodelist):
658n/a # xor_expr ('|' xor_expr)*
65910914 return self.com_binary(Bitor, nodelist)
660n/a
6612 def xor_expr(self, nodelist):
662n/a # xor_expr ('^' xor_expr)*
66310915 return self.com_binary(Bitxor, nodelist)
664n/a
6652 def and_expr(self, nodelist):
666n/a # xor_expr ('&' xor_expr)*
66710916 return self.com_binary(Bitand, nodelist)
668n/a
6692 def shift_expr(self, nodelist):
670n/a # shift_expr ('<<'|'>>' shift_expr)*
67110917 node = self.com_node(nodelist[0])
67210925 for i in range(2, len(nodelist), 2):
67310 right = self.com_node(nodelist[i])
67410 if nodelist[i-1][0] == token.LEFTSHIFT:
6756 node = LeftShift([node, right], lineno=nodelist[1][2])
6764 elif nodelist[i-1][0] == token.RIGHTSHIFT:
6774 node = RightShift([node, right], lineno=nodelist[1][2])
678n/a else:
6790 raise ValueError, "unexpected token: %s" % nodelist[i-1][0]
68010915 return node
681n/a
6822 def arith_expr(self, nodelist):
68310927 node = self.com_node(nodelist[0])
68411027 for i in range(2, len(nodelist), 2):
685102 right = self.com_node(nodelist[i])
686102 if nodelist[i-1][0] == token.PLUS:
68797 node = Add([node, right], lineno=nodelist[1][2])
6885 elif nodelist[i-1][0] == token.MINUS:
6895 node = Sub([node, right], lineno=nodelist[1][2])
690n/a else:
6910 raise ValueError, "unexpected token: %s" % nodelist[i-1][0]
69210925 return node
693n/a
6942 def term(self, nodelist):
69511029 node = self.com_node(nodelist[0])
69611172 for i in range(2, len(nodelist), 2):
697145 right = self.com_node(nodelist[i])
698145 t = nodelist[i-1][0]
699145 if t == token.STAR:
70047 node = Mul([node, right])
70198 elif t == token.SLASH:
7024 node = Div([node, right])
70394 elif t == token.PERCENT:
70481 node = Mod([node, right])
70513 elif t == token.DOUBLESLASH:
70613 node = FloorDiv([node, right])
707n/a else:
7080 raise ValueError, "unexpected token: %s" % t
709145 node.lineno = nodelist[1][2]
71011027 return node
711n/a
7122 def factor(self, nodelist):
71311239 elt = nodelist[0]
71411239 t = elt[0]
71511239 node = self.lookup_node(nodelist[-1])(nodelist[-1][1:])
716n/a # need to handle (unary op)constant here...
71711237 if t == token.PLUS:
7184 return UnaryAdd(node, lineno=elt[2])
71911233 elif t == token.MINUS:
72057 return UnarySub(node, lineno=elt[2])
72111176 elif t == token.TILDE:
7220 node = Invert(node, lineno=elt[2])
72311176 return node
724n/a
7252 def power(self, nodelist):
726n/a # power: atom trailer* ('**' factor)*
72711178 node = self.com_node(nodelist[0])
72817001 for i in range(1, len(nodelist)):
7295829 elt = nodelist[i]
7305829 if elt[0] == token.DOUBLESTAR:
7314 return Power([node, self.com_node(nodelist[i+1])],
7324 lineno=elt[2])
733n/a
7345825 node = self.com_apply_trailer(node, elt)
735n/a
73611172 return node
737n/a
7382 def atom(self, nodelist):
73911560 return self._atom_dispatch[nodelist[0][0]](nodelist)
740n/a
7412 def atom_lpar(self, nodelist):
742549 if nodelist[1][0] == token.RPAR:
74315 return Tuple((), lineno=nodelist[0][2])
744534 return self.com_node(nodelist[1])
745n/a
7462 def atom_lsqb(self, nodelist):
747337 if nodelist[1][0] == token.RSQB:
74848 return List((), lineno=nodelist[0][2])
749289 return self.com_list_constructor(nodelist[1])
750n/a
7512 def atom_lbrace(self, nodelist):
752132 if nodelist[1][0] == token.RBRACE:
75344 return Dict((), lineno=nodelist[0][2])
75488 return self.com_dictorsetmaker(nodelist[1])
755n/a
7562 def atom_backquote(self, nodelist):
7570 return Backquote(self.com_node(nodelist[1]))
758n/a
7592 def atom_number(self, nodelist):
760n/a ### need to verify this matches compile.c
7611799 k = eval(nodelist[0][1])
7621799 return Const(k, lineno=nodelist[0][2])
763n/a
7642 def decode_literal(self, lit):
7651730 if self.encoding:
766n/a # this is particularly fragile & a bit of a
767n/a # hack... changes in compile.c:parsestr and
768n/a # tokenizer.c must be reflected here.
7690 if self.encoding not in ['utf-8', 'iso-8859-1']:
7700 lit = unicode(lit, 'utf-8').encode(self.encoding)
7710 return eval("# coding: %s\n%s" % (self.encoding, lit))
772n/a else:
7731730 return eval(lit)
774n/a
7752 def atom_string(self, nodelist):
7761702 k = ''
7773432 for node in nodelist:
7781730 k += self.decode_literal(node[1])
7791702 return Const(k, lineno=nodelist[0][2])
780n/a
7812 def atom_name(self, nodelist):
7827060 return Name(nodelist[0][1], lineno=nodelist[0][2])
783n/a
784n/a # --------------------------------------------------------------
785n/a #
786n/a # INTERNAL PARSING UTILITIES
787n/a #
788n/a
789n/a # The use of com_node() introduces a lot of extra stack frames,
790n/a # enough to cause a stack overflow compiling test.test_parser with
791n/a # the standard interpreter recursionlimit. The com_node() is a
792n/a # convenience function that hides the dispatch details, but comes
793n/a # at a very high cost. It is more efficient to dispatch directly
794n/a # in the callers. In these cases, use lookup_node() and call the
795n/a # dispatched node directly.
796n/a
7972 def lookup_node(self, node):
79890435 return self._dispatch[node[0]]
799n/a
8002 def com_node(self, node):
801n/a # Note: compile.c has handling in com_node for del_stmt, pass_stmt,
802n/a # break_stmt, stmt, small_stmt, flow_stmt, simple_stmt,
803n/a # and compound_stmt.
804n/a # We'll just dispatch them.
80585874 return self._dispatch[node[0]](node[1:])
806n/a
8072 def com_NEWLINE(self, *args):
808n/a # A ';' at the end of a line can make a NEWLINE token appear
809n/a # here, Render it harmless. (genc discards ('discard',
810n/a # ('const', xxxx)) Nodes)
8110 return Discard(Const(None))
812n/a
8132 def com_arglist(self, nodelist):
814n/a # varargslist:
815n/a # (fpdef ['=' test] ',')* ('*' NAME [',' '**' NAME] | '**' NAME)
816n/a # | fpdef ['=' test] (',' fpdef ['=' test])* [',']
817n/a # fpdef: NAME | '(' fplist ')'
818n/a # fplist: fpdef (',' fpdef)* [',']
819632 names = []
820632 defaults = []
821632 flags = 0
822n/a
823632 i = 0
8241583 while i < len(nodelist):
825979 node = nodelist[i]
826979 if node[0] == token.STAR or node[0] == token.DOUBLESTAR:
82727 if node[0] == token.STAR:
82827 node = nodelist[i+1]
82927 if node[0] == token.NAME:
83027 names.append(node[1])
83127 flags = flags | CO_VARARGS
83227 i = i + 3
833n/a
83427 if i < len(nodelist):
835n/a # should be DOUBLESTAR
8365 t = nodelist[i][0]
8375 if t == token.DOUBLESTAR:
8385 node = nodelist[i+1]
839n/a else:
8400 raise ValueError, "unexpected token: %s" % t
8415 names.append(node[1])
8425 flags = flags | CO_VARKEYWORDS
843n/a
84427 break
845n/a
846n/a # fpdef: NAME | '(' fplist ')'
847952 names.append(self.com_fpdef(node))
848n/a
849952 i = i + 1
850952 if i < len(nodelist) and nodelist[i][0] == token.EQUAL:
85144 defaults.append(self.com_node(nodelist[i + 1]))
85244 i = i + 2
853908 elif len(defaults):
854n/a # we have already seen an argument with default, but here
855n/a # came one without
8561 raise SyntaxError, "non-default argument follows default argument"
857n/a
858n/a # skip the comma
859951 i = i + 1
860n/a
861631 return names, defaults, flags
862n/a
8632 def com_fpdef(self, node):
864n/a # fpdef: NAME | '(' fplist ')'
865952 if node[1][0] == token.LPAR:
8660 return self.com_fplist(node[2])
867952 return node[1][1]
868n/a
8692 def com_fplist(self, node):
870n/a # fplist: fpdef (',' fpdef)* [',']
8710 if len(node) == 2:
8720 return self.com_fpdef(node[1])
8730 list = []
8740 for i in range(1, len(node), 2):
8750 list.append(self.com_fpdef(node[i]))
8760 return tuple(list)
877n/a
8782 def com_dotted_name(self, node):
879n/a # String together the dotted names and return the string
88077 name = ""
881185 for n in node:
882108 if type(n) == type(()) and n[0] == 1:
88383 name = name + n[1] + '.'
88477 return name[:-1]
885n/a
8862 def com_dotted_as_name(self, node):
88758 assert node[0] == symbol.dotted_as_name
88858 node = node[1:]
88958 dot = self.com_dotted_name(node[0][1:])
89058 if len(node) == 1:
89152 return dot, None
8926 assert node[1][1] == 'as'
8936 assert node[2][0] == token.NAME
8946 return dot, node[2][1]
895n/a
8962 def com_dotted_as_names(self, node):
89750 assert node[0] == symbol.dotted_as_names
89850 node = node[1:]
89950 names = [self.com_dotted_as_name(node[0])]
90058 for i in range(2, len(node), 2):
9018 names.append(self.com_dotted_as_name(node[i]))
90250 return names
903n/a
9042 def com_import_as_name(self, node):
90520 assert node[0] == symbol.import_as_name
90620 node = node[1:]
90720 assert node[0][0] == token.NAME
90820 if len(node) == 1:
90919 return node[0][1], None
9101 assert node[1][1] == 'as', node
9111 assert node[2][0] == token.NAME
9121 return node[0][1], node[2][1]
913n/a
9142 def com_import_as_names(self, node):
91518 assert node[0] == symbol.import_as_names
91618 node = node[1:]
91718 names = [self.com_import_as_name(node[0])]
91820 for i in range(2, len(node), 2):
9192 names.append(self.com_import_as_name(node[i]))
92018 return names
921n/a
9222 def com_bases(self, node):
923359 bases = []
924775 for i in range(1, len(node), 2):
925416 bases.append(self.com_node(node[i]))
926359 return bases
927n/a
9282 def com_try_except_finally(self, nodelist):
929n/a # ('try' ':' suite
930n/a # ((except_clause ':' suite)+ ['else' ':' suite] ['finally' ':' suite]
931n/a # | 'finally' ':' suite))
932n/a
933146 if nodelist[3][0] == token.NAME:
934n/a # first clause is a finally clause: only try-finally
93510 return TryFinally(self.com_node(nodelist[2]),
93610 self.com_node(nodelist[5]),
93710 lineno=nodelist[0][2])
938n/a
939n/a #tryexcept: [TryNode, [except_clauses], elseNode)]
940136 clauses = []
941136 elseNode = None
942136 finallyNode = None
943376 for i in range(3, len(nodelist), 3):
944240 node = nodelist[i]
945240 if node[0] == symbol.except_clause:
946n/a # except_clause: 'except' [expr [(',' | 'as') expr]] */
947138 if len(node) > 2:
948130 expr1 = self.com_node(node[2])
949130 if len(node) > 4:
95021 expr2 = self.com_assign(node[4], OP_ASSIGN)
951n/a else:
952109 expr2 = None
953n/a else:
9548 expr1 = expr2 = None
955138 clauses.append((expr1, expr2, self.com_node(nodelist[i+2])))
956n/a
957240 if node[0] == token.NAME:
958102 if node[1] == 'else':
95999 elseNode = self.com_node(nodelist[i+2])
9603 elif node[1] == 'finally':
9613 finallyNode = self.com_node(nodelist[i+2])
962136 try_except = TryExcept(self.com_node(nodelist[2]), clauses, elseNode,
963136 lineno=nodelist[0][2])
964136 if finallyNode:
9653 return TryFinally(try_except, finallyNode, lineno=nodelist[0][2])
966n/a else:
967133 return try_except
968n/a
9692 def com_with(self, nodelist):
970n/a # with_stmt: 'with' with_item (',' with_item)* ':' suite
9717 body = self.com_node(nodelist[-1])
9728 for i in range(len(nodelist) - 3, 0, -2):
9738 ret = self.com_with_item(nodelist[i], body, nodelist[0][2])
9748 if i == 1:
9757 return ret
9761 body = ret
977n/a
9782 def com_with_item(self, nodelist, body, lineno):
979n/a # with_item: test ['as' expr]
9808 if len(nodelist) == 4:
9814 var = self.com_assign(nodelist[3], OP_ASSIGN)
982n/a else:
9834 var = None
9848 expr = self.com_node(nodelist[1])
9858 return With(expr, var, body, lineno=lineno)
986n/a
9872 def com_augassign_op(self, node):
98819 assert node[0] == symbol.augassign
98919 return node[1]
990n/a
9912 def com_augassign(self, node):
992n/a """Return node suitable for lvalue of augmented assignment
993n/a
994n/a Names, slices, and attributes are the only allowable nodes.
995n/a """
99619 l = self.com_node(node)
99719 if l.__class__ in (Name, Slice, Subscript, Getattr):
99819 return l
9990 raise SyntaxError, "can't assign to %s" % l.__class__.__name__
1000n/a
10012 def com_assign(self, node, assigning):
1002n/a # return a node suitable for use as an "lvalue"
1003n/a # loop to avoid trivial recursion
10041337 while 1:
100518099 t = node[0]
100618099 if t in (symbol.exprlist, symbol.testlist, symbol.testlist_safe, symbol.testlist_comp):
10071225 if len(node) > 2:
100843 return self.com_assign_tuple(node, assigning)
10091182 node = node[1]
101016874 elif t in _assign_types:
101114648 if len(node) > 2:
10120 raise SyntaxError, "can't assign to operator"
101314648 node = node[1]
10142226 elif t == symbol.power:
10151304 if node[1][0] != symbol.atom:
10160 raise SyntaxError, "can't assign to operator"
10171304 if len(node) > 2:
1018382 primary = self.com_node(node[1])
1019403 for i in range(2, len(node)-1):
102021 ch = node[i]
102121 if ch[0] == token.DOUBLESTAR:
10220 raise SyntaxError, "can't assign to operator"
102321 primary = self.com_apply_trailer(primary, ch)
1024382 return self.com_assign_trailer(primary, node[-1],
1025382 assigning)
1026922 node = node[1]
1027922 elif t == symbol.atom:
1028922 t = node[1][0]
1029922 if t == token.LPAR:
103010 node = node[2]
103110 if node[0] == token.RPAR:
10320 raise SyntaxError, "can't assign to ()"
1033912 elif t == token.LSQB:
10341 node = node[2]
10351 if node[0] == token.RSQB:
10360 raise SyntaxError, "can't assign to []"
10371 return self.com_assign_list(node, assigning)
1038911 elif t == token.NAME:
1039911 return self.com_assign_name(node[1], assigning)
1040n/a else:
10410 raise SyntaxError, "can't assign to literal"
1042n/a else:
10430 raise SyntaxError, "bad assignment (%s)" % t
1044n/a
10452 def com_assign_tuple(self, node, assigning):
104643 assigns = []
1047138 for i in range(1, len(node), 2):
104895 assigns.append(self.com_assign(node[i], assigning))
104943 return AssTuple(assigns, lineno=extractLineNo(node))
1050n/a
10512 def com_assign_list(self, node, assigning):
10521 assigns = []
10533 for i in range(1, len(node), 2):
10542 if i + 1 < len(node):
10551 if node[i + 1][0] == symbol.list_for:
10560 raise SyntaxError, "can't assign to list comprehension"
10571 assert node[i + 1][0] == token.COMMA, node[i + 1]
10582 assigns.append(self.com_assign(node[i], assigning))
10591 return AssList(assigns, lineno=extractLineNo(node))
1060n/a
10612 def com_assign_name(self, node, assigning):
1062911 return AssName(node[1], assigning, lineno=node[2])
1063n/a
10642 def com_assign_trailer(self, primary, node, assigning):
1065382 t = node[1][0]
1066382 if t == token.DOT:
1067339 return self.com_assign_attr(primary, node[2], assigning)
106843 if t == token.LSQB:
106943 return self.com_subscriptlist(primary, node[2], assigning)
10700 if t == token.LPAR:
10710 raise SyntaxError, "can't assign to function call"
10720 raise SyntaxError, "unknown trailer type: %s" % t
1073n/a
10742 def com_assign_attr(self, primary, node, assigning):
1075339 return AssAttr(primary, node[1], assigning, lineno=node[-1])
1076n/a
10772 def com_binary(self, constructor, nodelist):
1078n/a "Compile 'NODE (OP NODE)*' into (type, [ node1, ..., nodeN ])."
107957648 l = len(nodelist)
108057648 if l == 1:
108157109 n = nodelist[0]
108257109 return self.lookup_node(n)(n[1:])
1083539 items = []
10841902 for i in range(0, l, 2):
10851363 n = nodelist[i]
10861363 items.append(self.lookup_node(n)(n[1:]))
1087539 return constructor(items, lineno=extractLineNo(nodelist))
1088n/a
10892 def com_stmt(self, node):
10909967 result = self.lookup_node(node)(node[1:])
10919961 assert result is not None
10929961 if isinstance(result, Stmt):
10935137 return result
10944824 return Stmt([result])
1095n/a
10962 def com_append_stmt(self, stmts, node):
10978106 result = self.lookup_node(node)(node[1:])
10988101 assert result is not None
10998101 if isinstance(result, Stmt):
11008101 stmts.extend(result.nodes)
1101n/a else:
11020 stmts.append(result)
1103n/a
11042 def com_list_constructor(self, nodelist):
1105n/a # listmaker: test ( list_for | (',' test)* [','] )
1106289 values = []
11071412 for i in range(1, len(nodelist)):
11081137 if nodelist[i][0] == symbol.list_for:
110914 assert len(nodelist[i:]) == 1
111014 return self.com_list_comprehension(values[0],
111114 nodelist[i])
11121123 elif nodelist[i][0] == token.COMMA:
1113427 continue
1114696 values.append(self.com_node(nodelist[i]))
1115275 return List(values, lineno=values[0].lineno)
1116n/a
11172 def com_list_comprehension(self, expr, node):
111814 return self.com_comprehension(expr, None, node, 'list')
1119n/a
11202 def com_comprehension(self, expr1, expr2, node, type):
1121n/a # list_iter: list_for | list_if
1122n/a # list_for: 'for' exprlist 'in' testlist [list_iter]
1123n/a # list_if: 'if' test [list_iter]
1124n/a
1125n/a # XXX should raise SyntaxError for assignment
1126n/a # XXX(avassalotti) Set and dict comprehensions should have generator
1127n/a # semantics. In other words, they shouldn't leak
1128n/a # variables outside of the comprehension's scope.
1129n/a
113020 lineno = node[1][2]
113120 fors = []
113250 while node:
113330 t = node[1][1]
113430 if t == 'for':
113522 assignNode = self.com_assign(node[2], OP_ASSIGN)
113622 compNode = self.com_node(node[4])
113722 newfor = ListCompFor(assignNode, compNode, [])
113822 newfor.lineno = node[1][2]
113922 fors.append(newfor)
114022 if len(node) == 5:
114114 node = None
11428 elif type == 'list':
11434 node = self.com_list_iter(node[5])
1144n/a else:
11454 node = self.com_comp_iter(node[5])
11468 elif t == 'if':
11478 test = self.com_node(node[2])
11488 newif = ListCompIf(test, lineno=node[1][2])
11498 newfor.ifs.append(newif)
11508 if len(node) == 3:
11516 node = None
11522 elif type == 'list':
11530 node = self.com_list_iter(node[3])
1154n/a else:
11552 node = self.com_comp_iter(node[3])
1156n/a else:
11570 raise SyntaxError, \
11580 ("unexpected comprehension element: %s %d"
11590 % (node, lineno))
116020 if type == 'list':
116114 return ListComp(expr1, fors, lineno=lineno)
11626 elif type == 'set':
11633 return SetComp(expr1, fors, lineno=lineno)
11643 elif type == 'dict':
11653 return DictComp(expr1, expr2, fors, lineno=lineno)
1166n/a else:
11670 raise ValueError("unexpected comprehension type: " + repr(type))
1168n/a
11692 def com_list_iter(self, node):
11704 assert node[0] == symbol.list_iter
11714 return node[1]
1172n/a
11732 def com_comp_iter(self, node):
11749 assert node[0] == symbol.comp_iter
11759 return node[1]
1176n/a
11772 def com_generator_expression(self, expr, node):
1178n/a # comp_iter: comp_for | comp_if
1179n/a # comp_for: 'for' exprlist 'in' test [comp_iter]
1180n/a # comp_if: 'if' test [comp_iter]
1181n/a
11822 lineno = node[1][2]
11832 fors = []
11847 while node:
11855 t = node[1][1]
11865 if t == 'for':
11873 assignNode = self.com_assign(node[2], OP_ASSIGN)
11883 genNode = self.com_node(node[4])
11893 newfor = GenExprFor(assignNode, genNode, [],
11903 lineno=node[1][2])
11913 fors.append(newfor)
11923 if (len(node)) == 5:
11931 node = None
1194n/a else:
11952 node = self.com_comp_iter(node[5])
11962 elif t == 'if':
11972 test = self.com_node(node[2])
11982 newif = GenExprIf(test, lineno=node[1][2])
11992 newfor.ifs.append(newif)
12002 if len(node) == 3:
12011 node = None
1202n/a else:
12031 node = self.com_comp_iter(node[3])
1204n/a else:
12050 raise SyntaxError, \
12060 ("unexpected generator expression element: %s %d"
12070 % (node, lineno))
12082 fors[0].is_outmost = True
12092 return GenExpr(GenExprInner(expr, fors), lineno=lineno)
1210n/a
12112 def com_dictorsetmaker(self, nodelist):
1212n/a # dictorsetmaker: ( (test ':' test (comp_for | (',' test ':' test)* [','])) |
1213n/a # (test (comp_for | (',' test)* [','])) )
121488 assert nodelist[0] == symbol.dictorsetmaker
121588 nodelist = nodelist[1:]
121688 if len(nodelist) == 1 or nodelist[1][0] == token.COMMA:
1217n/a # set literal
12187 items = []
121928 for i in range(0, len(nodelist), 2):
122021 items.append(self.com_node(nodelist[i]))
12217 return Set(items, lineno=items[0].lineno)
122281 elif nodelist[1][0] == symbol.comp_for:
1223n/a # set comprehension
12243 expr = self.com_node(nodelist[0])
12253 return self.com_comprehension(expr, None, nodelist[1], 'set')
122678 elif len(nodelist) > 3 and nodelist[3][0] == symbol.comp_for:
1227n/a # dict comprehension
12283 assert nodelist[1][0] == token.COLON
12293 key = self.com_node(nodelist[0])
12303 value = self.com_node(nodelist[2])
12313 return self.com_comprehension(key, value, nodelist[3], 'dict')
1232n/a else:
1233n/a # dict literal
123475 items = []
1235230 for i in range(0, len(nodelist), 4):
1236155 items.append((self.com_node(nodelist[i]),
1237155 self.com_node(nodelist[i+2])))
123875 return Dict(items, lineno=items[0][0].lineno)
1239n/a
12402 def com_apply_trailer(self, primaryNode, nodelist):
12415846 t = nodelist[1][0]
12425846 if t == token.LPAR:
12433062 return self.com_call_function(primaryNode, nodelist[2])
12442784 if t == token.DOT:
12452640 return self.com_select_member(primaryNode, nodelist[2])
1246144 if t == token.LSQB:
1247144 return self.com_subscriptlist(primaryNode, nodelist[2], OP_APPLY)
1248n/a
12490 raise SyntaxError, 'unknown node type: %s' % t
1250n/a
12512 def com_select_member(self, primaryNode, nodelist):
12522640 if nodelist[0] != token.NAME:
12530 raise SyntaxError, "member must be a name"
12542640 return Getattr(primaryNode, nodelist[1], lineno=nodelist[2])
1255n/a
12562 def com_call_function(self, primaryNode, nodelist):
12573069 if nodelist[0] == token.RPAR:
1258487 return CallFunc(primaryNode, [], lineno=extractLineNo(nodelist))
12592582 args = []
12602582 kw = 0
12612582 star_node = dstar_node = None
12622582 len_nodelist = len(nodelist)
12632582 i = 1
12646749 while i < len_nodelist:
12654169 node = nodelist[i]
1266n/a
12674169 if node[0]==token.STAR:
126813 if star_node is not None:
12690 raise SyntaxError, 'already have the varargs indentifier'
127013 star_node = self.com_node(nodelist[i+1])
127113 i = i + 3
127213 continue
12734156 elif node[0]==token.DOUBLESTAR:
127410 if dstar_node is not None:
12750 raise SyntaxError, 'already have the kwargs indentifier'
127610 dstar_node = self.com_node(nodelist[i+1])
127710 i = i + 3
127810 continue
1279n/a
1280n/a # positional or named parameters
12814146 kw, result = self.com_argument(node, kw, star_node)
1282n/a
12834144 if len_nodelist != 2 and isinstance(result, GenExpr) \
12840 and len(node) == 3 and node[2][0] == symbol.comp_for:
1285n/a # allow f(x for x in y), but reject f(x for x in y, 1)
1286n/a # should use f((x for x in y), 1) instead of f(x for x in y, 1)
12870 raise SyntaxError, 'generator expression needs parenthesis'
1288n/a
12894144 args.append(result)
12904144 i = i + 2
1291n/a
12922580 return CallFunc(primaryNode, args, star_node, dstar_node,
12932580 lineno=extractLineNo(nodelist))
1294n/a
12952 def com_argument(self, nodelist, kw, star_node):
12964146 if len(nodelist) == 3 and nodelist[2][0] == symbol.comp_for:
12971 test = self.com_node(nodelist[1])
12981 return 0, self.com_generator_expression(test, nodelist[2])
12994145 if len(nodelist) == 2:
13004104 if kw:
13011 raise SyntaxError, "non-keyword arg after keyword arg"
13024103 if star_node:
13031 raise SyntaxError, "only named arguments may follow *expression"
13044102 return 0, self.com_node(nodelist[1])
130541 result = self.com_node(nodelist[3])
130641 n = nodelist[1]
1307615 while len(n) == 2 and n[0] != token.NAME:
1308574 n = n[1]
130941 if n[0] != token.NAME:
13100 raise SyntaxError, "keyword can't be an expression (%s)"%n[0]
131141 node = Keyword(n[1], result, lineno=n[2])
131241 return 1, node
1313n/a
13142 def com_subscriptlist(self, primary, nodelist, assigning):
1315n/a # slicing: simple_slicing | extended_slicing
1316n/a # simple_slicing: primary "[" short_slice "]"
1317n/a # extended_slicing: primary "[" slice_list "]"
1318n/a # slice_list: slice_item ("," slice_item)* [","]
1319n/a
1320n/a # backwards compat slice for '[i:j]'
1321187 if len(nodelist) == 2:
1322187 sub = nodelist[1]
1323187 if (sub[1][0] == token.COLON or \
1324170 (len(sub) > 2 and sub[2][0] == token.COLON)) and \
132536 sub[-1][0] != symbol.sliceop:
132636 return self.com_slice(primary, sub, assigning)
1327n/a
1328151 subscripts = []
1329302 for i in range(1, len(nodelist), 2):
1330151 subscripts.append(self.com_subscript(nodelist[i]))
1331151 return Subscript(primary, assigning, subscripts,
1332151 lineno=extractLineNo(nodelist))
1333n/a
13342 def com_subscript(self, node):
1335n/a # slice_item: expression | proper_slice | ellipsis
1336151 ch = node[1]
1337151 t = ch[0]
1338151 if t == token.DOT and node[2][0] == token.DOT:
13390 return Ellipsis()
1340151 if t == token.COLON or len(node) > 2:
13410 return self.com_sliceobj(node)
1342151 return self.com_node(ch)
1343n/a
13442 def com_sliceobj(self, node):
1345n/a # proper_slice: short_slice | long_slice
1346n/a # short_slice: [lower_bound] ":" [upper_bound]
1347n/a # long_slice: short_slice ":" [stride]
1348n/a # lower_bound: expression
1349n/a # upper_bound: expression
1350n/a # stride: expression
1351n/a #
1352n/a # Note: a stride may be further slicing...
1353n/a
13540 items = []
1355n/a
13560 if node[1][0] == token.COLON:
13570 items.append(Const(None))
13580 i = 2
1359n/a else:
13600 items.append(self.com_node(node[1]))
1361n/a # i == 2 is a COLON
13620 i = 3
1363n/a
13640 if i < len(node) and node[i][0] == symbol.test:
13650 items.append(self.com_node(node[i]))
13660 i = i + 1
1367n/a else:
13680 items.append(Const(None))
1369n/a
1370n/a # a short_slice has been built. look for long_slice now by looking
1371n/a # for strides...
13720 for j in range(i, len(node)):
13730 ch = node[j]
13740 if len(ch) == 2:
13750 items.append(Const(None))
1376n/a else:
13770 items.append(self.com_node(ch[2]))
13780 return Sliceobj(items, lineno=extractLineNo(node))
1379n/a
13802 def com_slice(self, primary, node, assigning):
1381n/a # short_slice: [lower_bound] ":" [upper_bound]
138236 lower = upper = None
138336 if len(node) == 3:
138419 if node[1][0] == token.COLON:
138511 upper = self.com_node(node[2])
1386n/a else:
13878 lower = self.com_node(node[1])
138817 elif len(node) == 4:
138911 lower = self.com_node(node[1])
139011 upper = self.com_node(node[3])
139136 return Slice(primary, assigning, lower, upper,
139236 lineno=extractLineNo(node))
1393n/a
13942 def get_docstring(self, node, n=None):
13956878 if n is None:
13966849 n = node[0]
13976849 node = node[1:]
13986878 if n == symbol.suite:
13991043 if len(node) == 1:
140071 return self.get_docstring(node[0])
14012916 for sub in node:
14022916 if sub[0] == symbol.stmt:
1403972 return self.get_docstring(sub)
14040 return None
14055835 if n == symbol.file_input:
140629 for sub in node:
140729 if sub[0] == symbol.stmt:
140829 return self.get_docstring(sub)
14090 return None
14105806 if n == symbol.atom:
141135 if node[0][0] == token.STRING:
141234 s = ''
141368 for t in node:
141434 s = s + eval(t[1])
141534 return s
14161 return None
14175771 if n == symbol.stmt or n == symbol.simple_stmt \
14183999 or n == symbol.small_stmt:
14192543 return self.get_docstring(node[0])
14203228 if n in _doc_nodes and len(node) == 1:
14212191 return self.get_docstring(node[0])
14221037 return None
1423n/a
1424n/a
1425n/a_doc_nodes = [
14262 symbol.expr_stmt,
14272 symbol.testlist,
14282 symbol.testlist_safe,
14292 symbol.test,
14302 symbol.or_test,
14312 symbol.and_test,
14322 symbol.not_test,
14332 symbol.comparison,
14342 symbol.expr,
14352 symbol.xor_expr,
14362 symbol.and_expr,
14372 symbol.shift_expr,
14382 symbol.arith_expr,
14392 symbol.term,
14402 symbol.factor,
14412 symbol.power,
1442n/a ]
1443n/a
1444n/a# comp_op: '<' | '>' | '=' | '>=' | '<=' | '<>' | '!=' | '=='
1445n/a# | 'in' | 'not' 'in' | 'is' | 'is' 'not'
14462_cmp_types = {
14472 token.LESS : '<',
14482 token.GREATER : '>',
14492 token.EQEQUAL : '==',
14502 token.EQUAL : '==',
14512 token.LESSEQUAL : '<=',
14522 token.GREATEREQUAL : '>=',
14532 token.NOTEQUAL : '!=',
1454n/a }
1455n/a
1456n/a_legal_node_types = [
14572 symbol.funcdef,
14582 symbol.classdef,
14592 symbol.stmt,
14602 symbol.small_stmt,
14612 symbol.flow_stmt,
14622 symbol.simple_stmt,
14632 symbol.compound_stmt,
14642 symbol.expr_stmt,
14652 symbol.print_stmt,
14662 symbol.del_stmt,
14672 symbol.pass_stmt,
14682 symbol.break_stmt,
14692 symbol.continue_stmt,
14702 symbol.return_stmt,
14712 symbol.raise_stmt,
14722 symbol.import_stmt,
14732 symbol.global_stmt,
14742 symbol.exec_stmt,
14752 symbol.assert_stmt,
14762 symbol.if_stmt,
14772 symbol.while_stmt,
14782 symbol.for_stmt,
14792 symbol.try_stmt,
14802 symbol.with_stmt,
14812 symbol.suite,
14822 symbol.testlist,
14832 symbol.testlist_safe,
14842 symbol.test,
14852 symbol.and_test,
14862 symbol.not_test,
14872 symbol.comparison,
14882 symbol.exprlist,
14892 symbol.expr,
14902 symbol.xor_expr,
14912 symbol.and_expr,
14922 symbol.shift_expr,
14932 symbol.arith_expr,
14942 symbol.term,
14952 symbol.factor,
14962 symbol.power,
14972 symbol.atom,
1498n/a ]
1499n/a
15002if hasattr(symbol, 'yield_stmt'):
15012 _legal_node_types.append(symbol.yield_stmt)
15022if hasattr(symbol, 'yield_expr'):
15032 _legal_node_types.append(symbol.yield_expr)
1504n/a
1505n/a_assign_types = [
15062 symbol.test,
15072 symbol.or_test,
15082 symbol.and_test,
15092 symbol.not_test,
15102 symbol.comparison,
15112 symbol.expr,
15122 symbol.xor_expr,
15132 symbol.and_expr,
15142 symbol.shift_expr,
15152 symbol.arith_expr,
15162 symbol.term,
15172 symbol.factor,
1518n/a ]
1519n/a
15202_names = {}
1521174for k, v in symbol.sym_name.items():
1522172 _names[k] = v
1523114for k, v in token.tok_name.items():
1524112 _names[k] = v
1525n/a
15262def debug_tree(tree):
15270 l = []
15280 for elt in tree:
15290 if isinstance(elt, int):
15300 l.append(_names.get(elt, elt))
15310 elif isinstance(elt, str):
15320 l.append(elt)
1533n/a else:
15340 l.append(debug_tree(elt))
15350 return l