コード例 #1
0
 def visit_SimpleType(self, node):
     # Associate a type name such as "int" with a Type object
     node.type = Type.get_by_name(node.name)
     if node.name == 'void':
         self.voidfunc = True
     if node.type is None and self.voidfunc == False:
         error(node.lineno, f"Tipo invalido '{node.name}'")
コード例 #2
0
    def visit_SimpleLocation(self, node):
        if node.name in self.symbols:
            node.type = self.symbols[node.name].type

        elif node.name in self.temp_symbols:
            node.type = self.temp_symbols[node.name].type
        else:
            node.type = None
            error(node.lineno, f"Nombre '{node.name}' no fue definido")
コード例 #3
0
    def visit_IfStatement(self, node):
        self.visit(node.condition)

        cond_type = node.condition.type
        if cond_type:
            if issubclass(node.condition.type, BoolType):
                self.visit(node.true_block)
                self.visit(node.false_block)
            else:
                error(
                    node.lineno,
                    f"'Condicion debe de ser de tipo 'bool' pero tiene tipo '{cond_type.name}'"
                )
コード例 #4
0
 def visit_ConstDeclaration(self, node):
     # For a declaration, you'll need to check that it isn't already defined.
     # You'll put the declaration into the symbol table so that it can be looked up later
     if node.name not in self.symbols:
         # First visit value node to extract its type
         self.visit(node.value)
         node.type = node.value.type
         self.symbols[node.name] = node
     else:
         prev_lineno = self.symbols[node.name].lineno
         error(
             node.lineno,
             f"Nombre '{node.name}' ha sido defino en linea {prev_lineno}")
コード例 #5
0
    def visit_WriteLocation(self, node):
        # First visit the location definition to check that it is a valid
        # location
        self.visit(node.location)
        # Visit the value, to also get type information
        self.visit(node.value)

        node.type = None
        if hasattr(node.location, 'type') and hasattr(node.value, 'type'):
            loc_name = node.location.name
            if loc_name in self.symbols:
                if isinstance(self.symbols[loc_name], ArrayDeclaration):
                    if node.location.size.value >= self.symbols[
                            node.location.
                            name].size or node.location.size.value < 0:
                        error(node.lineno,
                              f"'{loc_name}'  Fuera de rango de arreglo.")
                if isinstance(self.symbols[loc_name], ConstDeclaration):
                    # Basically, if we are writting a to a location that was
                    # declared as a constant, then this is an error
                    error(node.lineno,
                          f"No puedo escribir a una constante '{loc_name}'")
                    return
            else:
                if isinstance(self.temp_symbols[loc_name], ArrayLocalDecl):
                    if node.location.size.value >= self.temp_symbols[
                            node.location.
                            name].size or node.location.size.value < 0:
                        error(node.lineno,
                              f"'{loc_name}'  Fuera de rango de arreglo.")

            # If both have type information, then the type checking worked on
            # both branches
            if node.location.type == node.value.type:
                # Propagate the type
                node.type = node.value.type
            else:
                error(
                    node.lineno,
                    f"No puedo asignar tipo  '{node.value.type.name}' a variable  '{node.location.name}' de tipo '{node.location.type.name}'"
                )
        else:
            ''''''
            if hasattr(node.location.type, 'name'):
                if node.location.type.name != node.value.datatype.name:
                    error(node.lineno, f"No coincide el tipo de dato.")
                elif node.location.name in self.temp_symbols:
                    self.temp_symbols[
                        node.location.name].size = node.value.expr.value
                '''nodee=
コード例 #6
0
    def visit_WhileStatement(self, node):
        self.visit(node.condition)
        self.breakban = True

        cond_type = node.condition.type
        if cond_type:
            if issubclass(node.condition.type, BoolType):
                self.visit(node.body)
                self.breakban = False
            else:
                error(
                    node.lineno,
                    f"'Condicion debe de ser de tipo 'bool' pero es de tipo '{cond_type.name}'"
                )
コード例 #7
0
    def visit_UnaryOp(self, node):
        # Check and propagate the type of the only operand
        self.visit(node.right)

        node.type = None
        if node.right.type:
            op_type = node.right.type.unaryop_type(node.op)
            if not op_type:
                right_tname = node.right.type.name
                error(
                    node.lineno,
                    f"Operacion unaria  '{node.op} {right_tname}' no soportada"
                )

            node.type = op_type
コード例 #8
0
    def visit_FuncCall(self, node):
        if node.name not in self.functions:
            error(node.lineno, f"Funcion '{node.name}' no esta declarada")
        else:
            # We must check that the argument list matches the function
            # parameters definition
            self.visit(node.arguments)

            arg_types = tuple([arg.type.name for arg in node.arguments])
            func = self.functions[node.name]
            expected_types = tuple([param.type.name for param in func.params])
            if arg_types != expected_types:
                error(
                    node.lineno,
                    f"Funcion '{node.name}' espera {expected_types}, pero fue llamada con {arg_types}"
                )

            # The type of the function call is the return type of the function
            node.type = func.datatype.type
コード例 #9
0
    def visit_BinOp(self, node):
        # For operators, you need to visit each operand separately.  You'll
        # then need to make sure the types and operator are all compatible.
        self.visit(node.left)
        self.visit(node.right)

        node.type = None
        # Perform various checks here
        if node.left.type and node.right.type:
            op_type = node.left.type.binop_type(node.op, node.right.type)
            if not op_type:
                left_tname = node.left.type.name
                right_tname = node.right.type.name
                error(
                    node.lineno,
                    f"Operacion binaria '{left_tname} {node.op} {right_tname}' no soportada"
                )

            node.type = op_type
コード例 #10
0
def listener(messages):
	#Guarda mensajes--------------------------------------------------------------------------------------------------------------------------
	try:
		for m in messages:
			cid = m.chat.id
			if cid > 0:
				mensaje = str(m.chat.first_name) + "(" + str(cid) + ")" + str(m.text)
			else:
				uid = m.from_user.id
				mensaje = str(m.chat.first_name) + "-" + str(m.from_user.first_name)
				mensaje += "(" + str(cid) + "*" + str(uid) + ")" + str(m.text)
			with open(reg_arch,"a") as arch:
				arch.write(mensaje + "\n")	
			print(mensaje)					
	except:
		try:
			error(sys.exc_info()[0],"listener")
		except:
			error(None, "listener")
コード例 #11
0
    def visit_ArrayLocalDeclaration(self, node):
        # Here we must update the symbols table with the new symbol
        node.type = None

        # Before anything, if we are declaring a variable with a name that is
        # a typename, then we must fail
        if node.name in self.keywords:
            error(
                node.lineno,
                f"Nombre '{node.name}' no es legal para declaracion de variable"
            )
            return

        if node.name not in self.symbols:
            # First check that the datatype node is correct
            self.visit(node.datatype)

            if node.datatype.type:
                node.type = node.datatype.type
                self.symbols[node.name] = node

            else:
                error(node.lineno, f"Tipo desconocido  '{node.datatype.name}'")
        else:
            prev_lineno = self.symbols[node.name].lineno
            error(
                node.lineno,
                f"Nombre '{node.name}' ya ha sido definido en linea {prev_lineno}"
            )
コード例 #12
0
    def visit_ReadLocation(self, node):
        # Associate a type name such as "int" with a Type object
        self.visit(node.location)
        loc_name = node.location.name

        if loc_name in self.symbols:
            if isinstance(self.symbols[loc_name], ArrayDeclaration):
                if node.location.size.value >= self.symbols[
                        node.location.
                        name].size.value or node.location.size.value < 0:
                    error(node.lineno,
                          f" '{loc_name}' Fuera de rango del arreglo.")

        if loc_name in self.temp_symbols:
            if isinstance(self.temp_symbols[loc_name], ArrayLocalDeclaration):
                if node.location.size.value >= self.temp_symbols[
                        node.location.
                        name].size.value or node.location.size.value < 0:
                    error(node.lineno,
                          f" '{loc_name}'Fuera del rango del arreglo. ")

        node.type = node.location.type
コード例 #13
0
    def visit_VarDeclaration(self, node):
        # Here we must update the symbols table with the new symbol
        node.type = None

        # Before anything, if we are declaring a variable with a name that is
        # a typename, then we must fail
        if node.name in self.keywords:
            error(
                node.lineno,
                f"Nombre '{node.name}' no es legal para declaracion de variable"
            )
            return

        if node.name not in self.symbols:
            # First check that the datatype node is correct
            self.visit(node.datatype)

            if node.datatype.type:
                # Before finishing, this var declaration may have an expression
                # to initialize it. If so, we must visit the node, and check
                # type errors
                if node.value:
                    self.visit(node.value)

                    if node.value.type:  # If value has no type, then there was a previous error
                        if node.value.type == node.datatype.type:
                            # Great, the value type matches the variable type
                            # declaration
                            node.type = node.datatype.type
                            self.symbols[node.name] = node
                        else:
                            error(
                                node.lineno,
                                f"Declarando variable '{node.name}' de tipo '{node.datatype.type.name}' pero asignada a expresion de tipo '{node.value.type.name}'"
                            )
                else:
                    # There is no initialization, so we have everything needed
                    # to save it into our symbols table
                    node.type = node.datatype.type
                    self.symbols[node.name] = node
            else:
                error(node.lineno, f"Tipo desconocido  '{node.datatype.name}'")
        else:
            prev_lineno = self.symbols[node.name].lineno
            error(
                node.lineno,
                f"Nombre '{node.name}' ya ha sido definido en linea {prev_lineno}"
            )
コード例 #14
0
    def visit_FuncDeclaration(self, node):
        if node.name in self.functions:
            prev_def = self.functions[node.name].lineno
            error(node.lineno,
                  f"Funcion '{node.name}' ya definida en linea {prev_def}")

        self.visit(node.params)

        param_types_ok = all((param.type is not None for param in node.params))
        param_names = [param.name for param in node.params]
        param_names_ok = len(param_names) == len(set(param_names))
        if not param_names_ok:
            error(node.lineno,
                  "Nombre de parametro duplicado en la definicion de funcion")

        self.visit(node.datatype)
        ret_type_ok = node.datatype.type is not None

        # Before visiting the function, body, we must change the symbol table
        # to a new one
        if self.temp_symbols:
            error(node.lineno,
                  f"Declaracion de funcion anidada ilegal '{node.name}'")
        else:
            self.temp_symbols = self.symbols
            self.symbols = ChainMap(
                {param.name: param
                 for param in node.params}, self.temp_symbols)
            # Set the expected return value to observe
            self.expected_ret_type = node.datatype.type

            self.visit(node.body)

            if not self.current_ret_type:
                error(node.lineno,
                      f"Funcion '{node.name}' no tiene fumcion de return")
            elif self.current_ret_type == self.expected_ret_type:
                # We must add the function declaration as available for
                # future calls
                self.functions[node.name] = node

            self.symbols = self.temp_symbols
            self.temp_symbols = {}
            self.expected_ret_type = None
            self.current_ret_type = None
コード例 #15
0
 def visit_ReturnStatement(self, node):
     self.visit(node.value)
     # Propagate return value type as a special property ret_type, only
     # to be checked at function declaration checking
     if self.expected_ret_type or self.voidfunc == True:
         if (node.value):
             if self.voidfunc == True:
                 error(node.lineno,
                       f'Return de funcion void debe ser un void')
             else:
                 self.current_ret_type = node.value.type
                 if node.value.type and node.value.type != self.expected_ret_type:
                     error(
                         node.lineno,
                         f"Return de funcion '{self.expected_ret_type.name}'debe retornar una sentencia de valor de tipo'{self.expected_ret_type.name}'"
                     )
     else:
         error(node.lineno,
               "Instruccion return debe de estar dentro de una funcion")
コード例 #16
0
 def ERRO(self, t):
     error(self.lineno, 'Comentario anidado')
     self.index += 1
コード例 #17
0
 def error(self, t):
     error(self.lineno, 'Caracter Ilegal %r' % t.value[0])
     self.index += 1
コード例 #18
0
 def visit_NewArrayExpression(self, node):
     self.visit(node.datatype)
     self.visit(node.expr)
     if node.datatype.name != node.expr.type.name:
         error(node.lineno, f"Tipo de dato no coincide.")
コード例 #19
0
 def visit_BreakStatement(self, node):
     if self.breakban == False:
         error(node.lineno, f"El break esta fuera de un ciclo.")
コード例 #20
0
ファイル: cparse.py プロジェクト: bgoz/Minic
 def error(self, p):
     if p:
         error(p.lineno,
               "Error de sintaxis en la entrada en el token '%s'" % p.value)
     else:
         error('EOF', 'Error de sintaxis. No mas entrada.')