예제 #1
0
 def control_type(type_type, type_name):
     """
     Function check syntax of type
     :param type_type: Must be type in argument
     :param type_name: Must be in types  else it's error
     """
     types = ["bool", "int", "string", "nil", "float"]
     if type_type == "type":
         if type_name not in types:
             raise ERRConstruction(
                 "{} : Wrong format of type.".format(type_name))
     else:
         raise ERRConstruction("Expected type, got {}".format(type_name))
예제 #2
0
 def control_var(var_type, var_name, var_name_re):
     """
     Function check shape of variable
     var[0] should be "var"
     var[1] is name of variable in shape Frame@{not-digit}{any char}
     :param var_type: Type of variable to be checked
     :param var_name: Name of variable to be checked
     :param var_name_re: pre-compiled regex for name of variable
     """
     if var_type != "var":
         raise ERRConstruction(
             "Wrong XML argument type - expected variable, not {}.".format(
                 var_type))
     if var_name_re.fullmatch(var_name) is None:
         raise ERRConstruction(
             "Variable {} has wrong format. ".format(var_name))
예제 #3
0
 def control_label(label_type, label_name, label_name_re):
     """
     Function checks shape of label
     :param label_type: label type to check
     :param label_name: label name to check by regex
     :param label_name_re: label regex
     """
     if label_type == "label":
         if label_name_re.fullmatch(label_name) is None:
             raise ERRConstruction(
                 "Label {} doesnt have right name.".format(label_name))
         else:
             return
     else:
         raise ERRConstruction(
             "{} should be label, it isnt.".format(label_name))
예제 #4
0
 def control_number_of_arguments(expected_arguments,
                                 real_number_of_arguments):
     """
     Function check if the number of arguments is the same as expected
     :param expected_arguments: Number of expected arguments
     :param real_number_of_arguments:  Number of real arguments
     """
     if expected_arguments != real_number_of_arguments:
         raise ERRConstruction("Instruction has wrong number of arguments.")
예제 #5
0
 def parse_header(mytree):
     """
     Function control XML header that should be in form of: <program language="IPPcode20">
     """
     my_root = mytree.getroot()
     if my_root.tag != "program":
         raise ERRConstruction("Root element isn't 'program'.")
     for attrib, val in my_root.attrib.items():
         val = val.upper()
         if attrib == "language" and val != "IPPCODE20":
             raise ERRConstruction(
                 "Attribute language has to have value 'IPPcode20'.")
         elif attrib == "language" and val == "IPPCODE20":
             continue
         elif attrib != "name" and attrib != "description":
             raise ERRConstruction(
                 "Not allowed attribute: {} in root.".format(attrib))
     return my_root
예제 #6
0
 def parse_arguments(
     my_child,
     opcode,
     actual_order,
     arg_re,
     code,
 ):
     """
     Function controls arguments of instruction
     #TODO check number of arguments and order it
     :param my_child: One instruction
     :param opcode: Opcode of instructon
     :param arg_re: Regex for instruction - already compiled
     :param code: List with all instruction (opcode + arguments)
     """
     interpret = InstructionChecker()
     arguments = []
     arg_list = []
     for my_arguments in my_child:
         if arg_re.fullmatch(my_arguments.tag) is None:
             raise ERRConstruction(
                 "Expected tag arg(number), not {}".format(
                     my_arguments.tag))
         arg_num = int(my_arguments.tag[3:])
         for attribs, vals in my_arguments.attrib.items():
             if attribs != "type":
                 raise ERRConstruction(
                     "Unexpected attribute in arguments in instruction!")
         arg_list.append(
             [arg_num, my_arguments.attrib["type"], my_arguments.text])
     arg_list.sort(key=itemgetter(0))
     i = 0
     while len(arg_list) > len(arguments):
         if arg_list[i][0] != i + 1:
             raise ERRConstruction("Missing arguments!")
         arguments.append([arg_list[i][1], arg_list[i][2]])
         i += 1
     interpret.check_instruction(opcode, arguments)
     code.code_to_interpret.append([actual_order, opcode, arguments])
예제 #7
0
 def control_symb(self, symb_type, symb_name, var_name_re, const_name_re):
     """
     Function checks shape of symbol - constant or var and
     If there is string constant, function transform escape sequences to chars and continues control
     :param symb_type: symbol type to be checked
     :param symb_name: symbol name to be checked
     :param var_name_re: variable regex
     :param const_name_re: constant regex
     :return Return symbol_type and symbol_name
     """
     if symb_type == "var":
         if var_name_re.fullmatch(symb_name) is None:
             raise ERRConstruction(
                 "Symbol should be variable, but name {} doesnt match.".
                 format(symb_name))
     elif symb_type == "int" or symb_type == "bool" or symb_type == "nil":
         if symb_name is None:
             symbol = symb_type + "@"
         else:
             symbol = symb_type + "@" + symb_name
         if const_name_re.fullmatch(symbol) is None:
             raise ERRConstruction(
                 "{}: Wrong format of constant.".format(symbol))
     elif symb_type == "float":
         try:
             symb_name = float.fromhex(symb_name)
         except (ValueError, TypeError):
             raise ERRConstruction("Wrong format of float")
     elif symb_type == "string":
         if symb_name is None:
             symb_name = ''
         if re.search('[\s#]', symb_name) is not None:
             raise ERRConstruction(
                 "Symbol {} contains not allowed characters (white spaces, #)."
                 .format(symb_name))
         symb_name = self.escape_seq(symb_name)
         if re.search('[\\\\]', symb_name) is not None:
             raise ERRConstruction(
                 "Symbol {} contains not allowed characters (backspace not in escape seq)"
                 .format(symb_name))
     else:
         raise ERRConstruction(
             "Symbol {} isnt constant nor variable.".format(symb_name))
     return symb_type, symb_name
예제 #8
0
    def parse_program(self, my_root, stats):
        """
        Function parse XML instruction code and controls instruction attribute (order and opcode)
        #TODO order can be in different structure (1 5 7 4 ) and this func should order it
        At the end, function calls code.control which basically interpret instructions
        """
        arg_re = re.compile("arg[0-9]+")  # regex for controlling arguments
        frame = Frames()
        code = Interpret(frame, self.input_source, stats)

        order_number = []
        for my_child in my_root:
            if my_child.tag != "instruction":
                raise ERRConstruction("{} should be instruction.".format(
                    my_child.tag))
            if "opcode" not in my_child.attrib or "order" not in my_child.attrib:
                raise ERRConstruction(
                    "Missing opcode or order in instruction attribute.")

            opcode = ''
            actual_order = 0
            for attrib, val in my_child.attrib.items():
                if attrib == "order":
                    try:
                        if int(val) < 1:
                            raise ERRConstruction("Order lesser or equal 0.")
                    except ValueError:
                        raise ERRConstruction(
                            "Trying to convert string that doesn't contain number to int."
                        )
                    if int(val) not in order_number:
                        order_number.append(int(val))
                        actual_order = int(val)
                    else:
                        raise ERRConstruction("Duplicit order!")
                elif attrib == "opcode":
                    opcode = val.upper()
                else:
                    raise ERRConstruction("Attribute isn't opcode or order!")
            self.parse_arguments(my_child, opcode, actual_order, arg_re, code)
        code.control()
예제 #9
0
 def check_instruction(self, opcode, args):
     """
     Function controls syntax and lexical side of instruction
     Function also rewrites symbol in args after checking (delete escape sequences)
     At the end, function adds opcode and it's arguments to list of all code that is later used in interpretation
     :param opcode: Name of instruction
     :param args: Arguments of instruction
     :param code: List where is all code stored
     """
     opcode = opcode.upper()  # changes given opcode to uppercase
     if opcode in self.opcode:
         self.control_number_of_arguments(
             expected_arguments=0, real_number_of_arguments=len(args))
     elif opcode in self.opcode_var:
         self.control_number_of_arguments(
             expected_arguments=1, real_number_of_arguments=len(args))
         self.control_var(var_type=args[0][0],
                          var_name=args[0][1],
                          var_name_re=self.var_name_re)
     elif opcode in self.opcode_var_symb1_symb2:
         self.control_number_of_arguments(
             expected_arguments=3, real_number_of_arguments=len(args))
         self.control_var(var_type=args[0][0],
                          var_name=args[0][1],
                          var_name_re=self.var_name_re)
         args[1][0], args[1][1] = self.control_symb(
             self,
             symb_type=args[1][0],
             symb_name=args[1][1],
             var_name_re=self.var_name_re,
             const_name_re=self.const_name_re)
         args[2][0], args[2][1] = self.control_symb(
             self,
             symb_type=args[2][0],
             symb_name=args[2][1],
             var_name_re=self.var_name_re,
             const_name_re=self.const_name_re)
     elif opcode in self.opcode_var_symb:
         self.control_number_of_arguments(
             expected_arguments=2, real_number_of_arguments=len(args))
         self.control_var(var_type=args[0][0],
                          var_name=args[0][1],
                          var_name_re=self.var_name_re)
         args[1][0], args[1][1] = self.control_symb(
             self,
             symb_type=args[1][0],
             symb_name=args[1][1],
             var_name_re=self.var_name_re,
             const_name_re=self.const_name_re)
     elif opcode in self.opcode_symb:
         self.control_number_of_arguments(
             expected_arguments=1, real_number_of_arguments=len(args))
         args[0][0], args[0][1] = self.control_symb(
             self,
             symb_type=args[0][0],
             symb_name=args[0][1],
             var_name_re=self.var_name_re,
             const_name_re=self.const_name_re)
     elif opcode in self.opcode_label:
         self.control_number_of_arguments(
             expected_arguments=1, real_number_of_arguments=len(args))
         self.control_label(label_type=args[0][0],
                            label_name=args[0][1],
                            label_name_re=self.label_name_re)
     elif opcode in self.opcode_label_symb1_symb2:
         self.control_number_of_arguments(
             expected_arguments=3, real_number_of_arguments=len(args))
         self.control_label(label_type=args[0][0],
                            label_name=args[0][1],
                            label_name_re=self.label_name_re)
         args[1][0], args[1][1] = self.control_symb(
             self,
             symb_type=args[1][0],
             symb_name=args[1][1],
             var_name_re=self.var_name_re,
             const_name_re=self.const_name_re)
         args[2][0], args[2][1] = self.control_symb(
             self,
             symb_type=args[2][0],
             symb_name=args[2][1],
             var_name_re=self.var_name_re,
             const_name_re=self.const_name_re)
     elif opcode in self.opcode_var_type:
         self.control_number_of_arguments(
             expected_arguments=2, real_number_of_arguments=len(args))
         self.control_var(var_type=args[0][0],
                          var_name=args[0][1],
                          var_name_re=self.var_name_re)
         self.control_type(type_type=args[1][0], type_name=args[1][1])
     elif opcode in self.opcode_stack:
         self.control_number_of_arguments(
             expected_arguments=0, real_number_of_arguments=len(args))
     else:
         raise ERRConstruction(
             "Instruction: {} doesnt exist in IPPcode20.".format(opcode))