def reduce_32(*args): X0 = args[0] G = args[2] X = Token(idt="X") X.place = newtemp() gen('-', X0.place, G.place, X.place) return X
def reduce_36(*args): G0 = args[0] R = args[2] G = Token(idt="G") G.place = newtemp() gen('/', G0.place, R.place, G.place) return G
def reduce_40(*args): d = args[0] X = args[2] R = Token(idt="R") d.place = d.name R.place = "{}+{}".format(d.place, X.place) return R
def reduce_33(*args): d0 = args[0] d1 = args[2] X = args[4] d0.place = d0.name d1.place = d1.name X = Token(idt="X") gen('r=', X.place, None, 'rdx') gen('call', None, None, d1.place) gen('=r', 'rax', None, d0.place) return Token(idt="F")
def reduce_15(*args): E = args[0] d = args[1] n = args[3] if int(n.value) <= 0: raise ParseErrData( SEM_ERR, int(n.line), "The size of array must be positive but got {}".format(n.value), Token(idt="F")) for i in range(int(n.value)): gen('new', E.value, None, "{}+{}".format(d.place, i)) gen('=', '0', None, "{}+{}".format(d.place, i)) return Token(idt="F")
def reduce_17(*args): d = args[0] X0 = args[2] X1 = args[5] d.place = d.name gen('=', X1.place, None, "{}+{}".format(d.place, X0.place)) return Token(idt="F")
def reduce_16(*args): E = args[0] d = args[1] X = args[3] F = Token(idt="F") gen('newa', E.value, X.place, d.place) return F
def reduce_13(*args): E = args[0] d = args[1] d.place = d.name gen('new', E.value, None, d.place) gen('=', '0', None, d.place) return Token(idt="F")
def reduce_26(*args): O = args[2] M = args[4] L = args[5] I = Token(idt="I") backpatch(O.truelist, M.gotostm) I.nextlist += O.falselist + L.nextlist return I
def reduce_29(*args): X0 = args[0] S = args[1] X1 = args[2] O = Token(idt="O") js_command = gen(S.value, X0.place, X1.place, None) j_command = gen('j', None, None, None) O.truelist.append(js_command) O.falselist.append(j_command) return O
def reduce_13(*args): E = args[0] d = args[1] n0 = args[3] n1 = args[7] N = args[8] d.place = d.name for i in range(int(n0.value)): gen('new', E.value, None, "{}+{}".format(d.place, i)) gen('=', '0', None, "{}+{}".format(d.place, i)) gen('=', n1.value, None, "{}+{}".format(d.place, 0)) for index, n in enumerate(N.value): gen('=', n, None, "{}+{}".format(d.place, index+1)) if int(n.value) <= 0: raise ParseErrData(SEM_ERR, int(n.line), "The size of array must be positive but got {}".format(n.value), Token(idt="F")) return Token(idt="F")
def reduce_47(*args): M0 = args[2] O = args[3] M1 = args[5] B = args[6] backpatch(B.nextlist, M0.gotostm) backpatch(O.truelist, M1.gotostm) A = Token(idt="A") A.nextlist += O.falselist gen('j', None, None, M0.gotostm) return A
def reduce_24(*args): O = args[2] M0 = args[4] B0 = args[5] H = args[6] M1 = args[8] B1 = args[9] I = Token(idt="I") backpatch(O.truelist, M0.gotostm) backpatch(O.falselist, M1.gotostm) I.nextlist += (B0.nextlist + H.nextlist + B1.nextlist) return I
def reduce_25(*args): O = args[2] M = args[4] B0 = args[5] N = args[6] H = args[8] B1 = args[9] I = Token(idt="I") backpatch(O.truelist, M.gotostm) backpatch(O.falselist, H.gotostm) I.nextlist += (B0.nextlist + N.nextlist + B1.nextlist) return I
def reduce_3(*args): return Token(idt="B")
def reduce_2(*args): return Token(idt="P")
def reduce_1(*args): d = args[1] d.place = d.name func_dict[d.name] = d.line return Token(idt="P")
def reduce_0(*args): # 一个非常糟糕临时处理的想法,通过step命令记录的行号来找到函数位置 d = args[1] d.place = d.name func_dict[d.name] = d.line return Token(idt="P")
def reduce_49(*args): X = args[2] gen('write', X.place, None, None) return Token(idt="T")
def reduce_48(*args): X = args[2] gen('read', X.place, None, None) return Token(idt="W")
def reduce_46(*args): S = Token(idt="S") S.value = '<>' return S
def reduce_45(*args): S = Token(idt="S") S.value = '==' return S
def reduce_5(*args): return Token(idt="C")
def reduce_7(*args): X = args[1] gen('ret', X.place, None, None) return Token(idt="L")
def reduce_39(*args): X = args[1] R = Token(idt="R") R.place = X.place return R
def reduce_38(*args): n = args[0] R = Token(idt="R") R.place = newtemp() gen('=', n.value, None, R.place) return R
def reduce_6(*args): return Token(idt="L")
def reduce_44(*args): S = Token(idt="S") S.value = '>=' return S
def parse_tokens(self, tokens, show_syntax=False, file_name=None, draw_graph=False, checkpoints=[]): err_list = [] sem_err_mark = False succeeded = False dot.clear() table = ActionTable(action_table_data) analysis_stack = [] # TODO 赋予结束标志token更有意义的值 analysis_stack.append((0, Token(idt="#"))) i = 0 length = len(tokens) if file_name: fout = open(file_name + ".syn", 'w') outstream = fout else: outstream = sys.stdout line = 1 temp_str = "" while i < length: token = tokens[i] current_line = token.line state = analysis_stack[-1][0] # 加入断点 if int(token.line) in checkpoints: gen('check', None, None, int(current_line)) checkpoints.remove(token.line) if line != token.line: gen('step', None, None, int(current_line)) line = token.line # end try: action = table.action(state, token) except: # TODO 这种处理不妥 mark = "" mark_type = "" if token.idt == 'constnum': mark_type = 'const num' mark = token.value elif token.idt == 'identity': mark_type = 'variable' mark = token.name else: mark_type = 'key word' mark = token.idt parse_err = ParseErrData( SYN_ERR, int(token.line), message="Action failed. Unexpected {}: '{}'.".format( mark_type, mark)) print(parse_err) exit(1) if show_syntax: def show_stack(): print("analysis stack:", end="\t", file=outstream) print(" ".join([ "{}:{}".format(elem[0], elem[1].idt) for elem in analysis_stack ]), file=outstream) show_stack() print("token incoming: {}".format(token.idt), file=outstream) print("action: {}".format(action[0]), file=outstream) print(file=outstream) # input() 单步好像没啥意义 if 's' is action[0]: analysis_stack.append((action[1], action[2])) i += 1 elif 'r' is action[0]: num2reduce = action[1] reduce_action_args = [] new_nodes = [] for _ in range(num2reduce): pop_token = analysis_stack.pop()[1] # reduce_action_args[replace_symbol_reverse(pop_token.idt)] = pop_token reduce_action_args.append(pop_token) new_nodes.append(pop_token) reduce_action_args.reverse() try: token = action[2](*reduce_action_args) except ParseErrData as ped: ped.line = int(current_line) err_list.append(ped) sem_err_mark = True token = ped.token # TODO 一种很简单的处理 try: state = table.goto(analysis_stack[-1][0], token) except Exception: parse_err = ParseErrData( SYN_ERR, int(current_line), message= "Reduction failed. Thers's something wrong with the forms usually." ) print(parse_err) exit(1) analysis_stack.append((state, token)) if draw_graph: dot.node(str(token.count), token.idt) new_nodes.reverse() for child in new_nodes: dot.node(str(child.count), child.idt) dot.edge(str(token.count), str(child.count)) elif '#' in action[0]: if draw_graph: print(file_name) dot.render(file_name) succeeded = True break else: succeeded = False break if sem_err_mark: for err in err_list: print(err) exit(1) if outstream is not sys.stdout: outstream.close() outstream = sys.stdout return succeeded
def reduce_42(*args): S = Token(idt="S") S.value = '<=' return S