diff options
author | Jeremy Hylton <jeremy@alum.mit.edu> | 2001-09-17 18:03:55 (GMT) |
---|---|---|
committer | Jeremy Hylton <jeremy@alum.mit.edu> | 2001-09-17 18:03:55 (GMT) |
commit | 37c9351cf6efbe58e01fd879a1d60cc6073ced6b (patch) | |
tree | ea89cd6bdc54124e7b36b203269c1f68a89442e0 /Lib/compiler/syntax.py | |
parent | 09392b77a4d8be766e394177a466d51c2a64480f (diff) | |
download | cpython-37c9351cf6efbe58e01fd879a1d60cc6073ced6b.zip cpython-37c9351cf6efbe58e01fd879a1d60cc6073ced6b.tar.gz cpython-37c9351cf6efbe58e01fd879a1d60cc6073ced6b.tar.bz2 |
Handle more syntax errors.
Invoke compiler.syntax.check() after building AST. If a SyntaxError
occurs, print the error and exit without generating a .pyc file.
Refactor code to use compiler.misc.set_filename() rather than passing
filename argument around to each CodeGenerator instance.
Diffstat (limited to 'Lib/compiler/syntax.py')
-rw-r--r-- | Lib/compiler/syntax.py | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/Lib/compiler/syntax.py b/Lib/compiler/syntax.py new file mode 100644 index 0000000..14613ef --- /dev/null +++ b/Lib/compiler/syntax.py @@ -0,0 +1,45 @@ +"""Check for errs in the AST. + +The Python parser does not catch all syntax errors. Others, like +assignments with invalid targets, are caught in the code generation +phase. + +The compiler package catches some errors in the transformer module. +But it seems clearer to write checkers that use the AST to detect +errors. +""" + +from compiler import ast, walk + +def check(tree, multi=None): + v = SyntaxErrorChecker(multi) + walk(tree, v) + return v.errors + +class SyntaxErrorChecker: + """A visitor to find syntax errors in the AST.""" + + def __init__(self, multi=None): + """Create new visitor object. + + If optional argument multi is not None, then print messages + for each error rather than raising a SyntaxError for the + first. + """ + self.multi = multi + self.errors = 0 + + def error(self, node, msg): + self.errors = self.errors + 1 + if self.multi is not None: + print "%s:%s: %s" % (node.filename, node.lineno, msg) + else: + raise SyntaxError, "%s (%s:%s)" % (msg, node.filename, node.lineno) + + def visitAssign(self, node): + # the transformer module handles many of these + for target in node.nodes: + if isinstance(target, ast.AssList): + if target.lineno is None: + target.lineno = node.lineno + self.error(target, "can't assign to list comprehension") |