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, '', ''))
예제 #5
0
    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)
예제 #8
0
    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)