コード例 #1
0
    def check_declarations(self, declarations):
        """Checks for multiple declarations of the same pids
        and range of arrays.
        If no errors then return list with declared pids
        """
        # Checking for multiple declarations
        declared = []
        doubled = []
        for pid in declarations:
            if pid[1] not in declared:
                declared.append(pid[1])
                self.symtab.append(pid[:-1])
            else:
                doubled.append(pid)

        if doubled:
            for pid in doubled:
                logging.error('Double declaration "{}" in line {}'.format(
                    pid[1], pid[-1]))
            raise CompilerError()

        # Checkig arrays ranges
        for pid in declarations:
            if pid[0] == 'arr':
                if pid[2] > pid[3]:
                    logging.error(
                        'Array "{}" in line {} has wrong ranges'.format(
                            pid[1], pid[-1]))
                    raise CompilerError()

        return declared
コード例 #2
0
    def check_pid(self, pid):
        if is_number(pid):
            return
        if pid[1] in self.tmp_vars:
            return

        if pid[1] not in self.declared:
            logging.error('Variable "{}" not declared, line {}'.format(
                pid[1], pid[-1]))
            raise CompilerError()

        if pid[0] == 'arr':
            if is_number(pid[2]):
                return
            if pid[2] in self.tmp_vars:
                return
            if pid[2] not in self.declared:
                logging.error('Variable "{}" not declared, line {}'.format(
                    pid[2], pid[-1]))
                raise CompilerError()

        for iden in self.symtab:
            if iden[1] == pid[1]:
                if iden[0] != pid[0]:
                    logging.error(
                        'Wrong "{}" has another type, line {}'.format(
                            pid[1], pid[-1]))
                    raise CompilerError()
コード例 #3
0
 def check_variable(self, variable):
     if is_int(variable):
         self.check_int(variable)
     elif is_array(variable):
         self.check_inttab(variable)
     else:
         raise CompilerError("Unexpected variable type")
コード例 #4
0
ファイル: parser.py プロジェクト: piotrszyma/ply-compiler
 def parse(self, source_code):
     if source_code:
         return self.parser.parse(source_code,
                                  lexer=self.lexer.lexer,
                                  debug=False)
     else:
         raise CompilerError("Input file is empty")
コード例 #5
0
    def operation_add(self, target, operands):
        x, y = operands

        if is_array(x) and is_array(y):
            pass

        if is_number(x):
            if is_number(y):
                self.parse('GENERATE n', n=x + y)
                self.parse('STORE t', t=target)
                return
            else:
                x, y = y, x

        # t := a + 1
        if is_number(y):
            if y == 0:
                self.parse('LOAD x', x=x)
            elif y == 1:
                self.parse('LOAD x', x=x)
                self.parse('INC')
            else:
                self.parse('GENERATE n', n=y)
                self.parse('ADD x', x=x)
        # t := a + b
        # t := a + b[x]
        elif is_variable(y):
            self.parse('LOAD x', x=x)
            self.parse('ADD y', y=y)
        else:
            raise CompilerError("Unexpected symbol")

        self.parse('STORE a', a=target)
コード例 #6
0
 def operation_substract(self, target, operands):
     x, y = operands
     if is_number(x):
         # t := 1 - 1
         if is_number(y):
             if x - y > 0:
                 self.parse('GENERATE n', n=x - y)
             else:
                 self.parse('ZERO')
         # t := 1 - a
         # t := 1 - a[x]
         elif is_variable(y):
             self.parse('GENERATE n', n=x)
             self.parse('SUB a', a=y)
     elif is_variable(x):
         # t := a - 1
         if is_number(y):
             if y == 0:
                 self.parse('LOAD a', a=x)
             elif y == 1:
                 self.parse('LOAD a', a=x)
                 self.parse('DEC')
             else:
                 self.parse('GENERATE n', n=y)
                 self.parse('STORE a', a=Reg.r0)
                 self.parse('LOAD x', x=x)
                 self.parse('SUB a', a=Reg.r0)
         # t := a - b
         # t := a - b[x]
         elif is_variable(y):
             self.parse('LOAD a', a=x)
             self.parse('SUB a', a=y)
         else:
             raise CompilerError("Unexpected symbol")
     self.parse('STORE a', a=target)
コード例 #7
0
ファイル: utils.py プロジェクト: piotrszyma/ply-compiler
def raise_error(msg, lineno=None):
    error_msg = ""
    if lineno:
        error_msg += " in line {0}: ".format(lineno)
    error_msg += msg
    logging.error(error_msg)
    raise CompilerError()
コード例 #8
0
ファイル: lexer.py プロジェクト: piotrszyma/ply-compiler
 def t_ANY_error(self, t):
     if t.value[0] == ')':
         error_msg = " In line {}: Are you trying to close unopened comment?".format(
             t.lexer.lineno)
     else:
         error_msg = " In line {}: Illegal character '{}'".format(
             t.lexer.lineno, t.value[0])
     raise CompilerError(error_msg)
コード例 #9
0
 def test(self, data):
     self.lexer.input(data)
     while True:
         tok = self.lexer.token()
         if not tok:
             break
         else:
             logging.error('Lexer error')
             raise CompilerError()
コード例 #10
0
 def check_iterator(self, iterator):
     _, iter_symbol, iter_lineno = iterator
     if iter_symbol in self.scope:
         raise_error(
             msg=
             "trying to set previously declared variable '{0}' as iterator".
             format(iter_symbol),
             lineno=iter_lineno)
         raise CompilerError()
コード例 #11
0
    def check_initialization(self, pid):
        if is_number(pid):
            return
        if pid[1] in self.tmp_vars:
            return

        if pid[1] not in self.initialized:
            logging.error(
                'Using uninitialized variable "{}" in line {}'.format(
                    pid[1], pid[-1]))
            raise CompilerError()
コード例 #12
0
 def assign(self, target, expression):
     _, *value = expression
     if is_operation(value):
         self.assign_operation(target, value)
     else:
         if is_variable(value[0]):
             self.assign_variable(target, value[0])
         elif is_number(value[0]):
             self.assign_number(target, value[0])
         else:
             raise CompilerError("Unknown value type")
コード例 #13
0
 def check_scope(self, operand):
     if is_number(operand):
         pass
     elif is_int(operand):
         if operand[1] not in self.scope:
             raise_error(msg="Undeclared variable {}".format(operand[1]),
                         lineno=operand[2])
     elif is_array(operand):
         if is_number(operand[2]):
             self.check_inttab(operand)
     else:
         raise CompilerError("Unexpected operand")
コード例 #14
0
    def check_inttab(self, variable):
        _, symbol, index, lineno = variable

        arr_start = '#'.join([symbol, '0'])

        if arr_start not in self.scope:
            raise_error("Usage of undeclared array {}".format(symbol), lineno)
        if is_number(index):
            self.check_inttab_index(variable)
        elif is_int(index):
            self.check_variable(index)
        else:
            raise CompilerError("Unexpected array index")
コード例 #15
0
 def check_expression(self, cmd):
     _, *expression = cmd
     if len(expression) == 1:
         [var] = expression
         if is_variable(var):
             self.check_variable(var)
             self.check_initialized(var)
     elif len(expression) == 3:
         [_, l_var, r_var] = expression
         for var in [l_var, r_var]:
             if is_variable(var):
                 self.check_variable(var)
                 self.check_initialized(var)
     else:
         raise CompilerError("Unexpected expression")
コード例 #16
0
    def check_assign(self, cmd):
        _, target, expression = cmd
        self.check_scope(target)

        if is_int(target):
            _, symbol, lineno = target
            if symbol in self.iterators:
                raise_error(
                    "Mutation of iterator '{symbol}'".format(symbol=symbol),
                    lineno)
        elif is_array(target):
            _, symbol, index, _ = target
            symbol = '#'.join([symbol, str(index)])
        else:
            raise CompilerError("Unexpected target type")

        self.check_expression(expression)
        self.initialized[symbol] = True
コード例 #17
0
    def parse_array(self, left, right):
        _, var, index, *_ = right
        if is_number(index):
            array = self.mem['{}#0'.format(var)]
            arr_addr = array['address']
            cell_addr = index + arr_addr
            code = '{cmd} {param}'.format(cmd=left, param=cell_addr)
            self.code.append(code)
        elif is_reg(index):
            self.code.append('{cmd}I {reg}'.format(cmd=left, reg=index[1]))
        elif is_variable(index):
            left += 'I'
            array = self.mem['{}#0'.format(var)]
            arr_start_ptr = array['start_ptr']
            if left == 'LOADI':
                self.code.append(
                    'LOAD {arr_start_ptr}'.format(arr_start_ptr=arr_start_ptr))
                code = """
                ADD x
                STORE r9
                LOADI r9
                """
                self.parse(code, x=index, r9=Reg.r9)
            elif left in ['STOREI', 'ADDI', 'SUBI']:
                self.parse("""
                STORE r8
                """,
                           r8=Reg.r8)

                self.code.append(
                    'LOAD {arr_start_ptr}'.format(arr_start_ptr=arr_start_ptr))

                code = """ADD x
                STORE r9
                LOAD r8
                {cmd} r9
                """.format(cmd=left, arr_size=arr_start_ptr)
                self.parse(code, x=index, r9=Reg.r9, r8=Reg.r8)
            else:
                raise CompilerError("Unexpected command")
コード例 #18
0
ファイル: lexer.py プロジェクト: piotrszyma/ply-compiler
 def t_comment_eof(self, t):
     raise CompilerError(" In line %d: Unterminated comment" %
                         t.lexer.lineno)
コード例 #19
0
 def read(self, target):
     if is_variable(target):
         self.read_variable(target)
     else:
         raise CompilerError("Cannot READ non-variable")
コード例 #20
0
ファイル: parser.py プロジェクト: piotrszyma/ply-compiler
 def p_error(self, p):
     logging.error(" in line {lineno}: unknown symbol '{value}'".format(
         lineno=p.lineno,
         value=p.value
     ))
     raise CompilerError()
コード例 #21
0
 def parse(self, data):
     if data:
         return self.parser.parse(data, self.lexer.lexer, 0, 0, None)
     else:
         logging.error("Input file is empty")
         raise CompilerError()
コード例 #22
0
 def t_error(self, t):
     logging.error(f'Illegal character {t.value[0]} in line {t.lineno}')
     raise CompilerError()
コード例 #23
0
 def p_error(self, p):
     logging.error(f"Syntax error '{p.value}' in line {p.lineno}")
     raise CompilerError()