python2.6-compiler-package

Annotated compiler/syntax.py

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