Commit | Line | Data |
---|---|---|
86530b38 AT |
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 | for target in node.nodes: | |
42 | pass | |
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") |