def VAR_ENTRY(self): print "creating create_varEntry." # create a new class table entry for a variable entry = Entry(self.level, '', 'variable', '') while isinstance(self.attr_buffer[-1], int): entry.arraySize.insert(0, self.attr_buffer.pop()) if len(self.attr_buffer) > 1: nameToken = self.attr_buffer.pop() entry.name = nameToken typeToken = self.attr_buffer.pop() entry.type = typeToken # if variable already in scope give warning foundEntry = self.check_var_in_scope(entry) if isinstance(foundEntry, Entry): self.warnings += "\nWarning: Variable " + str( nameToken) + " already exists in scope here: " + str( foundEntry.name) # if type is a UD_Type, put in dict for 'second pass' circular class dependency checking if entry.type != 'int' and entry.type != 'float' and len( self.SymbolTable_stack ) > 1 and self.SymbolTable_stack[1].name != 'program': if self.SymbolTable_stack[1].name.value in self.classUsageDict: if typeToken not in self.classUsageDict[ self.SymbolTable_stack[1].name.value]: self.classUsageDict[ self.SymbolTable_stack[1].name.value].append(typeToken) else: self.classUsageDict[self.SymbolTable_stack[1].name.value] = [] # append the new entry to the class table if self.SymbolTable_stack: self.SymbolTable_stack[-1].addEntry(entry)
def CLASS_ENTRY_TABLE(self): print "create_classEntryAndTable." # ensure class name does not already exist in Global Table class_entry = Entry(self.level, self.prevToken_buffer, 'class', '') if self.SymbolTable_stack[0].search(class_entry) is None: # log class name in classDict if not there if class_entry.name.value not in self.classUsageDict: self.classUsageDict[class_entry.name.value] = [] # create a table entry and link it to the new class table self.level += 1 class_entry.link = Symbol_Table(self.level, class_entry.name) # append the new entry to the global table and put the reference to the class table on top the stack if self.SymbolTable_stack: self.SymbolTable_stack[-1].addEntry(class_entry) self.SymbolTable_stack.append(class_entry.link) else: # error this class name alreay exists in global table print "Attempting new class entry/table but name " + self.prevToken_buffer.value + " already exists in global table" self.error += "\nError: Duplicate class declaration: " + str( self.prevToken_buffer) print self.error
def FUNC_ENTRY_TABLE(self): print "create_funcEntryAndTable." # ensure function name does not already exist in current scope if len(self.attr_buffer) > 1: func_name = self.attr_buffer.pop() func_type = self.attr_buffer.pop() # create a new global/local table entry and link it to the new class table entry = Entry(self.level, func_name, 'function', func_type) self.level += 1 entry.link = Symbol_Table(self.level, entry.name) if self.SymbolTable_stack[-1].search(entry) is None: # check if in class or global table if len(self.SymbolTable_stack) <= 1: if entry.name.value not in self.classUsageDict: self.classUsageDict[entry.name.value] = [] # append the new entry to the global/class table and put the reference to the class table on top the stack if self.SymbolTable_stack: self.SymbolTable_stack[-1].addEntry(entry) self.SymbolTable_stack.append(entry.link) # save function reference for later type/valid call checking self.function_defs.append(entry) else: # error this function name alreay exists in scope print "Attempting new function but name " + func_name.value + " already exists in scope" self.error += "\nError: Duplicate function declaration: " + str( func_name) print self.error
def FACTOR_ID(self): print 'var or func ID in factor' if len(self.indice_lists) == 0: self.indice_lists.append( [Entry(self.level, self.prevToken_buffer, '', '')]) else: self.indice_lists[-1].append( Entry(self.level, self.prevToken_buffer, '', ''))
def CLASS_ENTRY_TABLE(self): print "create_classEntryAndTable." # create a table entry and link it to the new class table class_entry = Entry(self.level, self.prevToken_buffer, 'class', '') self.level += 1 class_entry.link = Symbol_Table(self.level, class_entry.name) # append the new entry to the global table and put the reference to the class table on top the stack self.SymbolTable_stack[-1].addEntry(class_entry) self.SymbolTable_stack.append(class_entry.link)
def PROGRAM_FUNC_ENTRY_TABLE(self): print 'adding the program function entry and symbol_table.' # create a new global table entry and link it to the new main program function table entry = Entry(self.level, self.prevToken_buffer, 'function', '') self.level += 1 entry.link = Symbol_Table(self.level, entry.name) # append the new entry to the global table and put the reference to the program table on top the stack if self.SymbolTable_stack: self.SymbolTable_stack[-1].addEntry(entry) self.SymbolTable_stack.append(entry.link)
def ASSIGNMENT_VAR(self): print 'Assign Var' entry = Entry(self.level, '', 'assignment', '') # get all arithExpr indices specified and save them in the assignment entry while isinstance(self.attr_buffer[-1], list): entry.IDXorPARAMS.insert(0, self.attr_buffer.pop()) if len(self.attr_buffer) > 0: entry.name = self.attr_buffer.pop() entry = self.ensure_var_exist(entry) if entry is not None and len(self.SymbolTable_stack) > 0: self.SymbolTable_stack[-1].addEntry(entry)
def __init__(self): # symbol tables, self.level = 0 self.SymbolTable_stack = [] # hold attrs while processing a table entry using the grammar rules self.prevToken_buffer = '' self.fParam_buffer = [] self.entry_buffer = Entry(self.level, '', '', '') # the semantic functions dictionary to use when a semantic symbol is poped self.dispatcher = {'CREATE_GLOBAL_TABLE': self.CREATE_GLOBAL_TABLE, 'CLASS_ENTRY_TABLE': self.CLASS_ENTRY_TABLE, 'END_CLASS': self.END_CLASS, 'ENTRY_TYPE': self.ENTRY_TYPE, 'ENTRY_NAME': self.ENTRY_NAME, 'ADD_DECL_ARRAY_DIM': self.ADD_DECL_ARRAY_DIM, 'CLASS_VAR_ENTRY': self.CLASS_VAR_ENTRY, 'FUNC_ENTRY_TABLE': self.FUNC_ENTRY_TABLE, # 'PARAM_TYPE': self.PARAM_TYPE, # 'PARAM_NAME': self.PARAM_NAME, # 'PARAM_NAME': self.PARAM_NAME, 'ADD_FUNC_PARAM_ENTRY': self.ADD_FUNC_PARAM_ENTRY, 'END_CLASS_FUNC': self.END_CLASS_FUNC, 'PROGRAM_FUNC_ENTRY_TABLE': self.PROGRAM_FUNC_ENTRY_TABLE }
def CHECK_VAR_EXIST(self): print "Checking if Variable has been declared for use" print self.attr_buffer if len(self.attr_buffer) > 0: nameToken = self.attr_buffer.pop() temp_entry = Entry(self.level, nameToken.value, 'variable', '') if not self.check_var_in_scope(temp_entry): self.error += "\nError: Variable or Parameter has not been declared: " + str( nameToken)
def PACK_NEST(self): print 'packing and saving nest' # self.warnings += '\nin pack_nest, ' + str(self.SymbolTable_stack[-1].entries[-1].nest) if len(self.SymbolTable_stack[-1].entries[-1].nest) > 0 and len( self.SymbolTable_stack[-1].entries[-1].nest[-1]) == 0: entry = Entry(self.level, '', 'nest', '') # get all arithExpr indices specified and save them in the assignment entry while isinstance(self.attr_buffer[-1], list): entry.IDXorPARAMS.insert(0, self.attr_buffer.pop()) if len(self.attr_buffer) > 0: entry.name = self.attr_buffer.pop() # should change to ensure nest variable exist... #entry = self.ensure_var_exist(entry) if entry is not None and len(self.SymbolTable_stack) > 0: self.SymbolTable_stack[-1].entries[-1].nest[-1].append(entry) # self.assignmentEntryBuffer = entry else: print 'no nest to pack'
def ADD_FUNC_PARAM_ENTRY(self): print 'adding a function parameter entry.' entry = Entry(self.level, '', 'parameter', '') while isinstance(self.attr_buffer[-1], int): entry.arraySize.insert(0, self.attr_buffer.pop()) if len(self.attr_buffer) > 1: nameToken = self.attr_buffer.pop() entry.name = nameToken.value entry.type = self.attr_buffer.pop().value # if variable already in scope give warning if self.check_var_in_scope(entry): self.warnings += "\nWarning: Parameter name already exists in scope: " + str( nameToken) if self.SymbolTable_stack: self.SymbolTable_stack[-1].addEntry(entry) # modify the type of the function entry two layers back if len(self.SymbolTable_stack) > 1: self.SymbolTable_stack[-2].append_param_to_func_entry_type( self.SymbolTable_stack[-1], entry)