def p_function_call_1(self, p): """function_call : lvalue1 function_call_body""" print("""function_call -> lvalue1 function_call_body""") p[0] = Nonterminal() label = self.new_label() p[0].args = p[2].args if self.t_counter > -1 : for i in range(0, self.t_counter): self.FuncVARIABLES.append("TT"+str(i)) p[0].code = CodeGenerator.storeVariables(self, self.FuncVARIABLES) + CodeGenerator.pushAddress(self,label) p[0].code += "// store arguments\n" + p[2].code + CodeGenerator.storeArgs(self,p[2].args)+ "\n goto " + p[1].get_value() + ";\n" p[0].place = self.new_temp() p[0].code += "// return label:\n" + label + ":\n" + "// load return value\n" + CodeGenerator.popVariable(self,p[0].place) +"\n //varaiables:" + CodeGenerator.loadVariables(self,self.FuncVARIABLES) print(p[0].code) print("-------------function call--------------")
def __init__(self): self.scope_counter = -1 self.t_counter = -1 self.l_counter = -1 self.code_generator = CodeGenerator() self.code_list = [] self.TRUE_LABEL = "TRUE_LABEL" self.FALSE_LABEL = "FALSE_LABEL" self.NEXT_LABEL = "NEXT_LABEL" self.VARIABLES = [] self.FuncVARIABLES = [] self.check = False self.symbol_table_list = [] self.func_table = [] self.variable_decs = ""
def p_func_body(self, p): """func_body : ID LP formal_arguments RP block""" print("""func_body -> ID LP formal_arguments RP block""") p[0] = Nonterminal() return_phrase = "goto end;\n\n" if p[1] == "_main" else CodeGenerator.popReturnAddr(self) + "goto *returnAddress; // return from function\n\n" p[0].code = "//function body ----------- \n" + p[1] + ": //function decleration\n\n" + p[3].code + "\n // function body:\n" + p[5].code + "\n// function ended\n" + return_phrase # self.variable_decs = "" print(p[0].code) p[0].func_name = p[1] p[0].sym_var = p[5].sym_var self.add_ref(p[0].sym_var, self.new_scope_name()) #save a scope self.symbol_table_list.append(p[0].sym_var)
def p_return(self, p): """return : RETURN exp SEMICOLON""" print("""return -> RETURN exp SEMICOLON""") p[0] = Nonterminal() p[0].code = "// push return value to stack\n" + p[2].code + CodeGenerator.popReturnAddr(self) p[0].code += CodeGenerator.pushVariable(self, p[2].get_value()) + "goto *returnAddress; // return from function\n\n"
class Parser: def __init__(self): self.scope_counter = -1 self.t_counter = -1 self.l_counter = -1 self.code_generator = CodeGenerator() self.code_list = [] self.TRUE_LABEL = "TRUE_LABEL" self.FALSE_LABEL = "FALSE_LABEL" self.NEXT_LABEL = "NEXT_LABEL" self.VARIABLES = [] self.FuncVARIABLES = [] self.check = False self.symbol_table_list = [] self.func_table = [] self.variable_decs = "" tokens = l.tokens def p_program(self, p): """program : macros classes""" print("""program -> macros classes""") p[0] = Nonterminal() p[0].sym_var = p[2].sym_var print("symbol table list :") print(self.symbol_table_list) include = "#include <stdio.h>" + "\n" include += "#include <stdio.h>" + "\n" if self.t_counter > -1: variables_declaration = "double " for i in range(0, self.t_counter + 1): if i == self.t_counter: variables_declaration += "TT" + str(i) + ";" else: variables_declaration += "TT" + str(i) + ", " else: variables_declaration = "" stack_components_declaration = "void* returnAddress;\ndouble * top = (double*) malloc(1000 * sizeof(double));\nvoid ** labelsTop = (void**) malloc(1000 * sizeof(void*));\ntop += 1000;\nlabelsTop += 1000;" goto_to_main = "goto _main;\n\n" p[0].code = include + "int main()\n{\n\n" + stack_components_declaration + "\n" + variables_declaration + "\n"+ self.variable_decs + goto_to_main + p[2].code + "\n\nend : return 0;\n}" file = open("final_result.c", "w") file.write(p[0].code) file.close() def p_macros(self, p): """macros : macros macro""" print("""macros -> macros macro""") def p_macros_e(self, p): """macros : """ print("""macros ->/* Lambda */""") def p_macro(self, p): """macro : reference""" print("""macro -> reference""") def p_reference(self, p): """reference : REFERENCE STRING""" print("""reference -> REFERENCE STRING""") def p_classes(self, p): """classes : classes class""" print("""classes -> classes class""") p[0] = Nonterminal() p[0].code = p[1].code + p[2].code p[0].sym_var = p[1].sym_var + p[2].sym_var def p_classes_e(self, p): """classes : """ print("""classes ->/* Lambda */""") p[0] = Nonterminal() p[0].code = "" p[0].sym_var = [] def p_class(self, p): """class : CLASS ID LCB symbol_decs RCB""" print("""class -> CLASS ID LCB symbol_decs RCB""") p[0] = Nonterminal() p[0].code = p[4].code p[0].sym_var = p[4].sym_var def p_symbol_decs(self, p): """symbol_decs : symbol_decs symbol_dec""" print("""symbol_decs -> symbol_decs symbol_dec""") p[0] = Nonterminal() p[0].code = p[1].code + p[2].code p[0].sym_var = p[1].sym_var + p[2].sym_var def p_symbol_decs_e(self, p): """symbol_decs : """ print("""symbol_decs ->/* Lambda */""") p[0] = Nonterminal() p[0].code = "" def p_symbol_dec_1(self, p): """symbol_dec : var_dec""" print("""symbol_dec -> var_dec""") p[0] = Nonterminal() p[0].code = p[1].code def p_symbol_dec_2(self, p): """symbol_dec : func_dec""" print("""symbol_dec -> func_dec""") p[0] = Nonterminal() p[0].code = p[1].code p[0].sym_var = p[1].sym_var def p_var_dec(self, p): """var_dec : var_type var_list SEMICOLON""" print("""var_dec -> var_type var_list SEMICOLON""") p[0] = Nonterminal() self.variable_decs += [p[1].rtype + " " + var + ";\n" for var in p[2].vars] self.VARIABLES += p[2].vars p[0].code = "\n" + p[2].code def p_var_type_1(self, p): """var_type : return_type""" print("""var_type -> return_type""") p[0] = Nonterminal() p[0].rtype = p[1].rtype # lvalue1 def p_var_type_1_1(self, p): """var_type : lvalue1""" print("""var_type -> lvalue1""") def p_var_type_2(self, p): """var_type : STATIC return_type""" print("""var_type -> STATIC return_type""") def p_var_type_2_1(self, p): """var_type : STATIC lvalue1""" print("""var_type -> STATIC lvalue1""") def p_return_type_1(self, p): """return_type : INT_TYPE""" print("""return_type -> INT_TYPE""") p[0] = Nonterminal() p[0].rtype = "double" p[0].sym_rtype = "int" def p_return_type_2(self, p): """return_type : REAL_TYPE""" print("""return_type -> REAL_TYPE""") p[0] = Nonterminal() p[0].rtype = "double" p[0].sym_rtype = "real" def p_return_type_3(self, p): """return_type : BOOL_TYPE""" print("""return_type -> BOOL_TYPE""") p[0] = Nonterminal() p[0].rtype = "bool" p[0].sym_rtype = "bool" def p_return_type_4(self, p): """return_type : STRING_TYPE""" print("""return_type -> STRING_TYPE""") p[0] = Nonterminal() p[0].rtype = "char*" p[0].sym_rtype = "string" # def p_return_type_5(self, p): # """return_type : ID""" def p_var_list_1(self, p): """var_list : var_list COMMA var_list_item""" print("""var_list -> var_list COMMA var_list_item""") p[0] = Nonterminal() p[0].code = p[1].code + p[3].code p[0].vars = p[1].vars + p[3].vars def p_var_list_2(self, p): """var_list : var_list_item""" print("""var_list -> var_list_item""") p[0] = Nonterminal() p[0].code = p[1].code p[0].vars = p[1].vars def p_item1(self, p): """item1 : ID ASSIGNMENT exp""" print("""item1 -> ID ASSIGNMENT exp""") p[0] = Nonterminal() p[0].code = p[3].code + p[1] + " = " + p[3].get_value() + ";\n" p[0].vars = [p[1]] def p_var_list_item_2(self, p): """var_list_item : item1""" print("""var_list_item -> item1""") p[0] = Nonterminal() p[0].code = p[1].code p[0].vars = p[1].vars def p_var_list_item_1(self, p): """var_list_item : ID""" print("""var_list_item -> ID""") p[0] = Nonterminal() p[0].code = "" p[0].vars = [p[1]] ############2 def p_func_dec(self, p): """func_dec : var_type func_body""" print("""func_dec -> var_type func_body""") p[0] = Nonterminal() p[0].code = p[2].code p[0].sym_var = p[2].sym_var dic = {} dic["ref"] = "NONE" dic["name"] = p[2].func_name dic["type"] = "FUNCTION" dic["v_type"] = "NONE" dic["size"] = "NONE" dic["address"] = "NONE" dic["return_type"] = p[1] p[0].sym_var.append(dic) def p_func_dec_1(self, p): """func_dec : VOID func_body""" print("""func_dec -> VOID func_body""") p[0] = Nonterminal() p[0].code = p[2].code p[0].sym_var = p[2].sym_var dic = {} dic["ref"] = "NONE" dic["name"] = p[2].func_name dic["type"] = "FUNCTION" dic["v_type"] = "NONE" dic["size"] = "NONE" dic["address"] = "NONE" dic["return_type"] = p[1] p[0].sym_var.append(dic) def p_func_dec_2(self, p): """func_dec : STATIC VOID func_body""" print("""func_dec -> STATIC VOID func_body""") p[0] = Nonterminal() p[0].code = p[3].code p[0].sym_var = p[3].sym_var dic = {} dic["ref"] = "NONE" dic["name"] = p[3].func_name dic["type"] = "FUNCTION" dic["v_type"] = "NONE" dic["size"] = "NONE" dic["address"] = "NONE" dic["return_type"] = p[2] p[0].sym_var.append(dic) def p_func_body(self, p): """func_body : ID LP formal_arguments RP block""" print("""func_body -> ID LP formal_arguments RP block""") p[0] = Nonterminal() return_phrase = "goto end;\n\n" if p[1] == "_main" else CodeGenerator.popReturnAddr(self) + "goto *returnAddress; // return from function\n\n" p[0].code = "//function body ----------- \n" + p[1] + ": //function decleration\n\n" + p[3].code + "\n // function body:\n" + p[5].code + "\n// function ended\n" + return_phrase # self.variable_decs = "" print(p[0].code) p[0].func_name = p[1] p[0].sym_var = p[5].sym_var self.add_ref(p[0].sym_var, self.new_scope_name()) #save a scope self.symbol_table_list.append(p[0].sym_var) def p_formal_arguments(self, p): """formal_arguments : formal_arguments_list""" print("""formal_arguments -> formal_arguments_list""") p[0] = Nonterminal() p[0].code = "// fetching arguments\n\n" + p[1].code p[0].t = p[1].t def p_formal_arguments_e(self, p): """formal_arguments : """ print("""formal_arguments ->/* Lambda */""") p[0] = Nonterminal() p[0].t = 0 p[0].code = "" def p_formal_arguments_list(self, p): """formal_arguments_list : formal_arguments_list COMMA formal_argument""" print("""formal_arguments_list -> formal_arguments_list COMMA formal_argument""") p[0] = Nonterminal() p[0].code = p[3].code + p[1].code p[0].t = p[1].t + p[3].t def p_formal_arguments_list_1(self, p): """formal_arguments_list : formal_argument""" print("""formal_arguments_list -> formal_argument""") p[0] = Nonterminal() p[0].code = p[1].code p[0].t = 1 def p_formal_argument(self, p): """formal_argument : return_type ID""" print("""formal_argument -> return_type ID""") p[0] = Nonterminal() p[0].code = CodeGenerator.popVariable(self, p[2]) p[0].t = 1 # lvalue1 def p_formal_argument_1(self, p): """formal_argument : lvalue1 ID""" print("""formal_argument -> lvalue1 ID""") def p_block(self, p): """block : LCB statements_list RCB""" print("""block -> LCB statements_list RCB""") p[0] = Nonterminal() p[0].code = p[2].code p[0].sym_var = p[2].sym_var def p_block_s(self, p): """block : statement""" print("""block -> statement""") p[0] = Nonterminal() p[0].code = p[1].code p[0].sym_var = p[1].sym_var def p_statements_list(self, p): """statements_list : statements_list statement""" print("""statements_list -> statements_list statement""") p[0] = Nonterminal() p[0].code = p[1].code + p[2].code p[0].sym_var = p[1].sym_var + p[2].sym_var def p_statements_list_e(self, p): """statements_list : """ p[0] = Nonterminal() p[0].code = "" print("""statements_list ->/* Lambda */""") def p_statement(self, p): """statement : SEMICOLON""" print("""statement -> SEMICOLON""") p[0] = Nonterminal() p[0].code = ";" def p_statement0(self, p): """statement : exp SEMICOLON""" # %prec EXPE print("""statement -> exp""") p[0] = Nonterminal() p[0].code = p[1].code + ";\n" def p_statement_1(self, p): """statement : assignment""" print("""statement -> assignment""") p[0] = Nonterminal() p[0].code = p[1].code self.check= False print(p[0].code) def p_statement_2(self, p): """statement : print""" print("""statement -> print""") p[0] = Nonterminal() p[0].code = p[1].code def p_statement_3(self, p): """statement : statement_var_dec""" print("""statement -> statement_var_dec""") p[0] = Nonterminal() p[0].code = p[1].code p[0].sym_var = p[1].sym_var def p_statement_4(self, p): """statement : if""" print("""statement -> if""") p[0] = Nonterminal() p[0].code = p[1].code p[0].sym_var = p[1].sym_var def p_statement_5(self, p): """statement : for""" print("""statement -> for""") p[0] = Nonterminal() p[0].code = p[1].code p[0].sym_var = p[1].sym_var def p_statement_6(self, p): """statement : while""" print("""statement -> while""") p[0] = Nonterminal() p[0].code = p[1].code p[0].sym_var = p[1].sym_var def p_statement_7(self, p): """statement : return""" print("""statement -> return""") p[0] = Nonterminal() p[0].code = p[1].code def p_statement_8(self, p): """statement : break""" print("""statement -> break""") def p_statement_9(self, p): """statement : continue""" print("""statement -> continue""") ############3 def p_assignment(self, p): """assignment : lvalue ASSIGNMENT exp SEMICOLON""" # print("""assignment -> lvalue ASSIGNMENT exp SEMICOLON""") p[0] = Nonterminal() if p[3].func == 1: p[0].code = p[3].code + "\n" + p[1].get_value() + "=" + p[3].get_value() +";\n" print(p[0].code) self.check = True else: p[0].code = p[3].code + p[1].place + " = " + p[3].get_value() + ";\n" if self.check == False: self.FuncVARIABLES.append(p[1].get_value()) def p_lvalue_1(self, p): """lvalue : lvalue1 %prec LVALI""" p[0] = Nonterminal() p[0].code = p[1].code p[0].place = p[1].place print("""lvalue -> lvalue1""") def p_lvalue_2(self, p): """lvalue : lvalue2 %prec LVAL""" p[0] = Nonterminal() p[0].code = p[1].code p[0].place = p[1].place print("""lvalue -> lvalue2""") def p_lval2(self, p): """lvalue2 : ID DOT ID""" print("""lvalue2 -> ID DOT ID""") def p_lval1(self, p): """lvalue1 : ID""" print("""lvalue1 -> ID""") p[0] = Nonterminal() p[0].place = p[1] def p_print(self, p): """print : PRINT LP STRING RP SEMICOLON""" print("""print -> PRINT LP STRING RP SEMICOLON""") p[0] = Nonterminal() p[0].code = 'printf("%lf", ' + p[3].split('{')[1].split('}')[0] + '); \n' def p_statement_var_dec(self, p): """statement_var_dec : return_type var_list SEMICOLON""" print("""statement_var_dec -> return_type var_list SEMICOLON""") p[0] = Nonterminal() self.variable_decs += "\n".join([p[1].rtype + " " + var + ";\n" for var in p[2].vars]) self.VARIABLES += p[2].vars p[0].code = "\n" + p[2].code print("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^") for i in range(0, len(p[2].vars)): dic = {} dic["ref"]="NONE" dic["name"] = p[2].vars[i] dic["type"] = "VARIABLE" dic["v_type"] = p[0].sym_rtype if dic["v_type"] == "int": dic["size"] = 4 elif dic["v_type"] == "real": dic["size"] = 8 elif dic["v_type"] == "bool": dic["size"] = 1 elif dic["v_type"] == "string": dic["size"] = 6 else: dic["size"] = 0 if i == 0 : dic["address"] = "NONE" else: dic["address"] = "NONE" dic["return_type"] = "NONE" p[0].sym_var.append(dic) print(p[0].sym_var) print("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^") def p_statement_var_dec_1(self, p): """statement_var_dec : lvalue1 var_list SEMICOLON""" print("""statement_var_dec -> lvalue1 var_list SEMICOLON""") # def p_if_1(self, p): # """if : IF LP exp RP block %prec IF""" # print("""if -> IF LP exp RP block""") # print("*****************************************************************") # p[0] = Nonterminal() # p[3].code = p[3].ifexp if p[3].ifexp else p[3].code # # print("*****************************************************************") # # print(p[3].true_list) # # print(p[5].code) # # # # token_list = p[5].code.split(':') # # self.backpatch(p[3].true_list, token_list[0]) # # # # token_list = token_list[-2].split(";") # # # print(token_list[-1]) # # # # num = int(token_list[-1].replace("L", "")) # # num = num + 1 # # # # self.backpatch(p[3].false_list, "L"+ str(len(self.code_list))) # # code = "L"+ str(len(self.code_list)) + ": " # # self.code_list.append(code) # # # # print(self.code_list) # # self.produce_output() # # # def p_if_2(self, p): # """if : IF LP exp RP block ELSE block %prec ELSE""" # #%prec IF2 # print("""if -> IF LP exp RP block ELSE block""") # print("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^") # p[0] = Nonterminal() # print("true list") # print(p[3].true_list) # print("false list") # print(p[3].false_list) # print("if code") # print(p[5].code) # true_code = p[5].code # print("else code") # false_code = p[7].code # print(p[7].code) # # token_list = true_code.split(':') # self.backpatch(p[3].true_list, token_list[0]) # # # token_list = false_code.split(':') # self.backpatch(p[3].false_list, token_list[0]) # # print(self.code_list) # self.produce_output() # # def p_if_3(self, p): # """if : IF LP exp RP block elseifs %prec prec2""" # print("hiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii") # p[0] = Nonterminal() # p[0].list = [] # p[3].list = [] # p[3].list.append(p[3].true_list) # p[3].list.append(p[3].false_list) # # num_of_elseifs = len(p[6].list) # # p[0].list = p[6].list # p[0].list.insert(0, p[3].list) # # print(p[0].list) # p[0].code_list = p[6].code # p[0].code_list.insert(0, p[5].code) # # print(p[0].code) # # next_code_label = str(self.get_num_of_last_label(p[0].code_list[-1]) + 1) # code = "L" + next_code_label + ": " # self.code_list.append(code) # # if_list = p[0].list[0] # self.backpatch(if_list[0], self.get_start(p[0].code_list[0])) # self.backpatch(if_list[1], "L" + str(p[0].list[1][0][0])) # # for i in range(1, num_of_elseifs + 1): # c = p[0].code_list[i] # c_list = c.split(";") # code_in_code_list = c_list[-2] + ";" # index = self.code_list.index(code_in_code_list) # new_code_in_code_list = code_in_code_list + "goto " + "L" + next_code_label + ";" # self.code_list.insert(index, new_code_in_code_list) # self.code_list.pop(index + 1) # c = c + "goto " + "L" + next_code_label + ";" # p[0].code_list[i] = c # # for i in range(1, num_of_elseifs + 1): # list = p[0].list[i] # self.backpatch(list[0], self.get_start(p[0].code_list[i])) # if i == num_of_elseifs: # self.backpatch(list[1], self.get_start(p[0].code_list[-1])) # else: # self.backpatch(list[1], code) # # print(self.code_list) # self.produce_output() # print("hiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii") # # def p_if_4(self, p): # """if : IF LP exp RP block elseifs ELSE block %prec prec1""" # print("""if -> IF LP exp RP block elseifs ELSE block""") # print("heyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy") # p[0] = Nonterminal() # p[0].list = [] # p[3].list = [] # p[3].list.append(p[3].true_list) # p[3].list.append(p[3].false_list) # # num_of_elseifs = len(p[6].list) # # p[0].list = p[6].list # p[0].list.insert(0, p[3].list) # # print(p[0].list) # p[0].code_list = p[6].code # p[0].code_list.insert(0, p[5].code) # p[0].code_list.insert(len(p[0].code_list), p[8].code) # # print(p[0].code) # # next_code_label = str(self.get_num_of_last_label(p[0].code_list[-1])+1) # code = "L"+next_code_label+": " # self.code_list.append(code) # # if_list = p[0].list[0] # self.backpatch(if_list[0], self.get_start(p[0].code_list[0])) # self.backpatch(if_list[1], "L" + str(p[0].list[1][0][0])) # # for i in range(1, num_of_elseifs+1): # c = p[0].code_list[i] # c_list = c.split(";") # code_in_code_list = c_list[-2]+";" # index = self.code_list.index(code_in_code_list) # new_code_in_code_list = code_in_code_list + "goto " + "L" + next_code_label + ";" # self.code_list.insert(index, new_code_in_code_list) # self.code_list.pop(index+1) # c = c + "goto " + "L" + next_code_label + ";" # p[0].code_list[i] = c # # for i in range(1, num_of_elseifs + 1): # list = p[0].list[i] # self.backpatch(list[0], self.get_start(p[0].code_list[i])) # if i == num_of_elseifs: # self.backpatch(list[1], self.get_start(p[0].code_list[-1])) # else: # self.backpatch(list[1], "L" + str(p[0].list[i + 1][0][0])) # # print(self.code_list) # self.produce_output() def p_if(self, p): r"""if : IF LP exp RP block elseif_blocks else_block""" print("""if : IF LP exp RP block elseif_blocks else_block""") p[3].code = p[3].ifexp if p[3].ifexp else p[3].code p[0] = Nonterminal() ####sym_table p[0].sym_var = p[5].sym_var + p[6].sym_var + p[7].sym_var self.add_ref(p[0].sym_var, self.new_scope_name()) self.symbol_table_list.append(p[0].sym_var) p[0].true = self.new_label() p[0].next = self.new_label() falselabel = None # back patch true block self.code_generator.back_patch_true(p[3], p[0].true) elseifblock = "" elseblock = "" elselabel = None # create label for else block and set next for it if p[7].code: elselabel = self.new_label() elseblock = elselabel + ": //else\n" + p[7].code elseiflabel = None # check if there is elseif block if p[6].code: elseiflabel = self.new_label() self.code_generator.back_patch_false(p[3], elseiflabel) falselabel = elseiflabel self.code_generator.back_patch_next(p[6], p[0].next) # check for else if p[7].code: self.code_generator.back_patch_false(p[6], elselabel) else: self.code_generator.back_patch_false(p[6], p[0].next) elseifblock = elseiflabel + ": //elseifs\n" + p[6].code # NO elseif check if there is else block elif p[7].code: self.code_generator.back_patch_false(p[3], elselabel) falselabel = elselabel # NO elseif NO else else: self.code_generator.back_patch_false(p[3], p[0].next) falselabel = None true_block = p[0].true + ": " + p[5].code + "goto " + p[0].next + "; //next label\n\n" false_block = "" if falselabel: false_block = elseifblock + elseblock next_block = p[0].next + ": //end of if statement - next\n" p[0].code = "// if statement\n//new\n" + p[3].code + true_block + false_block + next_block print("********************************************************************************************") print(p[0].code) print("********************************************************************************************") def p_elseif_blocks_1(self, p): r"""elseif_blocks : elseifs %prec PREC1""" print("""elseif_blocks : elseifs %prec PREC1""") p[0] = Nonterminal() p[0].code = p[1].code p[0].sym_var = p[1].sym_var def p_elseif_blocks_2(self, p): """elseif_blocks : """ print("""elseif_blocks : """) p[0] = Nonterminal() p[0].code = None def p_elseifs_1(self, p): r"""elseifs : elseifs elseif %prec PREC1""" print("""elseifs : elseifs elseif %prec PREC1""") p[0] = Nonterminal() elseif_label = self.new_label() self.code_generator.back_patch_false(p[1], elseif_label) p[0].code = p[1].code + elseif_label + ": //elseif \n" + p[2].code + "\n" p[0].sym_var = p[1].sym_var + p[2].sym_var def p_elseifs_2(self, p): r"""elseifs : elseif %prec PREC2""" print("""elseifs : elseif %prec PREC2""") p[0] = Nonterminal() p[0].code = p[1].code p[0].sym_var = p[1].sym_var def p_elseif(self, p): r"""elseif : ELSEIF LP exp RP block %prec PREC2""" print("""elseif : ELSEIF LP exp RP block %prec PREC2""") p[0] = Nonterminal() truelabel = self.new_label() self.code_generator.back_patch_true(p[3], truelabel) p[0].code = p[3].code + truelabel + ": //elseif expression\n" + p[5].code + "goto " + self.NEXT_LABEL + "; // next label\n\n" p[0].sym_var = p[5].sym_var self.add_ref(p[0].sym_var, self.new_scope_name()) self.symbol_table_list.append(p[0].sym_var) def p_else_block_1(self, p): r"""else_block : ELSE block %prec PREC2""" print("""else_block : ELSE block %prec PREC2""") p[0] = Nonterminal() p[0].code = p[2].code + "\n" p[0].sym_var = p[2].sym_var self.add_ref(p[0].sym_var, self.new_scope_name()) self.symbol_table_list.append(p[0].sym_var) def p_else_block_2(self, p): r"""else_block : %prec PREC1""" print("""else_block : %prec PREC1""") p[0] = Nonterminal() p[0].code = "" # def p_elseifs_1(self, p): # """elseifs : elseifs elseif""" # print("""elseifs -> elseifs elseif""") # p[0] = Nonterminal() # p[0].code = p[1].code # p[0].code.append(p[2].code) # p[0].list = p[1].list # p[0].list.append(p[2].list) # # print(p[0].list) # # print(p[0].code) # # # # def p_elseifs_2(self, p): # """elseifs : elseif""" # print("""elseifs -> elseif""") # p[0] = Nonterminal() # p[0].code = [] # p[0].code.append(p[1].code) # p[0].list = [] # p[0].list.append(p[1].list) # # print("))))))))))))))))))))))))))))))))))))))))))))))") # # print(p[0].list) # # print(p[0].code) # # # # def p_elseif(self, p): # """elseif : ELSEIF LP exp RP block %prec ELSEIF""" # print("""elseif -> ELSEIF LP exp RP block""") # # print("true_list") # # print(p[3].true_list) # # print("false_list") # # print(p[3].false_list) # # print("code block") # # print(p[5].code) # # p[0] = Nonterminal() # p[0].code = p[5].code # p[0].list = [] # p[0].list.append(p[3].true_list) # p[0].list.append(p[3].false_list) # # print("****************************") # # print(p[0].list) # # # # p[0].pure_code_list def p_for(self, p): """for : FOR LP ID IN exp TO exp STEPS exp RP block""" print("""for -> FOR LP ID IN exp TO exp STEPS exp RP block""") p[0] = Nonterminal() p[0].sym_var = p[11].sym_var self.add_ref(p[0].sym_var, self.new_scope_name()) self.symbol_table_list.append(p[0].sym_var) begin = self.new_label() code_begin = self.new_label() after = self.new_label() initialization = "double " + p[3] + ";\n" + p[3] + " = " + p[5].get_value() + "; // FOR initialization\n" check_bundry = "if ( " + p[3] + " < " + p[7].get_value() + " ) goto " + code_begin + "; // FOR check\n" check_bundry += "goto " + after + ";\n\n" iteration = p[3] + " = " + p[3] + " + " + p[9].get_value() + "; // FOR iteration\n" p[0].code = "// FOR BEGIN\n\n" + p[5].code + p[9].code + initialization + begin + ": // for begin\n\n" + p[7].code + check_bundry + code_begin + ": // for code begin\n" + p[11].code + iteration + "goto " + begin + "; //back to for begin\n\n" + after + ": // end of for\n\n" print("*******************************************************************************") print(p[0].code) print("*******************************************************************************") def p_while(self, p): """while : WHILE LP exp RP block""" print("""while -> WHILE LP exp RP block""") p[0] = Nonterminal() p[0].sym_var = p[5].sym_var self.add_ref(p[0].sym_var, self.new_scope_name()) self.symbol_table_list.append(p[0].sym_var) begin = self.new_label() code_begin = self.new_label() after = self.new_label() self.code_generator.back_patch_false(p[3], after) self.code_generator.back_patch_true(p[3], code_begin) p[0].code = begin + ": // while begin\n\n" + p[3].code + code_begin + ": // while code begin\n" + p[5].code + "goto " + begin + "; //back to while begin\n\n" + after + ": // end of while\n\n" print("*******************************************************************************") print(p[0].code) print("*******************************************************************************") # print(p[3].true_list) # print(p[3].false_list) # print(p[5].code) # self.backpatch(p[3].true_list, self.get_start(p[5].code)) # next_code_label = str(self.get_num_of_last_label(p[5].code) + 1) # code = "L" + next_code_label + ": " # self.code_list.append(code) # self.backpatch(p[3].false_list, "L" + next_code_label) # # # c_list = p[5].code.split(";") # code_in_code_list = c_list[-2] + ";" # index = self.code_list.index(code_in_code_list) # new_code_in_code_list = code_in_code_list + "goto " + "L" + str(p[3].true_list[0]) + ";" # self.code_list.insert(index, new_code_in_code_list) # self.code_list.pop(index + 1) # p[5].code = p[5].code + "goto " + "L" + str(p[3].true_list[0]) + ";" # # # # print(self.code_list) # self.produce_output() def p_return(self, p): """return : RETURN exp SEMICOLON""" print("""return -> RETURN exp SEMICOLON""") p[0] = Nonterminal() p[0].code = "// push return value to stack\n" + p[2].code + CodeGenerator.popReturnAddr(self) p[0].code += CodeGenerator.pushVariable(self, p[2].get_value()) + "goto *returnAddress; // return from function\n\n" def p_break(self, p): """break : BREAK SEMICOLON""" print("""break -> BREAK SEMICOLON""") def p_continue(self, p): """continue : CONTINUE SEMICOLON""" print("""continue -> CONTINUE SEMICOLON""") #######4 # fourth page def p_exp(self, p): """exp : INTEGER""" print("""exp -> INTEGER""") p[0] = Nonterminal() p[0].value = p[1] def p_exp_1(self, p): """exp : REAL""" p[0] = Nonterminal() p[0].value = p[1] print("""exp -> REAL""") def p_exp_2(self, p): """exp : TRUE""" p[0] = Nonterminal() p[0].value = p[1] print("""exp -> TRUE""") def p_exp_3(self, p): """exp : FALSE""" print("""exp -> FALSE""") p[0] = Nonterminal() p[0].value = p[1] def p_exp_4(self, p): """exp : STRING""" print("""exp -> STRING""") p[0] = Nonterminal() p[0].value = p[1] def p_exp_5(self, p): """exp : lvalue""" print("""exp -> lvalue""") p[0] = Nonterminal() p[0].place = p[1].place p[0].ifexp = "if ( " + p[1].place + " ) goto " + self.TRUE_LABEL + ";\n" + "goto " + self.FALSE_LABEL + ";\n\n" def p_exp_6(self, p): """exp : binary_operation %prec BIOP""" print("""exp -> binary_operation""") p[0] = Nonterminal() p[0].code = p[1].code p[0].place = p[1].get_value() def p_exp_7(self, p): """exp : logical_operation""" print("""exp -> logical_operation""") p[0] = Nonterminal() p[0].code = p[1].code p[0].place = p[1].get_value() def p_exp_8(self, p): """exp : comparison_operation %prec COMOP""" print("""exp -> comparison_operation""") p[0] = Nonterminal() p[0].code = p[1].code def p_exp_9(self, p): """exp : bitwise_operation %prec BITOP""" print("""exp -> bitwise_operation""") p[0] = Nonterminal() p[0].code = "NOT YET BITWISE" def p_exp_10(self, p): """exp : unary_operation""" print("""exp -> unary_operation""") p[0] = Nonterminal() p[0].code = p[1].code p[0].place = p[1].get_value() def p_exp_11(self, p): """exp : LP exp RP""" print("""exp -> LP exp RP""") p[0] = Nonterminal() p[0].place = p[2].place p[0].code = p[2].code def p_exp_12(self, p): """exp : function_call""" print("""exp -> function_call""") p[0] = Nonterminal() p[0] = p[1] p[0].code = p[1].code p[0].place = p[1].get_value() p[0].func = 1 def p_binary_operation(self, p): """binary_operation : exp ADDITION exp """ print("""binary_operation -> exp ADDITION exp """) p[0] = Nonterminal() self.code_generator.binary_operation_code(p, self.new_temp()) def p_binary_operation_1(self, p): """binary_operation : exp SUBTRACTION exp""" print("""binary_operation -> exp SUBTRACTION exp""") p[0] = Nonterminal() self.code_generator.binary_operation_code(p, self.new_temp()) def p_binary_operation_2(self, p): """binary_operation : exp MULTIPLICATION exp""" print("""binary_operation -> exp MULTIPLICATION exp""") p[0] = Nonterminal() self.code_generator.binary_operation_code(p, self.new_temp()) def p_binary_operation_3(self, p): """binary_operation : exp DIVISION exp""" print("""binary_operation -> exp DIVISION exp""") p[0] = Nonterminal() self.code_generator.binary_operation_code(p, self.new_temp()) def p_binary_operation_4(self, p): """binary_operation : exp MODULO exp""" print("""binary_operation -> exp MODULO exp""") p[0] = Nonterminal() self.code_generator.binary_operation_code(p, self.new_temp()) def p_binary_operation_5(self, p): """binary_operation : exp POWER exp""" print("""binary_operation -> exp POWER exp""") p[0] = Nonterminal() self.code_generator.binary_operation_code(p, self.new_temp()) def p_binary_operation_6(self, p): """binary_operation : exp SHIFT_LEFT exp""" print("""binary_operation -> exp SHIFT_LEFT exp""") p[0] = Nonterminal() self.code_generator.binary_operation_code(p, self.new_temp()) def p_binary_operation_7(self, p): """binary_operation : exp SHIFT_RIGHT exp""" print("""binary_operation -> exp SHIFT_RIGHT exp""") p[0] = Nonterminal() self.code_generator.binary_operation_code(p, self.new_temp()) def p_logical_operation(self, p): """logical_operation : exp AND exp""" print("""logical_operation -> exp AND exp""") p[0] = Nonterminal() true_label = self.new_label() self.code_generator.back_patch_true(p[1], true_label) p[0].code = p[1].code + true_label + ": // logical calculation (AND)\n" + p[3].code def p_logical_operation_1(self, p): """logical_operation : exp OR exp""" print("""logical_operation -> exp OR exp""") p[0] = Nonterminal() false_label = self.new_label() self.code_generator.back_patch_false(p[1], false_label) p[0].code = p[1].code + false_label + ": // logical calculation (OR)\n" + p[3].code #######5 def p_comparison_operation_1(self, p): """comparison_operation : exp LT exp""" print("""comparison_operation -> exp LT exp""") p[0] = Nonterminal() self.code_generator.comparison_operation_code(p) def p_comparison_operation_2(self, p): """comparison_operation : exp LE exp""" print("""comparison_operation -> exp LE exp""") p[0] = Nonterminal() self.code_generator.comparison_operation_code(p) def p_comparison_operation_3(self, p): """comparison_operation : exp GT exp""" print("""comparison_operation -> exp GT exp""") p[0] = Nonterminal() self.code_generator.comparison_operation_code(p) def p_comparison_operation_4(self, p): """comparison_operation : exp GE exp""" print("""comparison_operation -> exp GE exp""") p[0] = Nonterminal() self.code_generator.comparison_operation_code(p) def p_comparison_operation_5(self, p): """comparison_operation : exp EQ exp""" print("""comparison_operation -> exp EQ exp""") p[0] = Nonterminal() self.code_generator.comparison_operation_code(p) def p_comparison_operation_6(self, p): """comparison_operation : exp NE exp""" print("""comparison_operation -> exp NE exp""") p[0] = Nonterminal() self.code_generator.comparison_operation_code(p) def p_bitwise_operation_1(self, p): """bitwise_operation : exp BITWISE_AND exp""" print("""bitwise_operation -> exp BITWISE_AND exp""") p[0] = Nonterminal() self.code_generator.binary_operation_code(p, self.new_temp()) def p_bitwise_operation_2(self, p): """bitwise_operation : exp BITWISE_OR exp""" print("""bitwise_operation -> exp BITWISE_OR exp""") p[0] = Nonterminal() self.code_generator.binary_operation_code(p, self.new_temp()) def p_unary_operation_1(self, p): """unary_operation : SUBTRACTION exp %prec UMINUS""" print("""unary_operation -> SUBTRACTION exp""") p[0] = Nonterminal() self.code_generator.unary_operation_code(p, self.new_temp()) def p_unary_operation_2(self, p): """unary_operation : NOT exp""" print("""unary_operation -> NOT exp""") p[0] = Nonterminal() self.code_generator.unary_operation_code(p, self.new_temp()) def p_unary_operation_3(self, p): """unary_operation : BITWISE_NOT exp""" print("""unary_operation -> BITWISE_NOT exp""") p[0] = Nonterminal() self.code_generator.unary_operation_code(p, self.new_temp()) def p_function_call_2(self, p): """function_call : lvalue2 function_call_body""" print("""function_call -> lvalue2 function_call_body""") def p_function_call_1(self, p): """function_call : lvalue1 function_call_body""" print("""function_call -> lvalue1 function_call_body""") p[0] = Nonterminal() label = self.new_label() p[0].args = p[2].args if self.t_counter > -1 : for i in range(0, self.t_counter): self.FuncVARIABLES.append("TT"+str(i)) p[0].code = CodeGenerator.storeVariables(self, self.FuncVARIABLES) + CodeGenerator.pushAddress(self,label) p[0].code += "// store arguments\n" + p[2].code + CodeGenerator.storeArgs(self,p[2].args)+ "\n goto " + p[1].get_value() + ";\n" p[0].place = self.new_temp() p[0].code += "// return label:\n" + label + ":\n" + "// load return value\n" + CodeGenerator.popVariable(self,p[0].place) +"\n //varaiables:" + CodeGenerator.loadVariables(self,self.FuncVARIABLES) print(p[0].code) print("-------------function call--------------") def p_function_call_body(self, p): """function_call_body : LP actual_arguments RP""" print("""function_call_body -> LP actual_arguments RP""") p[0] = Nonterminal() p[0] = p[2] def p_actual_arguments(self, p): """actual_arguments : actual_arguments_list""" print("""actual_arguments -> actual_arguments_list""") p[0] = Nonterminal() p[0].code = p[1].code p[0]=p[1] def p_actual_arguments_e(self, p): """actual_arguments : """ print("""actual_arguments ->/* Lambda */""") p[0] = Nonterminal() p[0].code = "" p[0].args = "" def p_actual_arguments_list_1(self, p): """actual_arguments_list : actual_arguments_list COMMA exp""" print("""actual_arguments_list -> actual_arguments_list COMMA exp""") p[0] = Nonterminal() p[0].code = p[1].code + p[3].code p[0].args = p[1].args p[0].args.append(p[3].get_value()) def p_actual_arguments_list_2(self, p): """actual_arguments_list : exp""" print("""actual_arguments_list -> exp""") p[0] = Nonterminal() p[0].code = p[1].code p[0].args.append(p[1].get_value()) precedence = ( ('nonassoc', 'PREC2'), ('nonassoc', 'PREC1'), ('nonassoc', 'LVALI'), ('nonassoc', 'LVAL'), ('nonassoc', 'BIOP'), ('nonassoc', 'COMOP'), ('nonassoc', 'BITOP'), ('left', 'IF'), ('left', 'ELSE'), ('left', 'ELSEIF'), ('left', 'COMMA'), ('left', 'ASSIGNMENT'), ('left', 'OR'), ('left', 'AND'), ('left', 'NOT'), ('left', 'BITWISE_OR'), ('left', 'BITWISE_AND'), ('left', 'BITWISE_NOT'), ('left', 'LE', 'EQ', 'NE', 'GE', 'GT', 'LT'), # ('left', 'SHIFT_LEFT', 'SHIFT_RIGHT'), ('left', 'ADDITION', 'SUBTRACTION'), ('left', 'MULTIPLICATION', 'DIVISION'), ('left', 'SHIFT_LEFT', 'SHIFT_RIGHT'), ('left', 'POWER'), ('left', 'MODULO'), ('left', 'UMINUS'), ('left', 'RP', 'LP'), # ('right', 'PREC3'), # ('right', 'PREC2'), # ('right', 'PREC1'), # ('right', 'ELSEIF') ) def add_ref(self, list_dic, scope_name): for dic in list_dic: dic["ref"] = scope_name def new_scope_name(self): self.scope_counter += 1 return "scope" + str(self.t_counter) def new_temp(self): self.t_counter += 1 return "TT" + str(self.t_counter) def new_label(self): self.l_counter += 1 return "L" + str(self.l_counter) def backpatch(self, in_list, m): # print("backpatch") # print(in_list) # print(m) for index in in_list: # print("in for") # print(index) # print(m) code = self.code_list[index] # print(code) new_code = code.replace("_", str(m)) # print(code) self.code_list[index] = new_code def get_start(self, s): s_list = s.split(":") return s_list[0] def get_num_of_last_label(self, s): s_list = s.split(";") s_list = s_list[-2].split(':') num = int(s_list[0].replace("L","")) return num def produce_output(self): file = open("final_result.c", "w") s = "#include <stdio.h>"+"\n" s += "int main(){"+"\n" # if self.t_counter > -1 : # s += "double " # for i in range(0, self.t_counter+1): s += "\n".join(self.code_list) s += "\n" + "}" file.write(s) file.close() def build(self, **kwargs): """build the parser""" self.parser = yacc.yacc(module=self, **kwargs) return self.parser
def p_formal_argument(self, p): """formal_argument : return_type ID""" print("""formal_argument -> return_type ID""") p[0] = Nonterminal() p[0].code = CodeGenerator.popVariable(self, p[2]) p[0].t = 1
def __init__(self): self.t_counter = -1 self.l_counter = -1 self.code_generator = CodeGenerator() self.code_list = []
class Parser: def __init__(self): self.t_counter = -1 self.l_counter = -1 self.code_generator = CodeGenerator() self.code_list = [] tokens = l.tokens def p_program(self, p): '''program : macros classes''' print('''program -> macros classes''') def p_macros(self, p): """macros : macros macro""" print("""macros -> macros macro""") def p_macros_e(self, p): """macros : """ print("""macros ->/* Lambda */""") def p_macro(self, p): """macro : reference""" print("""macro -> reference""") def p_reference(self, p): """reference : REFERENCE STRING""" print("""reference -> REFERENCE STRING""") def p_classes(self, p): """classes : classes class""" print("""classes -> classes class""") def p_classes_e(self, p): """classes : """ print("""classes ->/* Lambda */""") def p_class(self, p): """class : CLASS ID LCB symbol_decs RCB""" print("""class -> CLASS ID LCB symbol_decs RCB""") def p_symbol_decs(self, p): """symbol_decs : symbol_decs symbol_dec""" print("""symbol_decs -> symbol_decs symbol_dec""") def p_symbol_decs_e(self, p): """symbol_decs : """ print("""symbol_decs ->/* Lambda */""") def p_symbol_dec_1(self, p): """symbol_dec : var_dec""" print("""symbol_dec -> var_dec""") def p_symbol_dec_2(self, p): """symbol_dec : func_dec""" print("""symbol_dec -> func_dec""") def p_var_dec(self, p): """var_dec : var_type var_list SEMICOLON""" print("""var_dec -> var_type var_list SEMICOLON""") def p_var_type_1(self, p): """var_type : return_type""" print("""var_type -> return_type""") # lvalue1 def p_var_type_1_1(self, p): """var_type : lvalue1""" print("""var_type -> lvalue1""") def p_var_type_2(self, p): """var_type : STATIC return_type""" print("""var_type -> STATIC return_type""") def p_var_type_2_1(self, p): """var_type : STATIC lvalue1""" print("""var_type -> STATIC lvalue1""") def p_return_type_1(self, p): """return_type : INT_TYPE""" print("""return_type -> INT_TYPE""") def p_return_type_2(self, p): """return_type : REAL_TYPE""" print("""return_type -> REAL_TYPE""") def p_return_type_3(self, p): """return_type : BOOL_TYPE""" print("""return_type -> BOOL_TYPE""") def p_return_type_4(self, p): """return_type : STRING_TYPE""" print("""return_type -> STRING_TYPE""") # def p_return_type_5(self, p): # """return_type : ID""" def p_var_list_1(self, p): """var_list : var_list COMMA var_list_item""" p[0] = Nonterminal() print("""var_list -> var_list COMMA var_list_item""") def p_var_list_2(self, p): """var_list : var_list_item""" print("""var_list -> var_list_item""") def p_item1(self, p): """item1 : ID ASSIGNMENT exp""" print("""item1 -> ID ASSIGNMENT exp""") def p_var_list_item_2(self, p): """var_list_item : item1""" print("""var_list_item -> item1""") def p_var_list_item_1(self, p): """var_list_item : ID""" p[0] = Nonterminal() p[0].value = p[1] p[0].code = "double " + p[0].value + ";" self.code_list.append(p[0].code) print("""var_list_item -> ID""") ############2 def p_func_dec(self, p): """func_dec : var_type func_body""" print("""func_dec -> var_type func_body""") def p_func_dec_1(self, p): """func_dec : VOID func_body""" print("""func_dec -> VOID func_body""") def p_func_dec_2(self, p): """func_dec : STATIC VOID func_body""" print("""func_dec -> STATIC VOID func_body""") def p_func_body(self, p): """func_body : ID LP formal_arguments RP block""" print("""func_body -> ID LP formal_arguments RP block""") def p_formal_arguments(self, p): """formal_arguments : formal_arguments_list""" print("""formal_arguments -> formal_arguments_list""") def p_formal_arguments_e(self, p): """formal_arguments : """ print("""formal_arguments ->/* Lambda */""") def p_formal_arguments_list(self, p): """formal_arguments_list : formal_arguments_list COMMA formal_argument""" print( """formal_arguments_list -> formal_arguments_list COMMA formal_argument""" ) def p_formal_arguments_list_1(self, p): """formal_arguments_list : formal_argument""" print("""formal_arguments_list -> formal_argument""") def p_formal_argument(self, p): """formal_argument : return_type ID""" print("""formal_argument -> return_type ID""") # lvalue1 def p_formal_argument_1(self, p): """formal_argument : lvalue1 ID""" print("""formal_argument -> lvalue1 ID""") def p_block(self, p): """block : LCB statements_list RCB""" p[0] = p[2] print("""block -> LCB statements_list RCB""") def p_block_s(self, p): """block : statement""" p[0] = p[1] print("""block -> statement""") def p_statements_list(self, p): """statements_list : statements_list statement""" print("""statements_list -> statements_list statement""") p[0] = Nonterminal() p[0].code = p[1].code + p[2].code print(p[0].code) def p_statements_list_e(self, p): """statements_list : """ p[0] = Nonterminal() p[0].code = "" print("""statements_list ->/* Lambda */""") def p_statement(self, p): """statement : SEMICOLON""" p[0] = Nonterminal() print("""statement -> SEMICOLON""") def p_statement0(self, p): """statement : exp SEMICOLON""" p[0] = p[1] # %prec EXPE print("""statement -> exp""") def p_statement_1(self, p): """statement : assignment""" p[0] = p[1] print("""statement -> assignment""") def p_statement_2(self, p): """statement : print""" p[0] = p[1] print("""statement -> print""") def p_statement_3(self, p): """statement : statement_var_dec""" p[0] = p[1] print("""statement -> statement_var_dec""") def p_statement_4(self, p): """statement : if""" p[0] = p[1] print("""statement -> if""") def p_statement_5(self, p): """statement : for""" p[0] = p[1] print("""statement -> for""") def p_statement_6(self, p): """statement : while""" p[0] = p[1] print("""statement -> while""") def p_statement_7(self, p): """statement : return""" print("""statement -> return""") def p_statement_8(self, p): """statement : break""" print("""statement -> break""") def p_statement_9(self, p): """statement : continue""" print("""statement -> continue""") ############3 def p_assignment(self, p): """assignment : lvalue ASSIGNMENT exp SEMICOLON""" # print("""assignment -> lvalue ASSIGNMENT exp SEMICOLON""") p[0] = Nonterminal() if p[3].place != "": print(p[3].code) p[0].code = "L" + str(len( self.code_list)) + ": " + p[1].value + "=" + p[3].place + ";" p[0].address = len(self.code_list) self.code_list.append(p[0].code) p[0].code = p[3].code + p[0].code print(self.code_list) self.produce_output() elif p[3].value != "": p[0].code = "L" + str(len( self.code_list)) + ": " + p[1].value + "=" + p[3].value + ";" p[0].address = len(self.code_list) self.code_list.append(p[0].code) print(self.code_list) self.produce_output() else: true_label = len(self.code_list) false_label = true_label + 2 c = "L" + str(true_label) + ": " + p[1].value + "=" + "true" + ";" self.code_list.append(c) d = "L" + str(len( self.code_list)) + ": " + "goto " + str(false_label + 1) + ";" self.code_list.append(d) c = "L" + str( false_label) + ": " + p[1].value + "=" + "false" + ";" self.code_list.append(c) d = "L" + str(false_label + 1) + ": " self.code_list.append(d) for code in self.code_list: index = self.code_list.index(code) if "goto" in code and "_" in code: if "if" in code: new_code = code.replace("_", "L" + str(true_label)) self.code_list[index] = new_code else: new_code = code.replace("_", "L" + str(false_label)) self.code_list[index] = new_code print(self.code_list) self.produce_output() def p_lvalue_1(self, p): """lvalue : lvalue1 %prec LVALI""" p[0] = p[1] print("""lvalue -> lvalue1""") def p_lvalue_2(self, p): """lvalue : lvalue2 %prec LVAL""" print("""lvalue -> lvalue2""") def p_lval2(self, p): """lvalue2 : ID DOT ID""" print("""lvalue2 -> ID DOT ID""") def p_lval1(self, p): """lvalue1 : ID""" p[0] = Nonterminal() p[0].value = p[1] print("""lvalue1 -> ID""") def p_print(self, p): """print : PRINT LP STRING RP SEMICOLON""" p[0] = Nonterminal() print("""print -> PRINT LP STRING RP SEMICOLON""") p[0].code = p[1] + p[2] + p[3] + p[4] + p[5] self.code_list.append((p[0].code)) self.produce_output() def p_statement_var_dec(self, p): """statement_var_dec : return_type var_list SEMICOLON""" p[0] = Nonterminal() print("""statement_var_dec -> return_type var_list SEMICOLON""") def p_statement_var_dec_1(self, p): """statement_var_dec : lvalue1 var_list SEMICOLON""" print("""statement_var_dec -> lvalue1 var_list SEMICOLON""") # lvalue1 def p_m(self, p): """m : """ p[0] = Nonterminal() p[0].quad = len(self.code_list) def p_n(self, p): """n : """ def p_if_1(self, p): """if : IF LP exp RP block %prec IF""" print("""if -> IF LP exp RP block""") print("***************************************************") p[0] = Nonterminal() print(p[3].true_list) print(p[5].code) token_list = p[5].code.split(':') self.backpatch(p[3].true_list, token_list[0]) token_list = token_list[-2].split(";") # print(token_list[-1]) num = int(token_list[-1].replace("L", "")) num = num + 1 self.backpatch(p[3].false_list, "L" + str(len(self.code_list))) code = "L" + str(len(self.code_list)) + ": " self.code_list.append(code) print(self.code_list) self.produce_output() def p_if_2(self, p): """if : IF LP exp RP block ELSE block %prec ELSE""" #%prec IF2 print("""if -> IF LP exp RP block ELSE block""") print("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^") p[0] = Nonterminal() print("true list") print(p[3].true_list) print("false list") print(p[3].false_list) print("if code") print(p[5].code) true_code = p[5].code print("else code") false_code = p[7].code print(p[7].code) token_list = true_code.split(':') self.backpatch(p[3].true_list, token_list[0]) # token_list = false_code.split(':') self.backpatch(p[3].false_list, token_list[0]) print(self.code_list) self.produce_output() def p_if_3(self, p): """if : IF LP exp RP block elseifs %prec prec2""" print( "hiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii" ) p[0] = Nonterminal() p[0].list = [] p[3].list = [] p[3].list.append(p[3].true_list) p[3].list.append(p[3].false_list) num_of_elseifs = len(p[6].list) p[0].list = p[6].list p[0].list.insert(0, p[3].list) # print(p[0].list) p[0].code_list = p[6].code p[0].code_list.insert(0, p[5].code) # print(p[0].code) next_code_label = str( self.get_num_of_last_label(p[0].code_list[-1]) + 1) code = "L" + next_code_label + ": " self.code_list.append(code) if_list = p[0].list[0] self.backpatch(if_list[0], self.get_start(p[0].code_list[0])) self.backpatch(if_list[1], "L" + str(p[0].list[1][0][0])) for i in range(1, num_of_elseifs + 1): c = p[0].code_list[i] c_list = c.split(";") code_in_code_list = c_list[-2] + ";" index = self.code_list.index(code_in_code_list) new_code_in_code_list = code_in_code_list + "goto " + "L" + next_code_label + ";" self.code_list.insert(index, new_code_in_code_list) self.code_list.pop(index + 1) c = c + "goto " + "L" + next_code_label + ";" p[0].code_list[i] = c for i in range(1, num_of_elseifs + 1): list = p[0].list[i] self.backpatch(list[0], self.get_start(p[0].code_list[i])) if i == num_of_elseifs: self.backpatch(list[1], self.get_start(p[0].code_list[-1])) else: self.backpatch(list[1], code) print(self.code_list) self.produce_output() print( "hiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii" ) def p_if_4(self, p): """if : IF LP exp RP block elseifs ELSE block %prec prec1""" print("""if -> IF LP exp RP block elseifs ELSE block""") print( "heyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy" ) p[0] = Nonterminal() p[0].list = [] p[3].list = [] p[3].list.append(p[3].true_list) p[3].list.append(p[3].false_list) num_of_elseifs = len(p[6].list) p[0].list = p[6].list p[0].list.insert(0, p[3].list) # print(p[0].list) p[0].code_list = p[6].code p[0].code_list.insert(0, p[5].code) p[0].code_list.insert(len(p[0].code_list), p[8].code) # print(p[0].code) next_code_label = str( self.get_num_of_last_label(p[0].code_list[-1]) + 1) code = "L" + next_code_label + ": " self.code_list.append(code) if_list = p[0].list[0] self.backpatch(if_list[0], self.get_start(p[0].code_list[0])) self.backpatch(if_list[1], "L" + str(p[0].list[1][0][0])) for i in range(1, num_of_elseifs + 1): c = p[0].code_list[i] c_list = c.split(";") code_in_code_list = c_list[-2] + ";" index = self.code_list.index(code_in_code_list) new_code_in_code_list = code_in_code_list + "goto " + "L" + next_code_label + ";" self.code_list.insert(index, new_code_in_code_list) self.code_list.pop(index + 1) c = c + "goto " + "L" + next_code_label + ";" p[0].code_list[i] = c for i in range(1, num_of_elseifs + 1): list = p[0].list[i] self.backpatch(list[0], self.get_start(p[0].code_list[i])) if i == num_of_elseifs: self.backpatch(list[1], self.get_start(p[0].code_list[-1])) else: self.backpatch(list[1], "L" + str(p[0].list[i + 1][0][0])) print(self.code_list) self.produce_output() def p_elseifs_1(self, p): """elseifs : elseifs elseif""" print("""elseifs -> elseifs elseif""") p[0] = Nonterminal() p[0].code = p[1].code p[0].code.append(p[2].code) p[0].list = p[1].list p[0].list.append(p[2].list) # print(p[0].list) # print(p[0].code) def p_elseifs_2(self, p): """elseifs : elseif""" print("""elseifs -> elseif""") p[0] = Nonterminal() p[0].code = [] p[0].code.append(p[1].code) p[0].list = [] p[0].list.append(p[1].list) # print("))))))))))))))))))))))))))))))))))))))))))))))") # print(p[0].list) # print(p[0].code) def p_elseif(self, p): """elseif : ELSEIF LP exp RP block %prec ELSEIF""" print("""elseif -> ELSEIF LP exp RP block""") # print("true_list") # print(p[3].true_list) # print("false_list") # print(p[3].false_list) # print("code block") # print(p[5].code) p[0] = Nonterminal() p[0].code = p[5].code p[0].list = [] p[0].list.append(p[3].true_list) p[0].list.append(p[3].false_list) # print("****************************") # print(p[0].list) # p[0].pure_code_list def p_for(self, p): """for : FOR LP ID IN exp TO exp STEPS exp RP block""" print("""for -> FOR LP ID IN exp TO exp STEPS exp RP block""") def p_while(self, p): """while : WHILE LP exp RP block""" print("""while -> WHILE LP exp RP block""") print("*************************************************") p[0] = Nonterminal() print(p[3].true_list) print(p[3].false_list) print(p[5].code) self.backpatch(p[3].true_list, self.get_start(p[5].code)) next_code_label = str(self.get_num_of_last_label(p[5].code) + 1) code = "L" + next_code_label + ": " self.code_list.append(code) self.backpatch(p[3].false_list, "L" + next_code_label) c_list = p[5].code.split(";") code_in_code_list = c_list[-2] + ";" index = self.code_list.index(code_in_code_list) new_code_in_code_list = code_in_code_list + "goto " + "L" + str( p[3].true_list[0]) + ";" self.code_list.insert(index, new_code_in_code_list) self.code_list.pop(index + 1) p[5].code = p[5].code + "goto " + "L" + str(p[3].true_list[0]) + ";" print(self.code_list) self.produce_output() print("*************************************************") def p_return(self, p): """return : RETURN exp SEMICOLON""" print("""return -> RETURN exp SEMICOLON""") def p_break(self, p): """break : BREAK SEMICOLON""" print("""break -> BREAK SEMICOLON""") def p_continue(self, p): """continue : CONTINUE SEMICOLON""" print("""continue -> CONTINUE SEMICOLON""") #######4 # fourth page def p_exp(self, p): """exp : INTEGER""" print("""exp -> INTEGER""") p[0] = Nonterminal() p[0].type = "int" p[0].value = p[1] def p_exp_1(self, p): """exp : REAL""" p[0] = Nonterminal() p[0].type = "real" p[0].value = p[1] # print("""exp -> REAL""") def p_exp_2(self, p): """exp : TRUE""" p[0] = Nonterminal() p[0].type = "bool" next_quad = len(self.code_list) p[0].true_list = [next_quad] p[0].m = next_quad + 1 code = "L" + str(next_quad) + ": " + "goto _" + ";" self.code_list.append(code) # print("""exp -> TRUE""") def p_exp_3(self, p): """exp : FALSE""" # print("""exp -> FALSE""") p[0] = Nonterminal() next_quad = len(self.code_list) p[0].false_list = [next_quad] p[0].m = next_quad + 1 code = "L" + str(next_quad) + ": " + "goto _" + ";" self.code_list.append(code) def p_exp_4(self, p): """exp : STRING""" print("""exp -> STRING""") def p_exp_5(self, p): """exp : lvalue""" p[0] = p[1] # print("""exp -> lvalue""") def p_exp_6(self, p): """exp : binary_operation %prec BIOP""" p[0] = p[1] # print("""exp -> binary_operation""") def p_exp_7(self, p): """exp : logical_operation""" p[0] = p[1] # print("""exp -> logical_operation""") def p_exp_8(self, p): """exp : comparison_operation %prec COMOP""" p[0] = p[1] # print("""exp -> comparison_operation""") def p_exp_9(self, p): """exp : bitwise_operation %prec BITOP""" print("""exp -> bitwise_operation""") def p_exp_10(self, p): """exp : unary_operation""" p[0] = p[1] # print("""exp -> unary_operation""") def p_exp_11(self, p): """exp : LP exp RP""" p[0] = p[1] # print("""exp -> LP exp RP""") def p_exp_12(self, p): """exp : function_call""" print("""exp -> function_call""") def p_binary_operation(self, p): """binary_operation : exp ADDITION exp """ print("""binary_operation -> exp ADDITION exp """) self.code_generator.generate_arithmetic_code(p, self.new_temp(), self.code_list) def p_binary_operation_1(self, p): """binary_operation : exp SUBTRACTION exp""" print("""binary_operation -> exp SUBTRACTION exp""") self.code_generator.generate_arithmetic_code(p, self.new_temp(), self.code_list) def p_binary_operation_2(self, p): """binary_operation : exp MULTIPLICATION exp""" print("""binary_operation -> exp MULTIPLICATION exp""") self.code_generator.generate_arithmetic_code(p, self.new_temp(), self.code_list) def p_binary_operation_3(self, p): """binary_operation : exp DIVISION exp""" print("""binary_operation -> exp DIVISION exp""") self.code_generator.generate_arithmetic_code(p, self.new_temp(), self.code_list) def p_binary_operation_4(self, p): """binary_operation : exp MODULO exp""" print("""binary_operation -> exp MODULO exp""") self.code_generator.generate_arithmetic_code(p, self.new_temp(), self.code_list) def p_binary_operation_5(self, p): """binary_operation : exp POWER exp""" print("""binary_operation -> exp POWER exp""") self.code_generator.generate_arithmetic_code(p, self.new_temp(), self.code_list) def p_binary_operation_6(self, p): """binary_operation : exp SHIFT_LEFT exp""" print("""binary_operation -> exp SHIFT_LEFT exp""") self.code_generator.generate_arithmetic_code(p, self.new_temp(), self.code_list) def p_binary_operation_7(self, p): """binary_operation : exp SHIFT_RIGHT exp""" print("""binary_operation -> exp SHIFT_RIGHT exp""") self.code_generator.generate_arithmetic_code(p, self.new_temp(), self.code_list) def p_logical_operation(self, p): """logical_operation : exp AND exp""" print("""logical_operation -> exp AND exp""") p[0] = Nonterminal() m = p[1].m self.backpatch(p[1].true_list, m) p[0].false_list = p[1].false_list + p[3].false_list p[0].true_list = p[3].true_list p[0].code = self.code_list print(self.code_list) self.produce_output() def p_logical_operation_1(self, p): """logical_operation : exp OR exp""" print("""logical_operation -> exp OR exp""") p[0] = Nonterminal() m = p[1].m self.backpatch(p[1].false_list, m) p[0].true_list = p[1].true_list + p[3].true_list p[0].false_list = p[3].false_list p[0].code = self.code_list print(self.code_list) self.produce_output() #######5 def p_comparison_operation_1(self, p): """comparison_operation : exp LT exp""" print("""comparison_operation -> exp LT exp""") self.code_generator.generate_boolean_code(p, self.code_list) def p_comparison_operation_2(self, p): """comparison_operation : exp LE exp""" print("""comparison_operation -> exp LE exp""") self.code_generator.generate_boolean_code(p, self.code_list) def p_comparison_operation_3(self, p): """comparison_operation : exp GT exp""" print("""comparison_operation -> exp GT exp""") self.code_generator.generate_boolean_code(p, self.code_list) def p_comparison_operation_4(self, p): """comparison_operation : exp GE exp""" print("""comparison_operation -> exp GE exp""") self.code_generator.generate_boolean_code(p, self.code_list) def p_comparison_operation_5(self, p): """comparison_operation : exp EQ exp""" print("""comparison_operation -> exp EQ exp""") self.code_generator.generate_boolean_code(p, self.code_list) def p_comparison_operation_6(self, p): """comparison_operation : exp NE exp""" print("""comparison_operation -> exp NE exp""") self.code_generator.generate_boolean_code(p, self.code_list) def p_bitwise_operation_1(self, p): """bitwise_operation : exp BITWISE_AND exp""" print("""bitwise_operation -> exp BITWISE_AND exp""") self.code_generator.generate_arithmetic_code(p, self.new_temp(), self.code_list) def p_bitwise_operation_2(self, p): """bitwise_operation : exp BITWISE_OR exp""" print("""bitwise_operation -> exp BITWISE_OR exp""") self.code_generator.generate_arithmetic_code(p, self.new_temp(), self.code_list) def p_unary_operation_1(self, p): """unary_operation : SUBTRACTION exp %prec UMINUS""" print("""unary_operation -> SUBTRACTION exp""") self.code_generator.generate_arithmetic_code(p, self.new_temp(), self.code_list) def p_unary_operation_2(self, p): """unary_operation : NOT exp""" print("""unary_operation -> NOT exp""") p[0] = Nonterminal() p[0].place = self.new_temp() arg1 = p[1] arg2 = p[2].value p[0].code = "L" + str(len( self.code_list)) + ": " + p[0].place + "=" + arg1 + arg2 + ";" self.code_list.append(p[0].code) print(self.code_list) self.produce_output() def p_unary_operation_3(self, p): """unary_operation : BITWISE_NOT exp""" print("""unary_operation -> BITWISE_NOT exp""") self.code_generator.generate_arithmetic_code(p, self.new_temp(), self.code_list) def p_function_call_2(self, p): """function_call : lvalue2 function_call_body""" print("""function_call -> lvalue2 function_call_body""") def p_function_call_1(self, p): """function_call : lvalue1 function_call_body""" print("""function_call -> lvalue1 function_call_body""") def p_function_call_body(self, p): """function_call_body : LP actual_arguments RP""" print("""function_call_body -> LP actual_arguments RP""") def p_actual_arguments(self, p): """actual_arguments : actual_arguments_list""" print("""actual_arguments -> actual_arguments_list""") def p_actual_arguments_e(self, p): """actual_arguments : """ print("""actual_arguments ->/* Lambda */""") def p_actual_arguments_list_1(self, p): """actual_arguments_list : actual_arguments_list COMMA exp""" print("""actual_arguments_list -> actual_arguments_list COMMA exp""") def p_actual_arguments_list_2(self, p): """actual_arguments_list : exp""" print("""actual_arguments_list -> exp""") # def p_id_rule(self, p): # """id_rule : ID""" precedence = ( ('nonassoc', 'prec2'), ('nonassoc', 'prec1'), ('nonassoc', 'LVALI'), ('nonassoc', 'LVAL'), ('nonassoc', 'BIOP'), ('nonassoc', 'COMOP'), ('nonassoc', 'BITOP'), ('left', 'IF'), ('left', 'ELSE'), ('left', 'ELSEIF'), ('left', 'COMMA'), ('left', 'ASSIGNMENT'), ('left', 'OR'), ('left', 'AND'), ('left', 'NOT'), ('left', 'BITWISE_OR'), ('left', 'BITWISE_AND'), ('left', 'BITWISE_NOT'), ('left', 'LE', 'EQ', 'NE', 'GE', 'GT', 'LT'), # ('left', 'SHIFT_LEFT', 'SHIFT_RIGHT'), ('left', 'ADDITION', 'SUBTRACTION'), ('left', 'MULTIPLICATION', 'DIVISION'), ('left', 'SHIFT_LEFT', 'SHIFT_RIGHT'), ('left', 'POWER'), ('left', 'MODULO'), ('left', 'UMINUS'), ('left', 'RP', 'LP'), ) def new_temp(self): self.t_counter += 1 return "TT" + str(self.t_counter) def new_label(self): self.l_counter += 1 return "L" + str(self.l_counter) def backpatch(self, in_list, m): # print("backpatch") # print(in_list) # print(m) for index in in_list: # print("in for") # print(index) # print(m) code = self.code_list[index] # print(code) new_code = code.replace("_", str(m)) # print(code) self.code_list[index] = new_code def get_start(self, s): s_list = s.split(":") return s_list[0] def get_num_of_last_label(self, s): s_list = s.split(";") s_list = s_list[-2].split(':') num = int(s_list[0].replace("L", "")) return num def produce_output(self): file = open("final_result.c", "w") s = "#include <stdio.h>" + "\n" s += "int main(){" + "\n" # if self.t_counter > -1 : # s += "double " # for i in range(0, self.t_counter+1): s += "\n".join(self.code_list) s += "\n" + "}" file.write(s) file.close() def build(self, **kwargs): """build the parser""" self.parser = yacc.yacc(module=self, **kwargs) return self.parser