Jeremy Hylton | 37c9351 | 2001-09-17 18:03:55 +0000 | [diff] [blame] | 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: |
Jeremy Hylton | 2e4cc7e | 2001-09-17 19:33:48 +0000 | [diff] [blame] | 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") |