1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/compiler/syntax.py Fri May 18 23:26:30 2012 +0200
1.3 @@ -0,0 +1,46 @@
1.4 +"""Check for errs in the AST.
1.5 +
1.6 +The Python parser does not catch all syntax errors. Others, like
1.7 +assignments with invalid targets, are caught in the code generation
1.8 +phase.
1.9 +
1.10 +The compiler package catches some errors in the transformer module.
1.11 +But it seems clearer to write checkers that use the AST to detect
1.12 +errors.
1.13 +"""
1.14 +
1.15 +from compiler import ast, walk
1.16 +
1.17 +def check(tree, multi=None):
1.18 + v = SyntaxErrorChecker(multi)
1.19 + walk(tree, v)
1.20 + return v.errors
1.21 +
1.22 +class SyntaxErrorChecker:
1.23 + """A visitor to find syntax errors in the AST."""
1.24 +
1.25 + def __init__(self, multi=None):
1.26 + """Create new visitor object.
1.27 +
1.28 + If optional argument multi is not None, then print messages
1.29 + for each error rather than raising a SyntaxError for the
1.30 + first.
1.31 + """
1.32 + self.multi = multi
1.33 + self.errors = 0
1.34 +
1.35 + def error(self, node, msg):
1.36 + self.errors = self.errors + 1
1.37 + if self.multi is not None:
1.38 + print "%s:%s: %s" % (node.filename, node.lineno, msg)
1.39 + else:
1.40 + raise SyntaxError, "%s (%s:%s)" % (msg, node.filename, node.lineno)
1.41 +
1.42 + def visitAssign(self, node):
1.43 + # the transformer module handles many of these
1.44 + pass
1.45 +## for target in node.nodes:
1.46 +## if isinstance(target, ast.AssList):
1.47 +## if target.lineno is None:
1.48 +## target.lineno = node.lineno
1.49 +## self.error(target, "can't assign to list comprehension")