Exemplo n.º 1
0
def compile(args):
    print("Compiling", args.source_file)
    SymbolTableManager.init()
    MemoryManager.init()
    parser = Parser(args.source_file)
    start = time.time()
    parser.parse()
    stop = time.time() - start
    print(f"Compilation took {stop:.6f} s")
    if not SymbolTableManager.error_flag:
        print("Compilation successful!")
    else:
        print("Compilation failed due to the following errors:\n")
        print(parser.scanner.lexical_errors)
        print(parser.syntax_errors)
        print(parser.semantic_analyzer.semantic_errors)
    if args.abstract_syntax_tree:
        parser.save_parse_tree()
    if args.symbol_table:
        parser.scanner.save_symbol_table()
    if args.tokens:
        parser.scanner.save_tokens()
    if args.error_files:
        parser.save_syntax_errors()
        parser.scanner.save_lexical_errors()
        parser.semantic_analyzer.save_semantic_errors()
    parser.code_generator.save_output()
    if args.run and not SymbolTableManager.error_flag:
        print("Executing compiled program")
        if os.name == "nt":
            tester_file = os.path.join(script_dir, "interpreter",
                                       "tester_Windows.exe")
        elif os.name == "posix":
            tester_file = os.path.join(script_dir, "interpreter",
                                       "tester_Linux.out")
        else:
            tester_file = os.path.join(script_dir, "interpreter",
                                       "tester_Mac.out")
        output_file = os.path.join(script_dir, "output", "output.txt")
        output_dir = os.path.dirname(output_file)
        if os.path.exists(output_file):
            preexec_fn = limit_virtual_memory if os.name != "nt" else None
            stderr = sp.PIPE if not args.verbose else None
            start = time.time()
            try:
                tester_output = sp.check_output(
                    tester_file,
                    cwd=output_dir,
                    stderr=stderr,
                    timeout=10,
                    preexec_fn=preexec_fn).decode("utf-8")
            except sp.TimeoutExpired:
                print("RuntimeError: Execution timed out!")
            else:
                if not args.verbose:
                    tester_output = "\n".join([
                        line.replace("PRINT", "").strip()
                        for line in tester_output.splitlines()
                        if line.startswith("PRINT")
                    ])
                stop = time.time() - start
                print(f"Execution took {stop:.6f} s")
            print("Program output:")
            print(tester_output)