[Python-checkins] CVS: python/dist/src/Tools/compiler/compiler syntax.py,NONE,1.1 pycodegen.py,1.52,1.53

Jeremy Hylton jhylton@users.sourceforge.net
2001年9月17日 11:03:57 -0700


Update of /cvsroot/python/python/dist/src/Tools/compiler/compiler
In directory usw-pr-cvs1:/tmp/cvs-serv3558
Modified Files:
	pycodegen.py 
Added Files:
	syntax.py 
Log Message:
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.
--- NEW FILE: syntax.py ---
"""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")
Index: pycodegen.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Tools/compiler/compiler/pycodegen.py,v
retrieving revision 1.52
retrieving revision 1.53
diff -C2 -d -r1.52 -r1.53
*** pycodegen.py	2001年09月17日 16:41:02	1.52
--- pycodegen.py	2001年09月17日 18:03:55	1.53
***************
*** 9,13 ****
 from cStringIO import StringIO
 
! from compiler import ast, parse, walk
 from compiler import pyassem, misc, future, symbols
 from compiler.consts import SC_LOCAL, SC_GLOBAL, SC_FREE, SC_CELL
--- 9,13 ----
 from cStringIO import StringIO
 
! from compiler import ast, parse, walk, syntax
 from compiler import pyassem, misc, future, symbols
 from compiler.consts import SC_LOCAL, SC_GLOBAL, SC_FREE, SC_CELL
***************
*** 42,47 ****
 self.loop = None
 
- 
- 
 def compile(filename, display=0):
 f = open(filename)
--- 42,45 ----
***************
*** 49,56 ****
 f.close()
 mod = Module(buf, filename)
! mod.compile(display)
! f = open(filename + "c", "wb")
! mod.dump(f)
! f.close()
 
 class Module:
--- 47,58 ----
 f.close()
 mod = Module(buf, filename)
! try:
! mod.compile(display)
! except SyntaxError, err:
! print "SyntaxError:", err
! else:
! f = open(filename + "c", "wb")
! mod.dump(f)
! f.close()
 
 class Module:
***************
*** 62,66 ****
 def compile(self, display=0):
 tree = parse(self.source)
! gen = ModuleCodeGenerator(self.filename, tree)
 if display:
 import pprint
--- 64,70 ----
 def compile(self, display=0):
 tree = parse(self.source)
! misc.set_filename(self.filename, tree)
! syntax.check(tree)
! gen = ModuleCodeGenerator(tree)
 if display:
 import pprint
***************
*** 150,159 ****
 class_name = None # provide default for instance variable
 
! def __init__(self, filename):
 if self.__initialized is None:
 self.initClass()
 self.__class__.__initialized = 1
 self.checkClass()
- self.filename = filename
 self.locals = misc.Stack()
 self.setups = misc.Stack()
--- 154,162 ----
 class_name = None # provide default for instance variable
 
! def __init__(self):
 if self.__initialized is None:
 self.initClass()
 self.__class__.__initialized = 1
 self.checkClass()
 self.locals = misc.Stack()
 self.setups = misc.Stack()
***************
*** 307,311 ****
 
 def _visitFuncOrLambda(self, node, isLambda=0):
! gen = self.FunctionGen(node, self.filename, self.scopes, isLambda,
 self.class_name, self.get_module())
 walk(node.code, gen)
--- 310,314 ----
 
 def _visitFuncOrLambda(self, node, isLambda=0):
! gen = self.FunctionGen(node, self.scopes, isLambda,
 self.class_name, self.get_module())
 walk(node.code, gen)
***************
*** 325,329 ****
 
 def visitClass(self, node):
! gen = self.ClassGen(node, self.filename, self.scopes,
 self.get_module())
 if node.doc:
--- 328,332 ----
 
 def visitClass(self, node):
! gen = self.ClassGen(node, self.scopes,
 self.get_module())
 if node.doc:
***************
*** 431,435 ****
 if not self.setups:
 raise SyntaxError, "'break' outside loop (%s, %d)" % \
! (self.filename, node.lineno)
 self.set_lineno(node)
 self.emit('BREAK_LOOP')
--- 434,438 ----
 if not self.setups:
 raise SyntaxError, "'break' outside loop (%s, %d)" % \
! (node.filename, node.lineno)
 self.set_lineno(node)
 self.emit('BREAK_LOOP')
***************
*** 438,442 ****
 if not self.setups:
 raise SyntaxError, "'continue' outside loop (%s, %d)" % \
! (self.filename, node.lineno)
 kind, block = self.setups.top()
 if kind == LOOP:
--- 441,445 ----
 if not self.setups:
 raise SyntaxError, "'continue' outside loop (%s, %d)" % \
! (node.filename, node.lineno)
 kind, block = self.setups.top()
 if kind == LOOP:
***************
*** 455,464 ****
 if kind != LOOP:
 raise SyntaxError, "'continue' outside loop (%s, %d)" % \
! (self.filename, node.lineno)
 self.emit('CONTINUE_LOOP', loop_block)
 self.nextBlock()
 elif kind == END_FINALLY:
 msg = "'continue' not allowed inside 'finally' clause (%s, %d)" 
! raise SyntaxError, msg % (self.filename, node.lineno)
 
 def visitTest(self, node, jump):
--- 458,467 ----
 if kind != LOOP:
 raise SyntaxError, "'continue' outside loop (%s, %d)" % \
! (node.filename, node.lineno)
 self.emit('CONTINUE_LOOP', loop_block)
 self.nextBlock()
 elif kind == END_FINALLY:
 msg = "'continue' not allowed inside 'finally' clause (%s, %d)" 
! raise SyntaxError, msg % (node.filename, node.lineno)
 
 def visitTest(self, node, jump):
***************
*** 1086,1093 ****
 scopes = None
 
! def __init__(self, filename, tree):
! self.graph = pyassem.PyFlowGraph("<module>", filename)
 self.futures = future.find_futures(tree)
! self.__super_init(filename)
 walk(tree, self)
 
--- 1089,1096 ----
 scopes = None
 
! def __init__(self, tree):
! self.graph = pyassem.PyFlowGraph("<module>", tree.filename)
 self.futures = future.find_futures(tree)
! self.__super_init()
 walk(tree, self)
 
***************
*** 1099,1103 ****
 lambdaCount = 0
 
! def __init__(self, func, filename, scopes, isLambda, class_name, mod):
 self.class_name = class_name
 self.module = mod
--- 1102,1106 ----
 lambdaCount = 0
 
! def __init__(self, func, scopes, isLambda, class_name, mod):
 self.class_name = class_name
 self.module = mod
***************
*** 1109,1116 ****
 name = func.name
 args, hasTupleArg = generateArgList(func.argnames)
! self.graph = pyassem.PyFlowGraph(name, filename, args, 
 optimized=1) 
 self.isLambda = isLambda
! self.super_init(filename)
 
 if not isLambda and func.doc:
--- 1112,1119 ----
 name = func.name
 args, hasTupleArg = generateArgList(func.argnames)
! self.graph = pyassem.PyFlowGraph(name, func.filename, args, 
 optimized=1) 
 self.isLambda = isLambda
! self.super_init()
 
 if not isLambda and func.doc:
***************
*** 1163,1170 ****
 __super_init = AbstractFunctionCode.__init__
 
! def __init__(self, func, filename, scopes, isLambda, class_name, mod):
 self.scopes = scopes
 self.scope = scopes[func]
! self.__super_init(func, filename, scopes, isLambda, class_name, mod)
 self.graph.setFreeVars(self.scope.get_free_vars())
 self.graph.setCellVars(self.scope.get_cell_vars())
--- 1166,1173 ----
 __super_init = AbstractFunctionCode.__init__
 
! def __init__(self, func, scopes, isLambda, class_name, mod):
 self.scopes = scopes
 self.scope = scopes[func]
! self.__super_init(func, scopes, isLambda, class_name, mod)
 self.graph.setFreeVars(self.scope.get_free_vars())
 self.graph.setCellVars(self.scope.get_cell_vars())
***************
*** 1175,1184 ****
 class AbstractClassCode:
 
! def __init__(self, klass, filename, scopes, module):
 self.class_name = klass.name
 self.module = module
! self.graph = pyassem.PyFlowGraph(klass.name, filename,
 optimized=0, klass=1)
! self.super_init(filename)
 lnf = walk(klass.code, self.NameFinder(), verbose=0)
 self.locals.push(lnf.getLocals())
--- 1178,1187 ----
 class AbstractClassCode:
 
! def __init__(self, klass, scopes, module):
 self.class_name = klass.name
 self.module = module
! self.graph = pyassem.PyFlowGraph(klass.name, klass.filename,
 optimized=0, klass=1)
! self.super_init()
 lnf = walk(klass.code, self.NameFinder(), verbose=0)
 self.locals.push(lnf.getLocals())
***************
*** 1201,1208 ****
 __super_init = AbstractClassCode.__init__
 
! def __init__(self, klass, filename, scopes, module):
 self.scopes = scopes
 self.scope = scopes[klass]
! self.__super_init(klass, filename, scopes, module)
 self.graph.setFreeVars(self.scope.get_free_vars())
 self.graph.setCellVars(self.scope.get_cell_vars())
--- 1204,1211 ----
 __super_init = AbstractClassCode.__init__
 
! def __init__(self, klass, scopes, module):
 self.scopes = scopes
 self.scope = scopes[klass]
! self.__super_init(klass, scopes, module)
 self.graph.setFreeVars(self.scope.get_free_vars())
 self.graph.setCellVars(self.scope.get_cell_vars())

AltStyle によって変換されたページ (->オリジナル) /