root/galaxy-central/eggs/Mako-0.2.5-py2.6.egg/mako/pyparser.py @ 3

リビジョン 3, 15.4 KB (コミッタ: kohda, 14 年 前)

Install Unix tools  http://hannonlab.cshl.edu/galaxy_unix_tools/galaxy.html

行番号 
1# ast.py
2# Copyright (C) Mako developers
3#
4# This module is part of Mako and is released under
5# the MIT License: http://www.opensource.org/licenses/mit-license.php
6
7"""Handles parsing of Python code.
8
9Parsing to AST is done via _ast on Python > 2.5, otherwise the compiler
10module is used.
11"""
12
13from StringIO import StringIO
14from mako import exceptions, util
15
16# words that cannot be assigned to (notably smaller than the total keys in __builtins__)
17reserved = util.Set(['True', 'False', 'None'])
18
19try:
20    import _ast
21    util.restore__ast(_ast)
22    import _ast_util
23except ImportError:
24    _ast = None
25    from compiler import parse as compiler_parse
26    from compiler import visitor
27
28
29def parse(code, mode='exec', **exception_kwargs):
30    """Parse an expression into AST"""
31    try:
32        if _ast:
33            return _ast_util.parse(code, '<unknown>', mode)
34        else:
35            return compiler_parse(code, mode)
36    except Exception, e:
37        raise exceptions.SyntaxException("(%s) %s (%s)" % (e.__class__.__name__, str(e), repr(code[0:50])), **exception_kwargs)
38
39
40if _ast:
41    class FindIdentifiers(_ast_util.NodeVisitor):
42        def __init__(self, listener, **exception_kwargs):
43            self.in_function = False
44            self.in_assign_targets = False
45            self.local_ident_stack = {}
46            self.listener = listener
47            self.exception_kwargs = exception_kwargs
48        def _add_declared(self, name):
49            if not self.in_function:
50                self.listener.declared_identifiers.add(name)
51        def visit_ClassDef(self, node):
52            self._add_declared(node.name)
53        def visit_Assign(self, node):
54            # flip around the visiting of Assign so the expression gets evaluated first,
55            # in the case of a clause like "x=x+5" (x is undeclared)
56            self.visit(node.value)
57            in_a = self.in_assign_targets
58            self.in_assign_targets = True
59            for n in node.targets:
60                self.visit(n)
61            self.in_assign_targets = in_a
62        def visit_FunctionDef(self, node):
63            self._add_declared(node.name)
64            # push function state onto stack.  dont log any
65            # more identifiers as "declared" until outside of the function,
66            # but keep logging identifiers as "undeclared".
67            # track argument names in each function header so they arent counted as "undeclared"
68            saved = {}
69            inf = self.in_function
70            self.in_function = True
71            for arg in node.args.args:
72                if arg.id in self.local_ident_stack:
73                    saved[arg.id] = True
74                else:
75                    self.local_ident_stack[arg.id] = True
76            for n in node.body:
77                self.visit(n)
78            self.in_function = inf
79            for arg in node.args.args:
80                if arg.id not in saved:
81                    del self.local_ident_stack[arg.id]
82        def visit_For(self, node):
83            # flip around visit
84            self.visit(node.iter)
85            self.visit(node.target)
86            for statement in node.body:
87                self.visit(statement)
88            for statement in node.orelse:
89                self.visit(statement)
90        def visit_Name(self, node):
91            if isinstance(node.ctx, _ast.Store):
92                self._add_declared(node.id)
93            if node.id not in reserved and node.id not in self.listener.declared_identifiers and node.id not in self.local_ident_stack:
94                self.listener.undeclared_identifiers.add(node.id)
95        def visit_Import(self, node):
96            for name in node.names:
97                if name.asname is not None:
98                    self._add_declared(name.asname)
99                else:
100                    self._add_declared(name.name.split('.')[0])
101        def visit_ImportFrom(self, node):
102            for name in node.names:
103                if name.asname is not None:
104                    self._add_declared(name.asname)
105                else:
106                    if name.name == '*':
107                        raise exceptions.CompileException("'import *' is not supported, since all identifier names must be explicitly declared.  Please use the form 'from <modulename> import <name1>, <name2>, ...' instead.", **self.exception_kwargs)
108                    self._add_declared(name.name)
109
110    class FindTuple(_ast_util.NodeVisitor):
111        def __init__(self, listener, code_factory, **exception_kwargs):
112            self.listener = listener
113            self.exception_kwargs = exception_kwargs
114            self.code_factory = code_factory
115        def visit_Tuple(self, node):
116            for n in node.elts:
117                p = self.code_factory(n, **self.exception_kwargs)
118                self.listener.codeargs.append(p)
119                self.listener.args.append(ExpressionGenerator(n).value())
120                self.listener.declared_identifiers = self.listener.declared_identifiers.union(p.declared_identifiers)
121                self.listener.undeclared_identifiers = self.listener.undeclared_identifiers.union(p.undeclared_identifiers)
122
123    class ParseFunc(_ast_util.NodeVisitor):
124        def __init__(self, listener, **exception_kwargs):
125            self.listener = listener
126            self.exception_kwargs = exception_kwargs
127        def visit_FunctionDef(self, node):
128            self.listener.funcname = node.name
129            argnames = [arg.id for arg in node.args.args]
130            if node.args.vararg:
131                argnames.append(node.args.vararg)
132            if node.args.kwarg:
133                argnames.append(node.args.kwarg)
134            self.listener.argnames = argnames
135            self.listener.defaults = node.args.defaults # ast
136            self.listener.varargs = node.args.vararg
137            self.listener.kwargs = node.args.kwarg
138
139    class ExpressionGenerator(object):
140        def __init__(self, astnode):
141            self.generator = _ast_util.SourceGenerator(' ' * 4)
142            self.generator.visit(astnode)
143        def value(self):
144            return ''.join(self.generator.result)
145else:
146    class FindIdentifiers(object):
147        def __init__(self, listener, **exception_kwargs):
148            self.in_function = False
149            self.local_ident_stack = {}
150            self.listener = listener
151            self.exception_kwargs = exception_kwargs
152        def _add_declared(self, name):
153            if not self.in_function:
154                self.listener.declared_identifiers.add(name)
155        def visitClass(self, node, *args):
156            self._add_declared(node.name)
157        def visitAssName(self, node, *args):
158            self._add_declared(node.name)
159        def visitAssign(self, node, *args):
160            # flip around the visiting of Assign so the expression gets evaluated first,
161            # in the case of a clause like "x=x+5" (x is undeclared)
162            self.visit(node.expr, *args)
163            for n in node.nodes:
164                self.visit(n, *args)
165        def visitFunction(self,node, *args):
166            self._add_declared(node.name)
167            # push function state onto stack.  dont log any
168            # more identifiers as "declared" until outside of the function,
169            # but keep logging identifiers as "undeclared".
170            # track argument names in each function header so they arent counted as "undeclared"
171            saved = {}
172            inf = self.in_function
173            self.in_function = True
174            for arg in node.argnames:
175                if arg in self.local_ident_stack:
176                    saved[arg] = True
177                else:
178                    self.local_ident_stack[arg] = True
179            for n in node.getChildNodes():
180                self.visit(n, *args)
181            self.in_function = inf
182            for arg in node.argnames:
183                if arg not in saved:
184                    del self.local_ident_stack[arg]
185        def visitFor(self, node, *args):
186            # flip around visit
187            self.visit(node.list, *args)
188            self.visit(node.assign, *args)
189            self.visit(node.body, *args)
190        def visitName(self, node, *args):
191            if node.name not in reserved and node.name not in self.listener.declared_identifiers and node.name not in self.local_ident_stack:
192                self.listener.undeclared_identifiers.add(node.name)
193        def visitImport(self, node, *args):
194            for (mod, alias) in node.names:
195                if alias is not None:
196                    self._add_declared(alias)
197                else:
198                    self._add_declared(mod.split('.')[0])
199        def visitFrom(self, node, *args):
200            for (mod, alias) in node.names:
201                if alias is not None:
202                    self._add_declared(alias)
203                else:
204                    if mod == '*':
205                        raise exceptions.CompileException("'import *' is not supported, since all identifier names must be explicitly declared.  Please use the form 'from <modulename> import <name1>, <name2>, ...' instead.", **self.exception_kwargs)
206                    self._add_declared(mod)
207        def visit(self, expr):
208            visitor.walk(expr, self) #, walker=walker())
209
210    class FindTuple(object):
211        def __init__(self, listener, code_factory, **exception_kwargs):
212            self.listener = listener
213            self.exception_kwargs = exception_kwargs
214            self.code_factory = code_factory
215        def visitTuple(self, node, *args):
216            for n in node.nodes:
217                p = self.code_factory(n, **self.exception_kwargs)
218                self.listener.codeargs.append(p)
219                self.listener.args.append(ExpressionGenerator(n).value())
220                self.listener.declared_identifiers = self.listener.declared_identifiers.union(p.declared_identifiers)
221                self.listener.undeclared_identifiers = self.listener.undeclared_identifiers.union(p.undeclared_identifiers)
222        def visit(self, expr):
223            visitor.walk(expr, self) #, walker=walker())
224
225    class ParseFunc(object):
226        def __init__(self, listener, **exception_kwargs):
227            self.listener = listener
228            self.exception_kwargs = exception_kwargs
229        def visitFunction(self, node, *args):
230            self.listener.funcname = node.name
231            self.listener.argnames = node.argnames
232            self.listener.defaults = node.defaults
233            self.listener.varargs = node.varargs
234            self.listener.kwargs = node.kwargs
235        def visit(self, expr):
236            visitor.walk(expr, self)
237
238    class ExpressionGenerator(object):
239        """given an AST node, generates an equivalent literal Python expression."""
240        def __init__(self, astnode):
241            self.buf = StringIO()
242            visitor.walk(astnode, self) #, walker=walker())
243        def value(self):
244            return self.buf.getvalue()       
245        def operator(self, op, node, *args):
246            self.buf.write("(")
247            self.visit(node.left, *args)
248            self.buf.write(" %s " % op)
249            self.visit(node.right, *args)
250            self.buf.write(")")
251        def booleanop(self, op, node, *args):
252            self.visit(node.nodes[0])
253            for n in node.nodes[1:]:
254                self.buf.write(" " + op + " ")
255                self.visit(n, *args)
256        def visitConst(self, node, *args):
257            self.buf.write(repr(node.value))
258        def visitAssName(self, node, *args):
259            # TODO: figure out OP_ASSIGN, other OP_s
260            self.buf.write(node.name)
261        def visitName(self, node, *args):
262            self.buf.write(node.name)
263        def visitMul(self, node, *args):
264            self.operator("*", node, *args)
265        def visitAnd(self, node, *args):
266            self.booleanop("and", node, *args)
267        def visitOr(self, node, *args):
268            self.booleanop("or", node, *args)
269        def visitBitand(self, node, *args):
270            self.booleanop("&", node, *args)
271        def visitBitor(self, node, *args):
272            self.booleanop("|", node, *args)
273        def visitBitxor(self, node, *args):
274            self.booleanop("^", node, *args)
275        def visitAdd(self, node, *args):
276            self.operator("+", node, *args)
277        def visitGetattr(self, node, *args):
278            self.visit(node.expr, *args)
279            self.buf.write(".%s" % node.attrname)
280        def visitSub(self, node, *args):
281            self.operator("-", node, *args)
282        def visitNot(self, node, *args):
283            self.buf.write("not ")
284            self.visit(node.expr)
285        def visitDiv(self, node, *args):
286            self.operator("/", node, *args)
287        def visitFloorDiv(self, node, *args):
288            self.operator("//", node, *args)
289        def visitSubscript(self, node, *args):
290            self.visit(node.expr)
291            self.buf.write("[")
292            [self.visit(x) for x in node.subs]
293            self.buf.write("]")
294        def visitUnarySub(self, node, *args):
295            self.buf.write("-")
296            self.visit(node.expr)
297        def visitUnaryAdd(self, node, *args):
298            self.buf.write("-")
299            self.visit(node.expr)
300        def visitSlice(self, node, *args):
301            self.visit(node.expr)
302            self.buf.write("[")
303            if node.lower is not None:
304                self.visit(node.lower)
305            self.buf.write(":")
306            if node.upper is not None:
307                self.visit(node.upper)
308            self.buf.write("]")
309        def visitDict(self, node):
310            self.buf.write("{")
311            c = node.getChildren()
312            for i in range(0, len(c), 2):
313                self.visit(c[i])
314                self.buf.write(": ")
315                self.visit(c[i+1])
316                if i<len(c) -2:
317                    self.buf.write(", ")
318            self.buf.write("}")
319        def visitTuple(self, node):
320            self.buf.write("(")
321            c = node.getChildren()
322            for i in range(0, len(c)):
323                self.visit(c[i])
324                if i<len(c) - 1:
325                    self.buf.write(", ")
326            self.buf.write(")")
327        def visitList(self, node):
328            self.buf.write("[")
329            c = node.getChildren()
330            for i in range(0, len(c)):
331                self.visit(c[i])
332                if i<len(c) - 1:
333                    self.buf.write(", ")
334            self.buf.write("]")
335        def visitListComp(self, node):
336            self.buf.write("[")
337            self.visit(node.expr)
338            self.buf.write(" ")
339            for n in node.quals:
340                self.visit(n)
341            self.buf.write("]")
342        def visitListCompFor(self, node):
343            self.buf.write(" for ")
344            self.visit(node.assign)
345            self.buf.write(" in ")
346            self.visit(node.list)
347            for n in node.ifs:
348                self.visit(n)
349        def visitListCompIf(self, node):
350            self.buf.write(" if ")
351            self.visit(node.test)
352        def visitCompare(self, node):
353            self.visit(node.expr)
354            for tup in node.ops:
355                self.buf.write(tup[0])
356                self.visit(tup[1])
357        def visitCallFunc(self, node, *args):
358            self.visit(node.node)
359            self.buf.write("(")
360            if len(node.args):
361                self.visit(node.args[0])
362                for a in node.args[1:]:
363                    self.buf.write(", ")
364                    self.visit(a)
365            self.buf.write(")")
366
367    class walker(visitor.ASTVisitor):
368        def dispatch(self, node, *args):
369            print "Node:", str(node)
370            #print "dir:", dir(node)
371            return visitor.ASTVisitor.dispatch(self, node, *args)
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。