예제 #1
0
 def callback(res):
     lexical = Lexical()
     lexical.get_dfa('./help/dfa.json')  # 读取DFA转换表
     lexical_res = lexical.lexical_run(str(res).replace(
         '\r\n', '\n'))  # 得到词法分析的token序列
     tokens, nums_attr = [], []
     if not lexical_res[0] and not lexical_res[1]:
         QMessageBox.warning(self, '输入无效', '请输入有效程序文本')
         return
     for idx in range(len(
             lexical_res[0])):  # item[1]为种别码,item[3]为行号,item[2]为属性值
         item = lexical_res[0][idx]
         if 'comment' not in item[1]:
             tokens.append(item[1])
             nums_attr.append((item[3], item[2]))
     if not self.syntax:
         self.syntax = Syntax()
         self.syntax.syntax_init('./help/semantic.json')
     semantic = Semantic()
     res_lst, res_err = semantic.semantic_run(tokens, nums_attr,
                                              self.syntax)
     self.semantic_win = QDialog()
     ui = semantic_res.Ui_Dialog()
     init_win(self.semantic_win, ui)
     set_semantic_win(ui, semantic)
예제 #2
0
	def __init__(self, receiving_list, token_list):
		self.receiving_list = receiving_list
		self.token_list = token_list
		self.running = True
		self.thread = threading.Thread(target=self.repeat, daemon=True)
		self.thread.start()
		self.s2 = Semantic(Queue(), [], [], [], "")
예제 #3
0
class Analyzer:
	def __init__(self, receiving_list, token_list):
		self.receiving_list = receiving_list
		self.token_list = token_list
		self.running = True
		self.thread = threading.Thread(target=self.repeat, daemon=True)
		self.thread.start()
		self.s2 = Semantic(Queue(), [], [], [], "")

	def stop(self):
		self.running = False
		self.thread.join()

	def repeat(self):
		while self.running:
			while len(self.receiving_list) is not len(self.token_list):
				try:
					token = self.s2.convert_id_to_token(self.receiving_list[len(self.token_list)])
				except:
					continue
				if isinstance(token, list):
					type = "LETRA|NUM"
				elif self.s2._safe_cast(token, int):
					type = "NUM"
				elif token == " ":
					type = "ESPACIO"
				elif len(token) > 1 and not (token == "CH" or token == "LL" or token == "RR"):
					type = "PALABRAS"
				else:
					type = "LETRA"
				self.token_list.append((token, type))
예제 #4
0
    def run(self):
        node = self.parser.parse()
        semantic = Semantic()
        err, msg = semantic.analysis(node)
        if err:
            raise LQLError(msg)

        return self.visit(node)
예제 #5
0
    def Run(self, event=0):

        self.objMain = Main()

        self.consoleT.delete(1.0, END)

        #open file and write all the IDE code text area content
        self.codeFile = open(Main._codeFile, 'w')
        self.codeFile.write(self.codeT.get('1.0', END))
        self.codeFile.close()

        #open file for reading
        self.codeFile = open(Main._codeFile, 'rb+')
        self.objMain.mainMethod(self.codeFile)
        self.codeFile.close()

        #write tokens to console area
        self.consoleT.insert(1.0, Main._fileData)

        #write tokens to test file
        self.outputFile = open(Main._outputFile, 'w')
        self.outputFile.write(Main._fileData)
        self.outputFile.close()

        #call syntax
        # self.objMain.PROG()

        self.objSyntax = Syntax(Main._tokens)
        self.objSemantic = Semantic(Main._tokens)

        if self.objSyntax.PROG():
            print("Code is parsed")
        else:
            print("there is error in code")
예제 #6
0
    def compile(self, program_file, debug_mode):    
        scan = scanner.Scanner()
        tokenstream = scan.read_program(program_file)

        if debug_mode == True: # prints language tokens 
            print("Language tokens : " + str(tokenstream))

        if tokenstream != False:
            token_head = scan.create_tokens(tokenstream)
            
            syntax_tree = SyntaxTree(token.MAGICCODE)
            
            parser = Parser(token_head)
            
            parser.statement(syntax_tree.insertSubtree("STATEMENT"))

            if debug_mode == True: # prints syntax tree generated by parser
                syntax_tree.printSyntaxTree(0)

            vm_code = Semantic(syntax_tree).generate()
            
            vm = magic_machine(vm_code, debug_mode)
            vm.run()

            print("Result : " + str(vm.get_symbol_table()))
 def start(self, code):
     parser = get_parser()
     result = parser.parse(code)
     self.errors = get_errors()
     if self.errors > 0:
         return
     self.logger.set_tree(result)
     self.semantic = Semantic(self.logger)
     self.semantic.start(result)
     if self.semantic.errors > 0:
         self.logger.log_error(self.semantic.error_list)
         return
     self.stack = Stack()
     self.robot = Robot()
     self.visit(result)
     # self.logger.log_visit(self.symbol_table)
     # self.logger.append_screen(self.symbol_table.copy())
     self.logger.log_visit(self.functions_table)
     self.logger.log_visit(self.main)
예제 #8
0
def main():
    # global fs, analyzer
    # fs = FakeSender()
    # analyzer = Analyzer(fs.get_queue(), 11)

    q = Queue()
    opq = Queue()
    receiving_list = []
    token_list = []
    context_list = []
    final_string = ""
    connected = [0]
    r = Receiver(q, receiving_list, connected, opq)
    a = Analyzer(receiving_list, token_list)
    s = Semantic(q, receiving_list, token_list, context_list, final_string)
    sender = Sender()

    interface = Interface(q, receiving_list, token_list, context_list,
                          final_string, s, connected, sender, opq)
            reg2, reg1 = self.free_reg(num2), self.free_reg(num1)
            reg3 = self.get_reg(res)
            self.mips_instructions.append(f'and $t{reg3} $t{reg1} $t{reg2}\n')
        elif op == Op.bit_or.value:
            reg2, reg1 = self.free_reg(num2), self.free_reg(num1)
            reg3 = self.get_reg(res)
            self.mips_instructions.append(f'or $t{reg3} $t{reg1} $t{reg2}\n')


if __name__ == '__main__':
    # test()
    lex = Lex()
    tokens = get_test_tokens("./test_case/basic_test2.cpp")

    grammar = Gram("../grammar/cfg_resource/cfg_v8.txt")
    grammar.parse(tokens, pr=True)
    if grammar.err:
        print('grammar error.')

    else:
        semantic = Semantic(grammar.tree)
        semantic.run()

        semantic.print_variable_table()
        semantic.print_function_table()
        error_manager.print()

        #         生成代码
        cg = CodeGenerator(semantic.instruction_manager.instructions)
        cg.mips_translate()
예제 #10
0
def runCompiler(input_file, file_name, stage, opt_stage, debug_stage):
    # scan, parse, ast, semantic, irt, codegen

    if (stage == "scan" or stage == "parse" or stage == "ast"
            or stage == "semantic" or stage == "irt" or stage == "codegen"):
        debug = False
        if (("scan" in debug_stage)):
            debug = True

        sc = Scanner.Scanner()
        rf = ReadFile.ReadFile()
        wf = WriteFile.WriteFile()

        # set de input file
        rf.set_file(f"decafs/{input_file}.decaf")

        # call scanner class and scan for tokens in input file
        token_list, error_list = sc.scan(rf.file_to_string(), debug)
        string_list = []
        for token in token_list:
            string_list.append(token.pretty_print())

        # write file in output/
        wf.write_file(file_name, string_list)
        # write file in output/
        error1 = len(error_list)
        wf.write_file_append("error_list", error_list)

    if (stage == "parse" or stage == "ast" or stage == "semantic"
            or stage == "irt" or stage == "codegen"):
        debug = False
        if (("parse" in debug_stage)):
            debug = True

        pr = Parser.Parser()
        main_program, error_list = pr.parse(token_list, debug)
        # write file in output/
        wf.write_file_append("error_list", error_list)
        error2 = len(error_list)

    if (stage == "ast" or stage == "semantic" or stage == "irt"
            or stage == "codegen"):
        debug = False
        if (("ast" in debug_stage)):
            debug = True
        ast = Ast.Ast()
        ast.ast(main_program, debug)

    if (stage == "semantic" or stage == "irt" or stage == "codegen"):
        debug = False
        if (("semantic" in debug_stage)):
            debug = True
        sm = Semantic.Semantic()
        error_list = sm.semantic(main_program, debug)
        # write file in output/
        wf.write_file_append("error_list", error_list)
        error3 = len(error_list)
    if (stage == "irt" or stage == "codegen"):
        if (error1 == 0 and error2 == 0 and error3 == 0):
            debug = False
            if (("irt" in debug_stage)):
                debug = True
            irt = Irt.Irt()
            irt_list = irt.irt(main_program, debug)
        else:
            print("There are errors in the error_log")

    if (stage == "codegen"):
        if (error1 == 0 and error2 == 0 and error3 == 0):
            codegen = Codegen.Codegen()
            code_list, code_list_2 = codegen.codegen(main_program, debug)
            wf.write_file_no_extension("program.asm", code_list)

            wf.write_file_no_extension("program.py", code_list_2)
        else:
            print("There are errors in the error_log")
        # TODO write file asm or py from code_list
        # print("CODEGEN not ready")

    if (stage != "scan" and stage != "parse" and stage != "ast"
            and stage != "semantic" and stage != "irt" and stage != "codegen"):
        print("stage value not defined")

    print(input_file, file_name, stage, opt_stage, debug_stage)
class Visitor:
    def __init__(self):
        self.stack = None
        self.semantic = None
        self.errors = None
        self.robot = None
        self.bind = None
        self.reflect = None
        self.main = None
        self.return_address = None
        self.symbol_table = None
        self.functions_table = None
        self.returnx = False
        self.logger = Logger()
        l = get_log()
        self.logger.set_log_p(l)
        colorama.init()

    def get_logger(self):
        return self.logger

    def start(self, code):
        parser = get_parser()
        result = parser.parse(code)
        self.errors = get_errors()
        if self.errors > 0:
            return
        self.logger.set_tree(result)
        self.semantic = Semantic(self.logger)
        self.semantic.start(result)
        if self.semantic.errors > 0:
            self.logger.log_error(self.semantic.error_list)
            return
        self.stack = Stack()
        self.robot = Robot()
        self.visit(result)
        # self.logger.log_visit(self.symbol_table)
        # self.logger.append_screen(self.symbol_table.copy())
        self.logger.log_visit(self.functions_table)
        self.logger.log_visit(self.main)

    def new_frame(self):
        self.stack.new_frame()
        self.symbol_table, self.functions_table = self.stack.get()

    def remove_frame(self):
        self.stack.remove_frame()
        self.symbol_table, self.functions_table = self.stack.get()

    def visit(self, result):
        self.logger.log_visit("visit: %s" % result.name)
        if isinstance(result, Variable):
            return self.xvisitVariable(result)
        elif isinstance(result, BinOp):
            return self.xvisitBinOp(result)
        elif isinstance(result, UnOp):
            return self.xvisitUnOp(result)
        elif isinstance(result, Number):
            return self.xvisitNumber(result)
        elif isinstance(result, Boolean):
            return self.xvisitBoolean(result)
        elif isinstance(result, String):
            return self.xvisitString(result)
        elif isinstance(result, Assigment):
            return self.xvisitAssigment(result)
        elif isinstance(result, Compound):
            self.xvisitCompound(result)
        elif isinstance(result, ListNode):
            self.xvisitListNode(result)
        elif isinstance(result, List):
            self.xvisitList(result)
        elif isinstance(result, FunctionDeclare):
            self.xvisitFunctionDeclare(result)
        elif isinstance(result, Program):
            self.xvisitProgram(result)
        elif isinstance(result, VariableDeclaration):
            self.xvisitVariableDeclaration(result)
        elif isinstance(result, VariableDeclarationMultiply):
            self.xvisitVariableDeclarationMultiply(result)
        elif isinstance(result, ReturnStatement):
            self.xvisitReturn(result)
        elif isinstance(result, FunctionCall):
            return self.xvisitFunctionCall(result)
        elif isinstance(result, EnterDoUntil):
            self.xvisitEnterDoUntil(result)
        elif isinstance(result, LogicOp):
            return self.xvisitLogicOp(result)
        elif isinstance(result, Initializer):
            return self.xvisitInitializer(result)
        elif isinstance(result, GetArrElement):
            return self.xvisitGetArrEl(result)
        elif isinstance(result, TypeConversion):
            return self.xvisitTypeConversion(result)
        elif isinstance(result, PrintStatement):
            self.xvisitPrintStatement(result)
        elif isinstance(result, RobotStatement):
            return self.xvisitRobot(result)
        elif isinstance(result, BindStatement):
            self.xvisitBind(result)
        elif isinstance(result, NoOp):
            pass
        else:
            # raise XExceptions("Gavno")
            self.logger.log_visit(result)

    def xvisitList(self, node):
        for i in node.nodes:
            #if isinstance(i,ReturnStatement):
            #raise XExceptions("out")
            self.visit(i)

    def xvisitBind(self, node):
        self.bind = node.variable.varname
        self.stack.set_st(name=self.bind, value='0')

    def xvisitRobot(self, node):
        if node.op != "measure":
            return self.robot.action(node)
        elif node.op == "measure":
            self.stack.set_st(name=self.bind, value=self.robot.action(node))

    def xvisitTypeConversion(self, node):
        if node.type.value == "int":
            return str(self.visit(node.value))
        elif node.type.value == "bool":
            return str(self.visit(node.value))
        elif node.type.value == "str":
            return str(self.visit(node.value))

    def xvisitGetArrEl(self, node):
        arr = self.stack.get_st(node.varname.varname)
        indexes = self.xvisitIndexing(node.left)
        x = arr
        for i in indexes:
            x = x[i]
        return x

    def set_arr_element(self, node, x):
        self.logger.append_screen(self.symbol_table)
        if not isinstance(node, GetArrElement):
            raise XExceptions("not a GetArrElement")
        ind = self.xvisitIndexing(node.left)
        arr = self.stack.get_st(node.varname.varname)
        arr_copy = arr
        self.logger.log_visit(arr)
        for i in ind[0:-1]:  #[0:-1]
            if arr.get(i) is None:
                arr[i] = {}
            arr = arr[i]
            self.logger.log_visit(arr)
        arr[i] = x
        self.stack.set_st(node.varname.varname, arr_copy)
        self.logger.log_visit(arr)
        self.logger.append_screen(self.symbol_table)

    def xvisitIndexing(self, node):
        return [self.visit(i) for i in node.nodes]

    def xvisitNumber(self, node):
        return node.value

    def xvisitBinOp(self, node):
        left = self.visit(node.left)
        right = self.visit(node.right)
        if (left is None) | (right is None):
            # self.logger.log_visit(self.symbol_table)
            self.logger.append_screen(self.symbol_table.copy())
            raise XExceptions("Gavno2")
        if node.op == '+':
            return left + right
        elif node.op == '-':
            return left - right
        elif node.op == '/':
            return left / right
        elif node.op == '*':
            return left * right
        elif node.op == '**':
            return left**right

    def xvisitLogicOp(self, node):
        left = self.visit(node.left)
        right = self.visit(node.right)
        if (left is None) or (right is None):
            # self.logger.log_visit  (self.symbol_table)
            self.logger.append_screen(self.symbol_table.copy())
            print(node.right, node.left)
            raise XExceptions("Gavno2")
        """
        if (isinstance(node.left,Variable)):
            left = left[1]
        if (isinstance(node.right,Variable)):
            right = right[1]
        """
        if node.op == '!=':
            self.logger.log_visit(node.op)
            return left != right
        elif node.op == '==':
            self.logger.log_visit(node.op)
            return left == right
        elif node.op == '>':
            self.logger.log_visit(node.op)
            return left > right
        elif node.op == '<':
            self.logger.log_visit(node.op)
            return left < right
        elif node.op == '>=':
            self.logger.log_visit(node.op)
            return left >= right
        elif node.op == '<=':
            self.logger.log_visit(node.op)
            return left <= right

    def xvisitUnOp(self, node):
        if node.op == '-':
            return -(self.visit(node.left))

    def xvisitVariable(self, node):
        return self.stack.get_st(node.varname)

    def xvisitAssigment(self, node):
        value = self.visit(node.right)
        if isinstance(node.right, FunctionCall):
            value = self.return_address
            self.return_address = None
        if isinstance(node.left, GetArrElement):
            self.set_arr_element(node.left, value)
        else:
            self.stack.set_st(name=node.left.varname, value=value)
        self.logger.append_screen(self.symbol_table)
        return value

    def xvisitCompound(self, node):
        self.visit(node.node)

    def xvisitListNode(self, node):
        self.visit(node.left)
        self.visit(node.right)

    def xvisitFunctionDeclare(self, node):
        self.functions_table[node.functionname.varname] = Function(
            arglist=node.arglist, ret_type=node.retType.value, code=node.left)
        self.logger.log_visit(self.functions_table)

    def xvisitProgram(self, node):
        self.main = node.main.functionname
        self.logger.log_visit("call main %s" % str(self.main))
        self.new_frame()
        self.visit(node.node)
        self.visit(node.main)
        self.remove_frame()
        # self.main = node.value.varname

    def xvisitVariableDeclaration(self, node):
        type = node.type
        name = None
        value = None
        if isinstance(node.node, Variable):
            name = node.node.varname
        elif isinstance(node.node, Assigment):
            name = node.node.left.varname
            value = self.visit(node.node.right)
        #if value is None and self.return_address is not None:
        #value = self.return_address
        #self.return_address = None
        self.stack.add_st(type, name, value)
        # self.logger.log_visit(self.symbol_table)
        self.logger.append_screen(self.symbol_table.copy())

    def xvisitVariableDeclarationMultiply(self, node):
        type = node.type
        names = [None] * len(node.nodes.nodes)
        values = [None] * len(node.nodes.nodes)
        for j in range(len(node.nodes.nodes)):  # reversed(range)
            i = node.nodes.nodes[j]
            if isinstance(i, Variable):
                names[j] = i.varname
                values[j] = None
            elif (isinstance(i, Assigment)):
                names[j] = i.left.varname
                # self.logger.log_visit(self.symbol_table)
                values[j] = (self.visit(i.right))
            self.logger.append_screen(self.symbol_table)
            self.stack.add_st(type, name=names[j], value=values[j])

    def xvisitFunctionCall(self, node):
        self.new_frame()
        func = self.stack.get_func(node.functionname.varname)
        if func is None:
            return
        if func.args is not None:
            for j in range(len(func.args.nodes)):
                name = None
                type = func.args.nodes[j].type.value
                func_arg = func.args.nodes[j]
                value = None
                call_arg = node.arglist.nodes[j]
                if (isinstance(func_arg, Variable)):
                    name = func_arg.varname
                    value = self.stack.get_st(call_arg.varname)
                elif (isinstance(func_arg, VariableDeclaration)):
                    if (isinstance(func_arg.node, Assigment)):
                        name = func_arg.node.left.varname
                    else:
                        name = func_arg.node.varname
                    value = self.visit(call_arg)
                    #print("%s=%s"%(call_arg,value))
                self.stack.add_st(type=type, name=name, value=value)
        else:
            self.logger.log_visit("without args")
        try:
            self.visit(func.code)
        except XExceptions:
            k = 0
        self.logger.append_screen(self.symbol_table)
        self.remove_frame()
        return self.return_address

    def xvisitReturn(self, node):
        self.return_address = self.visit(node.left)
        raise XExceptions("out")

    def xvisitEnterDoUntil(self, node):
        res = self.visit(node.logic)
        until = self.visit(node.until)
        while res == until:
            self.new_frame()
            try:
                self.visit(node.statementList)
                #print(self.symbol_table)
                self.remove_frame()
            except XExceptions:
                k = 0
                self.remove_frame()
                raise XExceptions("out")
            res = self.visit(node.logic)
            self.logger.log_visit("res = %s,until = %s" % (res, until))

    def xvisitBoolean(self, node):
        return node.value

    def xvisitInitializer(self, node):
        t = {}
        for i in range(len(node.left.nodes)):
            t[i] = self.visit(node.left.nodes[i])
        return t

    def xvisitPrintStatement(self, node):
        if isinstance(node.strx, List):
            s = [self.visit(i) for i in node.strx.nodes]
            print(*s, sep=',')
            for i in s:
                print("type=%s" % type(i))
        else:
            s = self.visit(node.strx)
            print("el=%s" % s)

    def xvisitString(self, node):
        return node.value.strip("\'")
예제 #12
0
print('记号流:')
for i in main_lexer.get_token(True):
    print(i)

if len(main_lexer.get_err_token()) != 0:
    print("错误流:")
    for i in main_lexer.get_err_token():
        print(i)
    sys.exit()

# 语法分析
main_parser = Parser(main_lexer.get_token())
grammar_tree = main_parser.get_grammar_tree()
print('语法树:')
Parser.print_grammmar_tree(grammar_tree)
if grammar_tree is None:
    sys.exit()

# 语义分析
main_semantic = Semantic(grammar_tree)
operation_queue = main_semantic.get_operation_queue()
print('中间代码:')
for i in operation_queue:
    print(i)

# 执行
main_actuator = Actuator(output_file)
main_actuator.append(operation_queue)
main_actuator.execute()
main_actuator.create_image()
예제 #13
0
dot = Graph('AST')
count = 0


def show_tree(node, count_node):
    global count
    dot.node(str(count_node), str(node.type))
    for children in node.children:
        if children:
            count = count + 1
            dot.edges([(str(count_node), str(count))])
            show_tree(children, count)


from semantic import Semantic
from cultivation import AST
from code_gen import Gen_Code

if __name__ == '__main__':
    filename = sys.argv[1]
    sourcefile = open(filename, encoding='UTF-8')
    data = sourcefile.read()
    parser = yacc.yacc(debug=True)
    p = parser.parse(data)  #sintatic analysis
    if not error_flag:
        Semantic(p)  #semantic analysis: object 'p' won't be modified
        AST(p)  #generate abstract syntax tree: object 'p' will be modified
        Gen_Code(p)  #code generation: object 'p' won't be modified
        #show_tree(p, 0) #uncomment to show tree
        #dot.render('tree.gv', view=True) #uncomment to show tree
예제 #14
0
def semantic(file, isCli=False, noOutputs=False):
    global hashTable
    semantic = Semantic(file, isCli, noOutputs)
    global semanticTree
    hashTable = semantic.getHashTable()
    semanticTree = semantic.getSemanticTree()
예제 #15
0
        elif code3.op == "return":
            output.write("  movl %ebp, %esp\n  popl %ebp\n")
            if code3.arg1 != None:
                var1 = getaddr(code3.arg1, funcTable, output)
                output.write("  movl %s, %%eax\n" % (var1))
            output.write("  ret\n")
        elif code3.op == "param":
            var1 = getaddr(code3.arg1, funcTable, output, "%eax")
            output.write("  pushl %eax\n")
        elif code3.op == "call":
            output.write("  call %s\n" % (code3.arg1))


if __name__ == "__main__":
    # cfl = getCFL("grammar.txt")
    scanner = Scanner(open("test.cpp", "rb"))
    semantic = Semantic("cfl.dump")

    while True:
        token = scanner.scan()
        print(token.elem, token.info)
        semantic.onlineAnalyze(token)
        if token.info == "":
            break

    codes = semantic.symbolStack[-1][1].code
    table = semantic.tableStack[-1]

    output = open("test.asm", "w")
    outputAssembler(codes, table, open("test.s", "w"))
예제 #16
0
    def generate_vm_code(self, head):

        return Semantic(head).generate()
예제 #17
0
def main():
    print("JCOSIM: Java Compiler Simulator")
    try:
        if len(argv) < 2:
            raise GetoptError('ERROR: Input file must be specified')
        options, remainder = getopt(argv[1:], 'i:o:stuapgc:vh', [
            'input=',
            'output=',
            'symtable',
            'token',
            'use-gcc',
            'analyzedtree',
            'analy',
            'gencode',
            'clean=',
            'verbose',
            'help',
        ])

        source = None
        exe = None
        symtable = False
        token = False
        parsetree = False
        analyzedtree = False
        gencode = False
        clean = False
        clean_path = '.'
        cc = False

        for opt, arg in options:
            if opt in ('-h', '--help'):
                raise GetoptError('')
            elif opt in ('-c', '--clean'):
                clean = True
                clean_path = arg
            elif opt in ('-i', '--input'):
                source = arg
            elif opt in ('-u', '--use-gcc'):
                cc = True
            elif opt in ('-o', '--output'):
                exe = arg
            elif opt in ('-s', '--symtable'):
                symtable = True
            elif opt in ('-t', '--token'):
                token = True
            elif opt in ('-p', '--parsetree'):
                parsetree = True
            elif opt in ('-a', '--analyzedtree'):
                analyzedtree = True
            elif opt in ('-g', '--gencode'):
                gencode = True
            elif opt in ('-v', '--verbose'):
                symtable = True
                token = True
                parsetree = True
                analyzedtree = True
                gencode = True

        # clean and exit
        if clean:
            if source:
                # Smartly get exe file name
                if not exe: exe = Path(source).stem
            else:
                exe = 'Main'

            files = [
                'tokens.txt', 'parsetree.png', 'analyzedtree.png',
                'symtable.json', f'{exe}.c', f'{exe}.exe', f'{exe}',
                f'{exe}.o', f'{exe}.obj'
            ]

            section(*clean_display(files))
            for file in files:
                _path = Path(clean_path).joinpath(file).resolve()
                if Path(_path).exists():
                    Path(_path).unlink()
            exit()

        # No source no life
        if not source:
            raise GetoptError('ERROR: Input file must be specified')

        # Smartly get exe file name
        if not exe:
            exe = Path(source).stem

        # Read Java source file
        with open(source, 'r') as f:
            buffer = f.read()

        # Lexing
        lexer = Lexer(buffer)

        # Parsing
        parser = Parser(lexer)
        program_tree = parser.program()

        # Generate symbol table
        lexer.reset()
        stb = SymbolTable(lexer)

        # Semantic
        semantic = Semantic(program_tree, stb)
        analyzed_tree = semantic.analyze()

        # Generate C code
        code_gen = CodeGen(analyzed_tree, stb)
        code = code_gen.generate_code()

        # Compile the code and output native binary
        section(*native_compile_display(code, exe, cc))

        # do things based on flags
        if token:
            section(*token_display(lexer))
        if symtable:
            section(*symtable_display(stb))
        if parsetree:
            section(*parsetree_display(program_tree, 'parsetree.png'))
        if analyzedtree:
            section(*parsetree_display(analyzed_tree, 'analyzedtree.png'))
        if gencode:
            section(*gencode_display(code, exe))

    except GetoptError as e:
        section(*help_text())
        print(e)