Beispiel #1
0
    def translate(self, filename: str) -> Program:
        """
        Translates the program from the AST into the corresponding IR.
        :param filename: name of file to parse.
        :return:
        """
        file_stream = FileStream(filename)
        lexer = BSLexer(file_stream)
        stream = CommonTokenStream(lexer)
        parser = BSParser(stream)
        tree = parser.program()

        # We can rely on Python's shallow copy and pass by reference semantics
        # to create only one object and allow all the passes to update it.
        symbol_table = SymbolTable()
        identifier = self.config.identify.get_identifier()

        # Order matters, don't mess with the order, it should be Header, Symbol, Method.
        visitor_passes = [
            HeaderVisitor(symbol_table, identifier),
            SymbolTableVisitor(symbol_table, identifier),
            MethodVisitor(symbol_table),
            IRVisitor(symbol_table)
        ]

        for visitor in visitor_passes:
            if self.config.debug:
                self.log.debug("Running {} pass.".format(visitor.visitor_name))
            visitor.visit(tree)

        ir = visitor_passes[-1]
        self.program = Program(functions=ir.functions,
                               config=self.config,
                               symbol_table=ir.symbol_table,
                               bb_graph=ir.graph,
                               name=self.config.input_file,
                               calls=ir.calls)

        self.visit_type_check(tree, ir.symbol_table)

        if self.config.write_cfg:
            for root in self.program.functions:
                self.program.write['{}_basic_block_graph'.format(
                    root)] = Writable(
                        self.program.name, "{}/{}_{}_basic_blocks.dot".format(
                            self.config.output, self.program.name,
                            root), self.program.functions[root]['graph'],
                        WritableType.GRAPH)
        return self.program
 def run_symbols(tree, symbol_table: SymbolTable) -> SymbolTable:
     symbol_visitor = SymbolTableVisitor(symbol_table, NaiveIdentifier())
     symbol_visitor.visit(tree)
     return symbol_visitor.symbol_table