Exemplo n.º 1
0
    def parse(self, file):
        tree = ET.ElementTree
        try:
            if file == "stdin":
                tree = ET.parse(sys.stdin)
            else:
                tree = ET.parse(file)
        except FileNotFoundError:
            ErrorPrints.file_error(f"{file} not found")
        except:
            ErrorPrints.err_xml_not_well_formed()
        """ Get head """
        root = tree.getroot()
        self.__check_head__(root)

        inst = root.findall("instruction")
        if inst != root.getchildren():
            ErrorPrints.err_xml_structure("Unsupported element")

        # Order instructions by order ascending
        try:
            inst[:] = sorted(inst, key=lambda child: int(child.get("order")))
        except:
            ErrorPrints.err_xml_structure("Invalid order attribute")

        self.__check_inst__(inst)

        if len(inst) != 0:
            if int(inst[0].attrib.get("order")) <= 0:
                ErrorPrints.err_xml_structure("Order must be positive number")

        return self.__create_instructions__(inst)
Exemplo n.º 2
0
def redirect_stdin(file):
    """If input is not supplied from stdin redirect the stdin to file."""
    if file != "stdin":
        try:
            sys.stdin = open(file, "r")
        except:
            ErrorPrints.file_error("Cannot open file for input")
Exemplo n.º 3
0
 def __check_inst_attrib__(self, item):
     """Helper method for checking the instruction attributes."""
     if item.get("order") is None or item.get("opcode") is None:
         ErrorPrints.err_xml_structure(
             "Missing order or opcode attribute in " + str(item))
     if len(item.attrib) > 2:
         ErrorPrints.err_xml_structure(
             f"Unexpected attribute in {item.get('opcode')} at {item.get('order')}"
         )
Exemplo n.º 4
0
    def __create_instructions__(self, instructions):
        """Method for creating the instruction list."""
        __instructions = list()
        inst = []
        try:
            for inst in instructions:
                children = inst.getchildren()
                instruction = instruction_factory(inst.attrib["opcode"],
                                                  int(inst.attrib["order"]),
                                                  children)

                if instruction.argc() != len(children):
                    ErrorPrints.err_xml_structure(
                        f"Argument count at {inst.attrib['order']} {inst.attrib['opcode']}"
                    )

                __instructions.append(instruction)
        except ArgError as ex:
            ErrorPrints.err_xml_structure(
                ex.message + f" At {inst.get('order')} {inst.get('opcode')}")
        except OpCodeError as ex:
            ErrorPrints.err_xml_structure(
                ex.message + f" At {inst.get('order')} {inst.get('opcode')}")
        except IndexError as ex:
            msg = ex.args[0]
            ErrorPrints.err_xml_structure(
                msg + f" At {inst.get('order')} {inst.get('opcode')}")

        return InstructionsCollection(__instructions)
Exemplo n.º 5
0
def write_stats(options, stacks):
    """Writes statistics to specified file"""
    try:
        file = open(options["stats"], "w")

        file_content = ''
        for option in options["statOpt"]:
            if option == "insts":
                file_content += f"{IPPInterpret().inst_count}\n"
            elif option == "vars":
                file_content += f"{stacks['GF'].MaxInitVars + stacks['LF'].MaxInitVars + stacks['TF'].MaxInitVars}\n"

        file.write(file_content)
        file.close()

    except OSError:
        ErrorPrints.file_error(f"Cannot open {options.get('stats')} file")
Exemplo n.º 6
0
    def __check_inst__(self, items):
        """
            Method that checks instruction for excessive or missing attributes,
            for duplicity order and instruction sub elements.
        """
        uniq = list()
        for item in items:
            self.__check_excessive_text__(item.text)
            self.__check_inst_attrib__(item)
            if item.attrib["order"] in uniq:
                ErrorPrints.err_xml_structure("Duplicity order number " +
                                              str(item.attrib["order"]))

            try:
                self.__check_inst_child__(item.getchildren())
            except ArgError as e:
                ErrorPrints.err_xml_structure(
                    e.message + f"At item {item.attrib['order']}")

            uniq.append(item.attrib["order"])
Exemplo n.º 7
0
    def interpret(self, options):
        xml_instr = XMLParser().parse(options["source"])
        redirect_stdin(options["input"])

        # First try to find all labels for the jumps
        inst = ''
        try:
            for inst in xml_instr:
                if isinstance(inst, Label):
                    inst.do(self.Stacks)
        except IPPBaseException as ex:
            ErrorPrints.interpret_err(
                f"{ex.message} in {inst.opCode} at {inst.order}", ex.ExitCode)

        # Execute each instruction
        try:
            for inst in xml_instr:
                IPPInterpret._inst_count += 1
                jump, order = inst.do(self.Stacks)

                # Unpack the jump tuple
                jump, return_jump = jump
                if jump:
                    # Jump to instruction
                    xml_instr.jump_to_inst(order)
                    # When the jump is from Return instruction we are jumping back to the Call instruction, so need to
                    # skip the call instruction
                    if return_jump:
                        xml_instr.skip()

        except IPPBaseException as ex:
            ErrorPrints.interpret_err(
                f"{ex.message} in {inst.opCode} at {inst.order}", ex.ExitCode)

        finally:
            sys.stdin.close()
            sys.stdin = self._old_stdin

        # Write statistics for the STATI extension
        if options.get("stats") is not None:
            write_stats(options, self.Stacks)
Exemplo n.º 8
0
def main(argv):
    _inputOpt = "input"
    _sourceOpt = "source"
    _stdin = "stdin"

    _statsOpt = "stats"
    _stats_extension = [_statsOpt + '=', "insts", "vars"]

    optlist = list()
    try:
        optlist, args = getopt.getopt(
            argv, "h",
            [_inputOpt + '=', _sourceOpt + '=', "help"] + _stats_extension)
    except getopt.GetoptError as e:
        errprint(e.msg)
        print_help()
        ErrorPrints.err_parameter()

    _optDic = {_inputOpt: _stdin, _sourceOpt: _stdin, "statOpt": list()}
    stats_set = False
    # Create option dictionary from passed arguments
    for opt, arg in optlist:
        if opt == "--help" or opt == "-h":
            print_help()
            sys.exit(0)
        elif opt in ("--" + _inputOpt, "--" + _sourceOpt):
            if arg != '':
                _optDic[str(opt).replace("--", '')] = arg
        elif opt == "--" + _statsOpt:
            stats_set = True
            _optDic[str(opt).replace("--", '')] = arg
        elif opt == "--insts" or opt == "--vars":
            _optDic["statOpt"] += [str(opt).replace("--", '')]

    # Check if at-least one of the parameters is set
    if _optDic[_inputOpt] == _stdin and _optDic[_sourceOpt] == _stdin:
        print_help()
        ErrorPrints.err_parameter()

    # For STATI extension the --stats= parameter must be set if other STATI parameters are set
    if not stats_set and len(_optDic["statOpt"]) != 0:
        print_help()
        ErrorPrints.err_parameter()

    # Run the interpret
    IPPInterpret().interpret(_optDic)
Exemplo n.º 9
0
    def __check_head__(self, root):
        """Check root element."""
        if len(root.attrib) < 1 or len(root.attrib) > 3:
            ErrorPrints.err_xml_structure("Wrong root element")

        if root.tag != "program":
            ErrorPrints.err_xml_structure("Wrong root element")

        lang = root.attrib.get("language")
        name = root.attrib.get("name")
        description = root.attrib.get("description")

        if lang is None:
            ErrorPrints.err_xml_structure("Wrong root element")
        if len(root.attrib) == 2 and (name is None and description is None):
            ErrorPrints.err_xml_structure("Wrong root element")
        if len(root.attrib) == 3 and (name is None or description is None):
            ErrorPrints.err_xml_structure("Wrong root element")
        if len(root.attrib) > 3:
            ErrorPrints.err_xml_structure("Wrong root element")

        if lang != "IPPcode20":
            ErrorPrints.err_xml_structure("Wrong language")
Exemplo n.º 10
0
 def __check_excessive_text__(self, text):
     if text is not None and text.rstrip() != '':
         ErrorPrints.err_xml_structure("Excessive text.")