class SemantickiAnalizator: """INIT""" def __init__(self, lines): # Turn padding into preceding number lines = [ str(calculate_padding(line)) + ' ' + line.strip() for line in lines ] self.table = Table() self.lines = Lines(lines) self.terminate = False self.result = "" return """CHECK EXPRESSIONS""" def check_expressions(self, expressions): if self.terminate: return False else: return self.lines.check_expressions(expressions) """ASSERT LEAF""" def assert_leaf(self, fst_exp, snd_exp = ""): global counter counter += 1 if self.terminate: return False else: return self.lines.assert_leaf(fst_exp, snd_exp) """PARSE ERROR""" def parse_error(self, curr_line): self.terminate = True return self.lines.parse_error(curr_line) """CHECK BOTH FOR INT AND RETURN INT""" def check_both_for_int_and_return_int(self, curr_line, fst_fun, expr, snd_fun): if not fst_fun() == Expr("INT"): return self.parse_error(curr_line) self.assert_leaf(expr) if not snd_fun() == Expr("INT"): return self.parse_error(curr_line) return Expr("INT") """CAN CAST""" def can_cast(self, fst_exp, snd_exp): return fst_exp == snd_exp \ or fst_exp == Expr("INT") and snd_exp == Expr("CHAR") """POST TRAVERSAL CHECKS""" def post_traversal_checks(self): if not self.table.is_declared("main", [Expr("VOID")], [Expr("INT")]) \ or not "main" in self.table._scopes[0]['_functions'] \ or not self.table.get_function("main")._function_to_types[0]._type == "INT": self.result = "main" return True for scope in self.table._scopes: for function in scope['_functions']: if not function in self.table._defined_functions: self.result = "funkcija" return True return False """PARSE""" def parse(self): #pprint("# Starting and checking for <prijevodna_jedinica>") self.check_expressions(["<prijevodna_jedinica>"]) #pprint("Calling self.prijevodna_jedinica()") self.prijevodna_jedinica() self.result = self.lines.result if not self.terminate: if not self.post_traversal_checks(): pprint("Succesful semantic analysis. No errors!") else: pprint("Post traversal errors found!") return(self.result) ###################################### ############### IZRAZI ############### ###################################### """PRIMARNI IZRAZ""" def primarni_izraz(self): curr_line = self.lines._iter pprint("# primarni_izraz") pprint(self.lines.get_line()) if self.check_expressions(["IDN"]): idn = self.assert_leaf("IDN") if self.table.contains(idn): return self.table.get_var(idn) elif self.table.is_JUST_declared(idn): return self.table.get_function(idn) else: return self.parse_error(curr_line) elif self.check_expressions(["BROJ"]): expr = self.assert_leaf("BROJ") if int(expr) < -2**31 or int(expr) >= 2**31: return self.parse_error(curr_line) return Expr("INT") elif self.check_expressions(["ZNAK"]): expr = self.assert_leaf("ZNAK") if not len(expr) == 3 or ord(expr[1]) < 0 or ord(expr[1]) > 255: return self.parse_error(curr_line) return Expr("CHAR") elif self.check_expressions(["NIZ_ZNAKOVA"]): expr = self.assert_leaf("NIZ_ZNAKOVA") if not is_valid_char_array(expr): return self.parse_error(curr_line) return Expr("CHAR", is_array = True) elif self.check_expressions(["L_ZAGRADA", "<izraz>", "D_ZAGRADA"]): self.assert_leaf("L_ZAGRADA") expr = self.izraz() self.assert_leaf("D_ZAGRADA") return expr else: return self.parse_error(curr_line) """POSTFIX IZRAZ""" def postfiks_izraz(self): curr_line = self.lines._iter pprint("# postfiks_izraz") pprint(self.lines.get_line()) if self.check_expressions(["<postfiks_izraz>", "L_UGL_ZAGRADA", "<izraz>", "D_UGL_ZAGRADA"]): expr = self.postfiks_izraz() _expr = Expr(expr) if not _expr.is_array: return self.parse_error(curr_line) ## We are accessing an element of this array so the return type is not array _expr.is_array = False self.assert_leaf("L_UGL_ZAGRADA") if not self.izraz() == Expr("INT"): return self.parse_error(curr_line) self.assert_leaf("D_UGL_ZAGRADA") if _expr.is_const: return _expr else: return _expr.set_to_lexpr() elif self.check_expressions(["<postfiks_izraz>", "L_ZAGRADA", "D_ZAGRADA"]): expr = self.postfiks_izraz() self.assert_leaf("L_ZAGRADA") self.assert_leaf("D_ZAGRADA") if not expr.is_function or not expr.is_function_from([Expr("VOID")]): return self.parse_error(curr_line) ret = expr.get_return_type() if len(ret) != 1: raise Exception("This should not happen") else: return ret[0] elif self.check_expressions(["<postfiks_izraz>", "L_ZAGRADA", "<lista_argumenata>", "D_ZAGRADA"]): expr = self.postfiks_izraz() self.assert_leaf("L_ZAGRADA") expr2 = self.lista_argumenata() self.assert_leaf("D_ZAGRADA") if not expr.is_function or not expr.is_function_from(expr2): return self.parse_error(curr_line) ret = expr.get_return_type() if len(ret) != 1: raise Exception("This should not happen") else: return ret[0] elif self.check_expressions(["<postfiks_izraz>", "OP_INC"]): expr = self.postfiks_izraz() self.assert_leaf("OP_INC") if not expr.is_lexpr or not expr == Expr("INT"): return self.parse_error(curr_line) else: return Expr("INT") elif self.check_expressions(["<postfiks_izraz>", "OP_DEC"]): expr = self.postfiks_izraz() self.assert_leaf("OP_DEC") if not expr.is_lexpr or not expr == Expr("INT"): return self.parse_error(curr_line) else: return Expr("INT") elif self.check_expressions(["<primarni_izraz>"]): return self.primarni_izraz() else: return self.parse_error(curr_line) """LISTA ARGUMENATA""" def lista_argumenata(self): curr_line = self.lines._iter pprint("# lista_argumenata") pprint(self.lines.get_line()) if self.check_expressions(["<izraz_pridruzivanja>"]): expr = self.izraz_pridruzivanja() return [expr] elif self.check_expressions(["<lista_argumenata>", "ZAREZ", "<izraz_pridruzivanja>"]): expr = self.lista_argumenata() self.assert_leaf("ZAREZ") expr2 = self.izraz_pridruzivanja() return expr + [expr2] else: return self.parse_error(curr_line) """UNARNI IZRAZ""" def unarni_izraz(self): curr_line = self.lines._iter pprint("# unarni_izraz") pprint(self.lines.get_line()) if self.check_expressions(["<postfiks_izraz>"]): return self.postfiks_izraz() elif self.check_expressions(["OP_DEC", "<unarni_izraz>"]): self.assert_leaf("OP_DEC") expr = self.unarni_izraz() if not expr.is_lexpr or not expr == Expr("INT"): return self.parse_error(curr_line) else: return Expr("INT") elif self.check_expressions(["OP_INC", "<unarni_izraz>"]): self.assert_leaf("OP_INC") expr = self.unarni_izraz() if not expr.is_lexpr or not expr == Expr("INT"): return self.parse_error(curr_line) else: return Expr("INT") elif self.check_expressions(["<unarni_operator>", "<cast_izraz>"]): self.unarni_operator() expr = self.cast_izraz() if not expr == Expr("INT"): return self.parse_error(curr_line) else: return Expr("INT") else: return self.parse_error(curr_line) """UNARNI OPERATOR""" def unarni_operator(self): curr_line = self.lines._iter pprint("# unarni_operator") pprint(self.lines.get_line()) if self.check_expressions(["PLUS"]): self.assert_leaf("PLUS") return elif self.check_expressions(["MINUS"]): self.assert_leaf("MINUS") return elif self.check_expressions(["OP_TILDA"]): self.assert_leaf("OP_TILDA") return elif self.check_expressions(["OP_NEG"]): self.assert_leaf("OP_NEG") return else: return self.parse_error(curr_line) """CAST IZRAZ""" def cast_izraz(self): curr_line = self.lines._iter pprint("# cast_izraz") pprint(self.lines.get_line()) if self.check_expressions(["<unarni_izraz>"]): return self.unarni_izraz() elif self.check_expressions(["L_ZAGRADA", "<ime_tipa>", "D_ZAGRADA", "<cast_izraz>"]): self.assert_leaf("L_ZAGRADA") expr = self.ime_tipa() self.assert_leaf("D_ZAGRADA") expr2 = self.cast_izraz() if not self.can_cast(expr, expr2): return self.parse_error(curr_line) else: return expr """IME TIPA""" def ime_tipa(self): curr_line = self.lines._iter pprint("# ime_tipa") pprint(self.lines.get_line()) if self.check_expressions(["<specifikator_tipa>"]): return self.specifikator_tipa() elif self.check_expressions(["KR_CONST", "<specifikator_tipa>"]): self.assert_leaf("KR_CONST") expr = self.specifikator_tipa() if expr == Expr("VOID"): return self.parse_error(curr_line) else: return expr.set_to_const() else: return self.parse_error(curr_line) """SPECIFIKATOR TIPA""" def specifikator_tipa(self): curr_line = self.lines._iter pprint("# specifikator_tipa") pprint(self.lines.get_line()) if self.check_expressions(["KR_VOID"]): self.assert_leaf("KR_VOID", "void") return Expr("VOID") elif self.check_expressions(["KR_CHAR"]): self.assert_leaf("KR_CHAR", "char") return Expr("CHAR") elif self.check_expressions(["KR_INT"]): self.assert_leaf("KR_INT", "int") return Expr("INT") else: return self.parse_error(curr_line) """MULTIPLIKATIVNI IZRAZ""" def multiplikativni_izraz(self): curr_line = self.lines._iter pprint("# multiplikativni_izraz") pprint(self.lines.get_line()) if self.check_expressions(["<cast_izraz>"]): return self.cast_izraz() elif self.check_expressions(["<multiplikativni_izraz>", "OP_PUTA", "<cast_izraz>"]): return self.check_both_for_int_and_return_int(curr_line, self.multiplikativni_izraz, "OP_PUTA", self.cast_izraz) elif self.check_expressions(["<multiplikativni_izraz>", "OP_DIJELI", "<cast_izraz>"]): return self.check_both_for_int_and_return_int(curr_line, self.multiplikativni_izraz, "OP_DIJELI", self.cast_izraz) elif self.check_expressions(["<multiplikativni_izraz>", "OP_MOD", "<cast_izraz>"]): return self.check_both_for_int_and_return_int(curr_line, self.multiplikativni_izraz, "OP_MOD", self.cast_izraz) else: return self.parse_error(curr_line) """ADITIVNI IZRAZ""" def aditivni_izraz(self): curr_line = self.lines._iter pprint("# aditivni_izraz") pprint(self.lines.get_line()) if self.check_expressions(["<multiplikativni_izraz>"]): return self.multiplikativni_izraz() elif self.check_expressions(["<aditivni_izraz>", "PLUS", "<multiplikativni_izraz>"]): return self.check_both_for_int_and_return_int(curr_line, self.aditivni_izraz, "PLUS", self.multiplikativni_izraz) elif self.check_expressions(["<aditivni_izraz>", "MINUS", "<multiplikativni_izraz>"]): return self.check_both_for_int_and_return_int(curr_line, self.aditivni_izraz, "MINUS", self.multiplikativni_izraz) else: return self.parse_error(curr_line) """ODNOSNI IZRAZ""" def odnosni_izraz(self): curr_line = self.lines._iter pprint("# odnosni_izraz") pprint(self.lines.get_line()) if self.check_expressions(["<aditivni_izraz>"]): return self.aditivni_izraz() elif self.check_expressions(["<odnosni_izraz>", "OP_LT", "<aditivni_izraz>"]): return self.check_both_for_int_and_return_int(curr_line, self.odnosni_izraz, "OP_LT" , self.aditivni_izraz) elif self.check_expressions(["<odnosni_izraz>", "OP_GT", "<aditivni_izraz>"]): return self.check_both_for_int_and_return_int(curr_line, self.odnosni_izraz, "OP_GT" , self.aditivni_izraz) elif self.check_expressions(["<odnosni_izraz>", "OP_LTE", "<aditivni_izraz>"]): return self.check_both_for_int_and_return_int(curr_line, self.odnosni_izraz, "OP_LTE" , self.aditivni_izraz) elif self.check_expressions(["<odnosni_izraz>", "OP_GTE", "<aditivni_izraz>"]): return self.check_both_for_int_and_return_int(curr_line, self.odnosni_izraz, "OP_GTE" , self.aditivni_izraz) else: return self.parse_error(curr_line) """JEDNAKOSNI IZRAZ""" def jednakosni_izraz(self): curr_line = self.lines._iter pprint("# jednakosni_izraz") pprint(self.lines.get_line()) if self.check_expressions(["<odnosni_izraz>"]): return self.odnosni_izraz() elif self.check_expressions(["<jednakosni_izraz>", "OP_EQ", "<odnosni_izraz>"]): return self.check_both_for_int_and_return_int(curr_line, self.jednakosni_izraz, "OP_EQ", self.odnosni_izraz) elif self.check_expressions(["<jednakosni_izraz>", "OP_NEQ", "<odnosni_izraz>"]): return self.check_both_for_int_and_return_int(curr_line, self.jednakosni_izraz, "OP_NEQ", self.odnosni_izraz) else: return self.parse_error(curr_line) """BIN I IZRAZ""" def bin_i_izraz(self): curr_line = self.lines._iter pprint("# bin_i_izraz") pprint(self.lines.get_line()) if self.check_expressions(["<jednakosni_izraz>"]): return self.jednakosni_izraz() elif self.check_expressions(["<bin_i_izraz>", "OP_BIN_I", "<jednakosni_izraz>"]): return self.check_both_for_int_and_return_int(curr_line, self.bin_i_izraz, "OP_BIN_I", self.jednakosni_izraz) else: return self.parse_error(curr_line) """BIN XILI IZRAZ""" def bin_xili_izraz(self): curr_line = self.lines._iter pprint("# bin_xili_izraz") pprint(self.lines.get_line()) if self.check_expressions(["<bin_i_izraz>"]): return self.bin_i_izraz() elif self.check_expressions(["<bin_xili_izraz>", "OP_BIN_XILI", "<bin_i_izraz>"]): return self.check_both_for_int_and_return_int(curr_line, self.bin_xili_izraz, "OP_BIN_XILI", self.bin_i_izraz) else: return self.parse_error(curr_line) """BIN ILI IZRAZ""" def bin_ili_izraz(self): curr_line = self.lines._iter pprint("# bin_ili_izraz") pprint(self.lines.get_line()) if self.check_expressions(["<bin_xili_izraz>"]): return self.bin_xili_izraz() elif self.check_expressions(["<bin_ili_izraz>", "OP_BIN_ILI", "<bin_xili_izraz>"]): return self.check_both_for_int_and_return_int(curr_line, self.bin_ili_izraz, "OP_BIN_ILI", self.bin_xili_izraz) else: return self.parse_error(curr_line) """LOG I IZRAZ""" def log_i_izraz(self): curr_line = self.lines._iter pprint("# log_i_izraz") pprint(self.lines.get_line()) if self.check_expressions(["<bin_ili_izraz>"]): return self.bin_ili_izraz() elif self.check_expressions(["<log_i_izraz>", "OP_I", "<bin_ili_izraz>"]): return self.check_both_for_int_and_return_int(curr_line, self.log_i_izraz, "OP_I", self.bin_ili_izraz) else: return self.parse_error(curr_line) """LOG ILI IZRAZ""" def log_ili_izraz(self): curr_line = self.lines._iter pprint("# log_ili_izraz") pprint(self.lines.get_line()) if self.check_expressions(["<log_i_izraz>"]): return self.log_i_izraz() elif self.check_expressions(["<log_ili_izraz>", "OP_ILI", "<log_i_izraz>"]): return self.check_both_for_int_and_return_int(curr_line, self.log_ili_izraz, "OP_ILI", self.log_i_izraz) else: return self.parse_error(curr_line) """IZRAZ PRIDRUZIVANJA""" def izraz_pridruzivanja(self): curr_line = self.lines._iter pprint("# izraz_pridruzivanja") pprint(self.lines.get_line()) if self.check_expressions(["<log_ili_izraz>"]): return self.log_ili_izraz() elif self.check_expressions(["<postfiks_izraz>", "OP_PRIDRUZI", "<izraz_pridruzivanja>"]): expr = self.postfiks_izraz() if not expr.is_lexpr: return self.parse_error(curr_line) self.assert_leaf("OP_PRIDRUZI") expr2 = self.izraz_pridruzivanja() if not expr == expr2: return self.parse_error(curr_line) return expr else: return self.parse_error(curr_line) """IZRAZ""" def izraz(self): curr_line = self.lines._iter pprint("# izraz") pprint(self.lines.get_line()) if self.check_expressions(["<izraz_pridruzivanja>"]): return self.izraz_pridruzivanja() elif self.check_expressions(["<izraz>", "ZAREZ", "<izraz_pridruzivanja>"]): self.izraz() self.assert_leaf("ZAREZ") return self.izraz_pridruzivanja() ################################## ## NAREDBENA STRUKTURA PROGRAMA ## ################################## """SLOZENA NAREDBA""" def slozena_naredba(self, in_loop = False, in_function = False, function_to = []): curr_line = self.lines._iter pprint("# slozena_naredba") pprint(self.lines.get_line()) if self.check_expressions(["L_VIT_ZAGRADA", "<lista_naredbi>", "D_VIT_ZAGRADA"]): self.assert_leaf("L_VIT_ZAGRADA") self.lista_naredbi(in_loop = in_loop, in_function = in_function, function_to = function_to) self.assert_leaf("D_VIT_ZAGRADA") elif self.check_expressions(["L_VIT_ZAGRADA", "<lista_deklaracija>", "<lista_naredbi>" , "D_VIT_ZAGRADA"]): self.table.create_new_scope() #### SCOPING!!!!!!!! self.assert_leaf("L_VIT_ZAGRADA") self.lista_deklaracija() self.lista_naredbi(in_loop = in_loop, in_function = in_function, function_to = function_to) self.assert_leaf("D_VIT_ZAGRADA") self.table.destroy_current_scope() #### SCOPING!!!!!!!! else: return self.parse_error(curr_line) """LISTA NAREDBI""" def lista_naredbi(self, in_loop = False, in_function = False, function_to = []): curr_line = self.lines._iter pprint("# lista_naredbi") pprint(self.lines.get_line()) if self.check_expressions(["<naredba>"]): self.naredba(in_loop = in_loop, in_function = in_function, function_to = function_to) elif self.check_expressions(["<lista_naredbi>", "<naredba>"]): self.lista_naredbi(in_loop = in_loop, in_function = in_function, function_to = function_to) self.naredba(in_loop = in_loop, in_function = in_function, function_to = function_to) else: return self.parse_error(curr_line) """NAREDBA""" def naredba(self, in_loop = False, in_function = False, function_to = []): curr_line = self.lines._iter pprint("# naredba") pprint(self.lines.get_line()) if self.check_expressions(["<slozena_naredba>"]): self.slozena_naredba(in_loop = in_loop, in_function = in_function, function_to = function_to) elif self.check_expressions(["<izraz_naredba>"]): self.izraz_naredba() elif self.check_expressions(["<naredba_grananja>"]): self.naredba_grananja(in_loop = in_loop, in_function = in_function, function_to = function_to) elif self.check_expressions(["<naredba_petlje>"]): self.naredba_petlje(in_loop = in_loop, in_function = in_function, function_to = function_to) elif self.check_expressions(["<naredba_skoka>"]): self.naredba_skoka(in_loop = in_loop, in_function = in_function, function_to = function_to) else: return self.parse_error(curr_line) """IZRAZ NAREDBA""" def izraz_naredba(self): curr_line = self.lines._iter pprint("# izraz_naredba") pprint(self.lines.get_line()) if self.check_expressions(["TOCKAZAREZ"]): self.assert_leaf("TOCKAZAREZ") return Expr("INT") elif self.check_expressions(["<izraz>", "TOCKAZAREZ"]): expr = self.izraz() self.assert_leaf("TOCKAZAREZ") return expr else: return self.parse_error(curr_line) """NAREDBA GRANANJA""" def naredba_grananja(self, in_loop = False, in_function = False, function_to = []): curr_line = self.lines._iter pprint("# naredba_grananja") pprint(self.lines.get_line()) if self.check_expressions(["KR_IF", "L_ZAGRADA", "<izraz>", "D_ZAGRADA", "<naredba>"]): self.assert_leaf("KR_IF") self.assert_leaf("L_ZAGRADA") expr = self.izraz() if not expr == Expr("INT"): return self.parse_error(curr_line) self.assert_leaf("D_ZAGRADA") self.naredba(in_loop = in_loop, in_function = in_function, function_to = function_to) elif self.check_expressions(["KR_IF", "L_ZAGRADA", "<izraz>" ,"D_ZAGRADA", "<naredba>", "KR_ELSE", "<naredba>"]): self.assert_leaf("KR_IF") self.assert_leaf("L_ZAGRADA") if not self.izraz() == Expr("INT"): return self.parse_error(curr_line) self.assert_leaf("D_ZAGRADA") self.naredba(in_loop = in_loop, in_function = in_function, function_to = function_to) self.assert_leaf("KR_ELSE") self.naredba(in_loop = in_loop, in_function = in_function, function_to = function_to) else: return self.parse_error(curr_line) """NAREDBA PETLJE""" def naredba_petlje(self, in_loop = False, in_function = False, function_to = []): curr_line = self.lines._iter pprint("# naredba_petlje") pprint(self.lines.get_line()) if self.check_expressions(["KR_WHILE", "L_ZAGRADA", "<izraz>", "D_ZAGRADA", "<naredba>"]): self.assert_leaf("KR_WHILE") self.assert_leaf("L_ZAGRADA") if not self.izraz() == Expr("INT"): return self.parse_error(curr_line) self.assert_leaf("D_ZAGRADA") self.naredba(in_loop = True, in_function = in_function, function_to = function_to) elif self.check_expressions(["KR_FOR", "L_ZAGRADA", "<izraz_naredba>", "<izraz_naredba>" ,"D_ZAGRADA", "<naredba>"]): self.assert_leaf("KR_FOR") self.assert_leaf("L_ZAGRADA") self.izraz_naredba() if not self.izraz_naredba() == Expr("INT"): return self.parse_error(curr_line) self.assert_leaf("D_ZAGRADA") self.naredba(in_loop = True, in_function = in_function, function_to = function_to) elif self.check_expressions(["KR_FOR", "L_ZAGRADA", "<izraz_naredba>", "<izraz_naredba>" ,"<izraz>", "D_ZAGRADA", "<naredba>"]): self.assert_leaf("KR_FOR") self.assert_leaf("L_ZAGRADA") self.izraz_naredba() if not self.izraz_naredba() == Expr("INT"): return self.parse_error(curr_line) self.izraz() self.assert_leaf("D_ZAGRADA") self.naredba(in_loop = True, in_function = in_function, function_to = function_to) else: return self.parse_error(curr_line) """NAREDBA SKOKA""" def naredba_skoka(self, in_loop = False, in_function = False, function_to = []): curr_line = self.lines._iter pprint("# naredba_skoka") pprint(self.lines.get_line()) if self.check_expressions(["KR_CONTINUE", "TOCKAZAREZ"]): if not in_loop: return self.parse_error(curr_line) self.assert_leaf("KR_CONTINUE") self.assert_leaf("TOCKAZAREZ") return if self.check_expressions(["KR_BREAK", "TOCKAZAREZ"]): if not in_loop: return self.parse_error(curr_line) self.assert_leaf("KR_BREAK") self.assert_leaf("TOCKAZAREZ") return elif self.check_expressions(["KR_RETURN", "TOCKAZAREZ"]): if not in_function or not function_to == [Expr("VOID")]: return self.parse_error(curr_line) self.assert_leaf("KR_RETURN") self.assert_leaf("TOCKAZAREZ") elif self.check_expressions(["KR_RETURN", "<izraz>", "TOCKAZAREZ"]): self.assert_leaf("KR_RETURN") expr = self.izraz() print(expr) if not in_function: return self.parse_error(curr_line) if not [expr] == function_to: return self.parse_error(curr_line) self.assert_leaf("TOCKAZAREZ") """PRIJEVODNA JEDINICA""" def prijevodna_jedinica(self): curr_line = self.lines._iter pprint("# prijevodna_jedinica") pprint(self.lines.get_line()) if self.check_expressions(["<vanjska_deklaracija>"]): pprint("<vanjska_deklaracija>") self.vanjska_deklaracija() elif self.check_expressions(["<prijevodna_jedinica>", "<vanjska_deklaracija>"]): pprint("<prijevodna_jedinica> <vanjska_deklaracija>") self.prijevodna_jedinica() self.vanjska_deklaracija() else: return self.parse_error(curr_line) """VANJSKA DEKLARACIJA""" def vanjska_deklaracija(self): curr_line = self.lines._iter pprint("# vanjska_deklaracija") pprint(self.lines.get_line()) if self.check_expressions(["<definicija_funkcije>"]): self.definicija_funkcije() elif self.check_expressions(["<deklaracija>"]): pprint("# vanjska_deklaracija") self.deklaracija() else: return self.parse_error(curr_line) ############################## ## DEKLARACIJE I DEFINICIJE ## ############################## """DEFINICIJA FUNKCIJE""" def definicija_funkcije(self): curr_line = self.lines._iter pprint("# definicija_funkcije") pprint(self.lines.get_line()) if self.check_expressions(["<ime_tipa>", "IDN", "L_ZAGRADA", "KR_VOID", "D_ZAGRADA" , "<slozena_naredba>"]): ## 1 expr = self.ime_tipa() ## 2 if expr.is_const: return self.parse_error(curr_line) idn = self.assert_leaf("IDN") ## 3 if self.table.contains(idn) and self.table.is_defined(idn): return self.parse_error(curr_line) ## 4 if self.table.is_declared(idn, [Expr("VOID")], [expr]): return self.parse_error(curr_line) ## 5 if not self.table.is_declared(idn, [Expr("VOID")], [expr]): self.table.declare_fun(idn, [Expr("VOID")], [expr]) if not self.table.is_defined(idn, [Expr("VOID")], [expr]): self.table.define(idn, [Expr("VOID")], [expr]) ## X self.assert_leaf("L_ZAGRADA") self.assert_leaf("KR_VOID") self.assert_leaf("D_ZAGRADA") ## 6 self.slozena_naredba(in_function = True, function_to = [expr]) elif self.check_expressions(["<ime_tipa>", "IDN", "L_ZAGRADA", "<lista_parametara>", "D_ZAGRADA" , "<slozena_naredba>"]): ## 1 expr = self.ime_tipa() ## 2 if expr.is_const: return self.parse_error(curr_line) idn = self.assert_leaf("IDN") ## X self.assert_leaf("L_ZAGRADA") ## 4 types, names = self.lista_parametara() ## 5 if self.table.is_declared(idn, types, [expr]): return self.parse_error(curr_line) ## 3 if self.table.contains(idn) or self.table.is_defined(idn, types, [expr]): return self.parse_error(curr_line) ## 6 if not self.table.is_declared(idn, types, [expr]): self.table.declare_fun(idn, types, [expr]) if not self.table.is_defined(idn, types, [expr]): self.table.define(idn, types, [expr]) #### SCOPING!!!!!!!! self.table.create_new_scope() #### SCOPING!!!!!!!! ## 4 . continued ### Addomg types+names to scope (no scoping implemented yet) for i, name in enumerate(names): self.table.declare_var(name, types[i]) ## X self.assert_leaf("D_ZAGRADA") ## 7 !!! Careful about function parameters. Should be implemented (i think) pprint("!!!!!!!!!!!!!!!!!!!!!!!!!!!") pprint(expr) self.slozena_naredba(in_function = True, function_to = [expr]) self.table.destroy_current_scope() #### SCOPING!!!!!!!! else: return self.parse_error(curr_line) """LISTA PARAMETARA""" def lista_parametara(self): curr_line = self.lines._iter pprint("# lista_parametara") pprint(self.lines.get_line()) if self.check_expressions(["<deklaracija_parametra>"]): tip, ime = self.deklaracija_parametra() return [tip], [ime] elif self.check_expressions(["<lista_parametara>", "ZAREZ", "<deklaracija_parametra>"]): tipovi, imena = self.lista_parametara() self.assert_leaf("ZAREZ") tip, ime = self.deklaracija_parametra() return tipovi + [tip], imena + [ime] else: return self.parse_error(curr_line) """DEKLARACIJA PARAMETRA""" def deklaracija_parametra(self): curr_line = self.lines._iter pprint("# deklaracija_parametra") pprint(self.lines.get_line()) if self.check_expressions(["<ime_tipa>", "IDN", "L_UGL_ZAGRADA", "D_UGL_ZAGRADA"]): expr = self.ime_tipa() if expr == Expr("VOID"): return self.parse_error(curr_line) idn = self.assert_leaf("IDN") self.assert_leaf("L_UGL_ZAGRADA") self.assert_leaf("D_UGL_ZAGRADA") return expr.set_to_array(), idn elif self.check_expressions(["<ime_tipa>", "IDN"]): expr = self.ime_tipa() if expr == Expr("VOID"): return self.parse_error(curr_line) idn = self.assert_leaf("IDN") return expr, idn else: return self.parse_error(curr_line) """LISTA DEKLARACIJA""" def lista_deklaracija(self): curr_line = self.lines._iter pprint("# lista_deklaracija") pprint(self.lines.get_line()) if self.check_expressions(["<deklaracija>"]): self.deklaracija() elif self.check_expressions(["<lista_deklaracija>", "<deklaracija>"]): self.lista_deklaracija() self.deklaracija() else: return self.parse_error(curr_line) """DEKLRACIJA""" def deklaracija(self): curr_line = self.lines._iter pprint("# deklaracija") pprint(self.lines.get_line()) if self.check_expressions(["<ime_tipa>", "<lista_init_deklaratora>", "TOCKAZAREZ"]): expr = self.ime_tipa() self.lista_init_deklaratora(expr) self.assert_leaf("TOCKAZAREZ") return """LISTA INIT DEKLARATORA""" def lista_init_deklaratora(self, inherited_type): curr_line = self.lines._iter pprint("# lista_init_deklaratora") pprint(self.lines.get_line()) if self.check_expressions(["<init_deklarator>"]): self.init_deklarator(inherited_type) elif self.check_expressions(["<lista_init_deklaratora>", "ZAREZ", "<init_deklarator>"]): self.lista_init_deklaratora(inherited_type) self.assert_leaf("ZAREZ") self.init_deklarator(inherited_type) else: return self.parse_error(curr_line) """INIT DEKLARATOR""" def init_deklarator(self, inherited_type): curr_line = self.lines._iter pprint("# init_deklarator") pprint(self.lines.get_line()) if self.check_expressions(["<izravni_deklarator>"]): tmp = self.izravni_deklarator(inherited_type) if self.terminate: return tmp expr, num = tmp if expr.is_const: return self.parse_error(curr_line) elif self.check_expressions(["<izravni_deklarator>", "OP_PRIDRUZI", "<inicijalizator>"]): tmp = self.izravni_deklarator(inherited_type) if self.terminate: return tmp expr, num = tmp self.assert_leaf("OP_PRIDRUZI") tmp = self.inicijalizator() if self.terminate: return tmp expr2, num2 = tmp if not expr.is_array and not expr2.is_function: if not expr == expr2: return self.parse_error(curr_line) if not expr.is_array and expr2.is_function: if not expr == expr2.get_return_type(): return self.parse_error(curr_line) elif expr.is_array: if not num >= num2: return self.parse_error(curr_line) if type(expr2) is list: _expr = Expr(expr) _expr.is_array = False for e in expr2: if not e == _expr: return self.parse_error(curr_line) else: if not expr2 == expr: return self.parse_error(curr_line) else: return self.parse_error(curr_line) """IZRAVNI DEKLARATOR""" def izravni_deklarator(self, inherited_type): curr_line = self.lines._iter pprint("# izravni_deklarator") pprint(self.lines.get_line()) if self.check_expressions(["IDN"]): idn = self.assert_leaf("IDN") if inherited_type == Expr("VOID"): return self.parse_error(curr_line) if self.table.contains(idn): return self.parse_error(curr_line) self.table.declare_var(idn, inherited_type) ## Returning false to know that it's not a declaration that returns a number as second arg return inherited_type, 1 elif self.check_expressions(["IDN", "L_UGL_ZAGRADA", "BROJ", "D_UGL_ZAGRADA"]): _inherited_type = Expr(inherited_type).set_to_array() idn = self.assert_leaf("IDN") if _inherited_type == Expr("VOID"): return self.parse_error(curr_line) if self.table.contains(idn): return self.parse_error(curr_line) self.assert_leaf("L_UGL_ZAGRADA") num = self.assert_leaf("BROJ") if int(num) < 0 or int(num) > 1024: return self.parse_error(curr_line) self.table.declare_var(idn, _inherited_type) self.assert_leaf("D_UGL_ZAGRADA") return _inherited_type, int(num) elif self.check_expressions(["IDN", "L_ZAGRADA", "KR_VOID", "D_ZAGRADA"]): idn = self.assert_leaf("IDN") self.assert_leaf("L_ZAGRADA") self.assert_leaf("KR_VOID") self.assert_leaf("D_ZAGRADA") if self.table.is_JUST_declared(idn) \ and not self.table.is_declared(idn, [Expr("VOID")], [inherited_type]): return self.parse_error(curr_line) elif not self.table.is_JUST_declared(idn): self.table.declare_fun(idn, [Expr("VOID")], [inherited_type]) else: pass # It means it's already declared and of same type ## Returning false to know that it's not a declaration that returns a number as second arg return Expr("VOID", is_function = True, fun_from = [Expr("VOID")], fun_to = [inherited_type]), 1 elif self.check_expressions(["IDN", "L_ZAGRADA", "<lista_parametara>", "D_ZAGRADA"]): idn = self.assert_leaf("IDN") self.assert_leaf("L_ZAGRADA") params, names = self.lista_parametara() self.assert_leaf("D_ZAGRADA") if self.table.is_JUST_declared(idn) \ and not self.table.is_declared(idn, params, [inherited_type]): return self.parse_error(curr_line) elif not self.table.is_JUST_declared(idn): self.table.declare_fun(idn, params, [inherited_type]) else: pass # It means it's already declared and of same type ## Returning false to know that it's not a declaration that returns a number as second arg return Expr("VOID", is_function = True, fun_from = params, fun_to = [inherited_type]), 1 else: return self.parse_error(curr_line) """INICIJALIZATOR""" def inicijalizator(self): curr_line = self.lines._iter pprint("# inicijalizator") pprint(self.lines.get_line()) if self.check_expressions(["<izraz_pridruzivanja>"]): expr = self.izraz_pridruzivanja() if expr == Expr("CHAR", is_array = True): return Expr("CHAR", is_array = True), expr.array_length else: return expr, 1 elif self.check_expressions(["L_VIT_ZAGRADA", "<lista_izraza_pridruzivanja>", "D_VIT_ZAGRADA"]): self.assert_leaf("L_VIT_ZAGRADA") expr, num = self.lista_izraza_pridruzivanja() self.assert_leaf("D_VIT_ZAGRADA") return expr, num else: return self.parse_error(curr_line) """LISTA IZRAZA PRIDRUZIVANJA""" def lista_izraza_pridruzivanja(self): curr_line = self.lines._iter pprint("# lista_izraza_pridruzivanja") pprint(self.lines.get_line()) if self.check_expressions(["<izraz_pridruzivanja>"]): expr = self.izraz_pridruzivanja() return [expr], 1 elif self.check_expressions(["<lista_izraza_pridruzivanja>", "ZAREZ", "<izraz_pridruzivanja>"]): expr, num = self.lista_izraza_pridruzivanja() self.assert_leaf("ZAREZ") expr2 = self.izraz_pridruzivanja() return (expr + [expr2]), (num + 1) else: return self.parse_error(curr_line)