|
1 """Check for errs in the AST. |
|
2 |
|
3 The Python parser does not catch all syntax errors. Others, like |
|
4 assignments with invalid targets, are caught in the code generation |
|
5 phase. |
|
6 |
|
7 The compiler package catches some errors in the transformer module. |
|
8 But it seems clearer to write checkers that use the AST to detect |
|
9 errors. |
|
10 """ |
|
11 |
|
12 from compiler import ast, walk |
|
13 |
|
14 def check(tree, multi=None): |
|
15 v = SyntaxErrorChecker(multi) |
|
16 walk(tree, v) |
|
17 return v.errors |
|
18 |
|
19 class SyntaxErrorChecker: |
|
20 """A visitor to find syntax errors in the AST.""" |
|
21 |
|
22 def __init__(self, multi=None): |
|
23 """Create new visitor object. |
|
24 |
|
25 If optional argument multi is not None, then print messages |
|
26 for each error rather than raising a SyntaxError for the |
|
27 first. |
|
28 """ |
|
29 self.multi = multi |
|
30 self.errors = 0 |
|
31 |
|
32 def error(self, node, msg): |
|
33 self.errors = self.errors + 1 |
|
34 if self.multi is not None: |
|
35 print "%s:%s: %s" % (node.filename, node.lineno, msg) |
|
36 else: |
|
37 raise SyntaxError, "%s (%s:%s)" % (msg, node.filename, node.lineno) |
|
38 |
|
39 def visitAssign(self, node): |
|
40 # the transformer module handles many of these |
|
41 pass |
|
42 ## for target in node.nodes: |
|
43 ## if isinstance(target, ast.AssList): |
|
44 ## if target.lineno is None: |
|
45 ## target.lineno = node.lineno |
|
46 ## self.error(target, "can't assign to list comprehension") |