class Compiler: """This class encapsulates all the compiling process.""" def __init__(self): self.setUpLogging() self.debug = False self.input = sys.stdin #We use 'buffer' to get a stream of bytes, not str, because we want to #encode it using utf-8 (just for safety). self.output = sys.stdout.buffer #Create all the data structures needed. self.defCats = {} self.defAttrs = {} self.defVars = {} self.defLists = {} #Initialize all the compiler's components. self.callStack = CallStack() self.symbolTable = SymbolTable() self.codeGenerator = AssemblyCodeGenerator() #here we set the code generator to use self.eventHandler = EventHandler(self) self.parser = ExpatParser(self) def setUpLogging(self): """Set at least an error through stderr logger""" self.formatString = '%(levelname)s: %(filename)s[%(lineno)d]:\t%(message)s' self.logger = logging.getLogger('compiler') errorHandler = logging.StreamHandler(sys.stderr) errorHandler.setFormatter(logging.Formatter(self.formatString)) errorHandler.setLevel(logging.ERROR) self.logger.addHandler(errorHandler) def setDebug(self, fileName): """Set the debug capabilities using the file passed.""" self.debug = True self.codeGenerator.debug = True self.logger.setLevel(logging.DEBUG) debugHandler = logging.FileHandler(filename=fileName, mode='w', encoding='utf-8') debugHandler.setFormatter(logging.Formatter(self.formatString)) debugHandler.setLevel(logging.DEBUG) self.logger.addHandler(debugHandler) def compile(self): try: self.parser.parse(self.input.read()) self.output.write(self.codeGenerator.getWritableCode()) self.logger.debug(str(self.symbolTable)) except (CompilerError, Exception) as e: if self.debug: self.logger.exception(e) else: self.logger.error(e) exit(1)
def __init__(self, xmlfile): # various lists self.def_cats = {} self.def_attrs = {} self.variables = {} self.def_lists = {} self.labels = [] self.codestack = [] # id variables use for labeling, these need to be incremented self.whenid = 0 # otherwiseid, calculated from whenid but initially set to 0 self.otherwiseid = 0 self.actionid = 0 self.pattern_item_count = 0 self.macro_args_count = 0 # state variables self.MACRO_MODE = False self.APPEND_MODE = False self.appendModeArgs = 0 self.NESTED_WHEN_MODE = False self.CONCAT_MODE = False self.concatModeArgs = 0 self.chunkModeArgs = 0 # data structures # whenstack is used for nested when call self.whenStack = [] self.otherwiseStack = [] # callStack holds the call history self.callStack = CallStack() # parentRecord holds the child parent relationship ## self.parentRecord = ParentRecord() self.symbolTable = SymbolTable(self.callStack) # create the parse and the handler self.parser = ExpatParser(xmlfile, self) self.eventHandler = EventHandler(self) self.processedCode = [] self.lazyBuffer = []
def __init__(self): self.setUpLogging() self.debug = False self.input = sys.stdin #We use 'buffer' to get a stream of bytes, not str, because we want to #encode it using utf-8 (just for safety). self.output = sys.stdout.buffer #Create all the data structures needed. self.defCats = {} self.defAttrs = {} self.defVars = {} self.defLists = {} #Initialize all the compiler's components. self.callStack = CallStack() self.symbolTable = SymbolTable() self.codeGenerator = AssemblyCodeGenerator() #here we set the code generator to use self.eventHandler = EventHandler(self) self.parser = ExpatParser(self)
class Compiler(object): """ This is actually a container class that abstracts the underlying logic for the compilation process """ def __init__(self, xmlfile): # various lists self.def_cats = {} self.def_attrs = {} self.variables = {} self.def_lists = {} self.labels = [] self.codestack = [] # id variables use for labeling, these need to be incremented self.whenid = 0 # otherwiseid, calculated from whenid but initially set to 0 self.otherwiseid = 0 self.actionid = 0 self.pattern_item_count = 0 self.macro_args_count = 0 # state variables self.MACRO_MODE = False self.APPEND_MODE = False self.appendModeArgs = 0 self.NESTED_WHEN_MODE = False self.CONCAT_MODE = False self.concatModeArgs = 0 self.chunkModeArgs = 0 # data structures # whenstack is used for nested when call self.whenStack = [] self.otherwiseStack = [] # callStack holds the call history self.callStack = CallStack() # parentRecord holds the child parent relationship ## self.parentRecord = ParentRecord() self.symbolTable = SymbolTable(self.callStack) # create the parse and the handler self.parser = ExpatParser(xmlfile, self) self.eventHandler = EventHandler(self) self.processedCode = [] self.lazyBuffer = [] def compile(self): self.parser.parse() def optimize(self): if len(self.codestack) == 1: for line in self.codestack[0][2]: line = line.encode('utf-8') # optimization 1: remove placeholder instructions (#!#) ## if line.startswith('#!#'): ## continue self.processedCode.append(line) else: raise CompilerException("FATAL ERROR:\n\tCannot optimize code, the code did not compile correctly!\n\tCurrent Codestack length: " + str(len(self.codestack))) def printCode(self): for line in self.processedCode: print line def printLabels(self): for label in self.labels: print label