版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、计算机科学与通信工程学院编译原理实验报告题目: 1.词法分析器2. LL(1)分析器 3. LR(0)分析器班级: 姓名: 学号: 指导老师: 2017年 月 目录一、实验题目1二、实验目的和要求1三、代码实现2四、总结27一、 实验题目1. 词法分析器分析一段程序代码,将代码中的单词符号分解出来,并对其进行检查,输出token表和error表2. LL(1)文法分析器分析给定文法。求出文法的FIRST集,FOLLOW集,并构建分析表,对给定输入串进行分析。3. LR(0)文法分析器分析给定文法。用_CLOSURE方法构造文法的LR(0)项目集规范族,根据状态转换函数GO构造出文法的DFA,并
2、转换为分析表,对给定输入串进行分析。二、 实验目的和要求1. 学会词法分析器的实现思路。2. 学会求解FIRST集, FOLLOW集,构造LL(1)分析表。3. 学会_CLOSURE方法, 状态转换函数GO, 构造LR(0)分析表。三、 代码实现1. 词法分析器program.txt 中存放要分析的文法:E->TRR->+TR|-TR|T->FGG->*FG|/FG|F->(E)|i代码:KEYWORD_LIST = 'while', 'if', 'else', 'switch', 'case
3、'SEPARATOR_LIST = '', ':', ',', '(', ')', '', '', '', ''OPERATOR_LIST1 = '+', '-', '*'OPERATOR_LIST2 = '<=', '<', '=', '=', '>', '>='CATEGOR
4、Y_DICT = # KEYWORD "while": "while": "", "if": "if": "", "else": "else": "", "switch": "switch": "", "case": "case": "", # OPERATOR "+": &qu
5、ot;+": "", "-": "-": "", "*": "*": "", "<=": "relop": "LE", "<": "relop": "LT", ">=": "relop": "GE", ">": "r
6、elop": "GT", "=": "relop": "EQ", "=": "=": "", # SEPARATOR "": "": "", ":": ":": "", ",": ",": "", "(": "(": "
7、", ")": ")": "", "": "": "", "": "": "", "": "": "", "": "": "",CONSTANTTABLE = TOKENTABLE = OPERATORTABLE = KEYWORDTABLE = SEPARATORTABLE = UNDE
8、FINEDTABLE = # READ FILEdef read_file(path, method): temp_str = "" try: file = open(path, method) for line in file: line = line.replace('n', " ") temp_str += line temp_str = str(temp_str) except IOError as e: print(e) exit() finally: file.close() return temp_str.strip() +
9、 " "# GETBEdef getbe(): global token getchar() token = "" return# GETCHARdef getchar(): global character global location while all_stringlocation = " ": location = location + 1 character = all_stringlocation return character# LINK TOKENdef concatenation(): global token
10、global character token = token + character# IS NUMBERdef digit(): if '0' <= character <= '9': return True return False# IS ALPHABETdef letter(): if 'A' <= character <= 'Z' or 'a' <= character <= 'z': return True return False# IS IDENT
11、IFIERdef reserve(): if token in KEYWORD_LIST: return CATEGORY_DICTtoken else: return 0# RETRACTdef retract(): global location global character # location = location - 1 character = "" return# MAIN FUNCTIONdef main(): global token global character global location s = getchar() getbe() if
12、39;a' <= s <= 'z' or 'A' <= s <= 'Z': while letter() or digit(): concatenation() location = location + 1 character = all_stringlocation retract() c = reserve() if c = 0: TOKENTABLE.append(token) print("这是标识符:'", token, "':'", TO
13、KENTABLE.index(token), "'") else: KEYWORDTABLE.append(token) print("这是保留字:", CATEGORY_DICTtoken) elif '0' <= s <= '9': while digit(): concatenation() location = location + 1 character = all_stringlocation retract() CONSTANTTABLE.append(token) print("
14、;这是常数:'", token, "':'", CONSTANTTABLE.index(token), "'") elif s in OPERATOR_LIST1: location = location + 1 OPERATORTABLE.append(s) print("这是单操作符:", CATEGORY_DICTs) elif s in OPERATOR_LIST2: location = location + 1 character = all_stringlocation if c
15、haracter = '=': OPERATORTABLE.append(s + character) print("这是双操作符:", CATEGORY_DICTs + character) else: retract() location = location + 1 OPERATORTABLE.append(s) print("这是单操作符:", CATEGORY_DICTs) elif s in SEPARATOR_LIST: location = location + 1 SEPARATORTABLE.append(s) pri
16、nt("这是分隔符:", CATEGORY_DICTs) else: location += 1 UNDEFINEDTABLE.append(s) print("error:undefined identity :'", s, "'")if _name_ = '_main_': character = "" token = "" all_string = read_file("program.txt", "r") locat
17、ion = 0 while location + 1 < len(all_string): main() print('KEYWORDTABLE:', KEYWORDTABLE) print('TOKENTABLE:', TOKENTABLE) print('CONSTANTTABLE:', CONSTANTTABLE) print('OPERATORTABLE:', OPERATORTABLE) print('SEPARATORTABLE:', SEPARATORTABLE)运行结果:2. LL(1)分析器
18、program.txt 中存放要分析的文法:E->TRR->+TR|-TR|T->FGG->*FG|/FG|F->(E)|i输入串:i+i*i代码:NonTermSet = set() # 非终结符集合TermSet = set() # 终结符集合First = # First集Follow = # Follow集GramaDict = # 处理过的产生式Code = # 读入的产生式AnalysisList = # 分析表StartSym = "" # 开始符号EndSym = '#' # 结束符号为“#“Epsilon =
19、"" # 由于没有epsilon符号用“”代替# 构造First集def getFirst(): global NonTermSet, TermSet, First, Follow, FirstA for X in NonTermSet: FirstX = set() # 初始化非终结符First集为空 for X in TermSet: FirstX = set(X) # 初始化终结符First集为自己 Change = True while Change: # 当First集没有更新则算法结束 Change = False for X in NonTermSet: fo
20、r Y in GramaDictX: k = 0 Continue = True while Continue and k < len(Y): if not FirstYk - set(Epsilon) <= FirstX: # 没有一样的就添加,并且改变标志 if Epsilon not in FirstYk and Yk in NonTermSet and k > 0: # Y1到Yi候选式都有存在 Continue = False else: FirstX |= FirstYk - set(Epsilon) Change = True if Epsilon not in
21、 FirstYk: Continue = False k += 1 if Continue: # X->或者Y1到Yk均有产生式 FirstX |= set(Epsilon) # FirstAY |= set(Epsilon)# 构造Follow集def getFollow(): global NonTermSet, TermSet, First, Follow, StartSym for A in NonTermSet: FollowA = set() FollowStartSym.add(EndSym) # 将结束符号加入Follow开始符号中 Change = True while
22、 Change: # 当Follow集没有更新算法结束 Change = False for X in NonTermSet: for Y in GramaDictX: for i in range(len(Y): if Yi in TermSet: continue Flag = True for j in range(i + 1, len(Y): # continue if not FirstYj - set(Epsilon) <= FollowYi: FollowYi |= FirstYj - set(Epsilon) # 步骤2 FIRST()/ 加入到FOLLOW(B)中。 C
23、hange = True if Epsilon not in FirstYj: Flag = False break if Flag: if not FollowX <= FollowYi: # 步骤3 ->,把FOLLOW(A)加到FOLLOW(B)中 FollowYi |= FollowX Change = True# 构造分析表def getAnalysisList(): for nonX in NonTermSet: AnalysisListnonX = dict() row = AnalysisListnonX flag = True for Y in GramaDict
24、nonX: for term in TermSet: if term in FirstY0 and term in FirstnonX: rowterm = nonX+'->'+Y if Epsilon in FirstnonX and flag: flag = False for tmp in FollownonX: rowtmp = nonX+'->'+Epsilon print('分析表:') for nonX in NonTermSet: print(' ', nonX, AnalysisListnonX)#
25、查询分析表def findAnalysisList(non, ter): try: tmp = AnalysisListnonter X, Y = tmp.split('->') except Exception as e: print('find error ') # MA,a为空,发现语法错误 print(e) pass return Y# 显示格式def display(show_list): for item in show_list: print(' %-25s' % item, end='') print()#
26、LL(1)分析器def analyzer(): head = "Stack", "StackTop", 'NowStr', "InputStr", "Action" # inputStr = 'i+i*i' + EndSym inputStr = input("请输入表达式:") + EndSym print('分析过程:') display(head) stack = location = 0 stack.append(EndSym) stack
27、.append(StartSym) stack_top = stack.pop() while stack_top != EndSym and location < len(inputStr): if stack_top in TermSet and inputStrlocation = stack_top: # x = a != '#', mess = '匹配,弹出栈顶符号' + stack_top + '并读入输入串的下一符号' + inputStrlocation + 1 display(stack, stack_top, input
28、Strlocation, inputStrlocation + 1: len(inputStr), mess) location += 1 stack_top = stack.pop() elif stack_top in NonTermSet and inputStrlocation in TermSet: # x为一非终结符A,则查MA,a result = findAnalysisList(stack_top, inputStrlocation) if result = Epsilon: # MA,a中的产生式为A->,只将A弹出 mess = '弹出栈顶符号' +
29、 stack_top + '因M' + stack_top + ',' + inputStrlocation + '中为' + stack_top mess = mess + '->,故不压栈' else: # MA,a中的产生式右部符号串按逆序逐一压入栈中 mess = '弹出栈顶符号' + stack_top + ',将M' + stack_top + ',' + inputStr location + '中的' + stack_top + '-&g
30、t;' + result + '的' + result mess = mess + '逆序压栈' tmp_list = for char in result: tmp_list.append(char) tmp_list.reverse() stack.extend(tmp_list) display(stack, stack_top, inputStrlocation, inputStrlocation + 1: len(inputStr), mess) stack_top = stack.pop() else: break if stack_top
31、= EndSym and inputStrlocation = EndSym: # x = a = '#' 分析成功,分析器停止工作 display(, '#', '#', '', '匹配,分析成功') print() print('*') print('* Analysis Success *') print('*') else: print('Analysis Error')# 读取文法def readGrammar(): try: file =
32、open('grammar.txt', 'r') for line in file: line = line.replace('n', "") Code.append(line) except IOError as e: print(e) exit() finally: file.close() return Code# 初始化def init(): global NonTermSet, TermSet, First, Follow, StartSym, Code Code = readGrammar() n = int(le
33、n(Code) print('产生式个数:', n) StartSym = Code00 print("开始符号:", StartSym) print('产生式:G', StartSym, ':') for i in range(n): X, Y = Codei.split('->') print(' ', Codei) NonTermSet.add(X) Y = Y.split('|') for Yi in Y: TermSet |= set(Yi) if X not i
34、n GramaDict: GramaDictX = set() GramaDictX |= set(Y) # 生成产生式集 TermSet -= NonTermSet print('非终结符:', NonTermSet) print('终结符:', TermSet) getFirst() getFollow() print("FIRST集:") for k in NonTermSet: print(' FIRST', k, ': ', Firstk) print("FOLLOW集:") fo
35、r k, v in Follow.items(): print(' FOLLOW', k, ': ', v) TermSet -= set(Epsilon) TermSet |= set(EndSym) getAnalysisList() analyzer()init()运行结果:3. LR(0)分析器program.txt 中存放要分析的文法:X->SS->BBB->aBB->b输入串:abab代码:VN = # 非终结符VT = # 终结符NFA = # NFA表DFA = # DFA表grammar = # 读入的文法doted_g
36、rammar = # 加点后的文法VN2Int = # 非终结符映射VT2Int = # 终结符映射action = # action表goto = # goto表DFA_node = # DFA节点表status_stack = # 状态栈symbol_stack = # 符号栈now_state = '' # 栈顶状态input_ch = '' # 栈顶字符input_str = '' # 输入串location = 0 # 输入位置now_step = 0 # 当前步骤# 读取文法def read_grammar(file_name): g
37、lobal grammar with open(file_name, 'r') as file: for line in file: line = line.replace('n', "") grammar.append(line) file.close()# 找到终结符和非终结符def find_term_non(): global grammar n = int(len(grammar) temp_vt = l = 0 for i in range(n): X, Y = grammari.split('->') if
38、 X not in VN: VN.append(X) VN2Int.update(X: l) l += 1 for Yi in Y: temp_vt.append(Yi) m = 0 for i in temp_vt: if i not in VN and i not in VT: VT.append(i) VT2Int.update(i: m) m += 1 VT.append('#') VT2Int.update('#': m)# 在字符串某个位置加点def add_char2str(grammar_i, i): grammar_i = grammar_i0
39、:i + '.' + grammar_ii:len(grammar_i) return grammar_i# 给文法加点def add_dot(): global doted_grammar j = 0 n = 0 for i in grammar: for k in range(len(i) - 2): doted_grammar.append() doted_grammarn.append(add_char2str(i, k + 3) doted_grammarn.append('false') n += 1 j += 1# 显示加点后的文法def prin
40、t_doted_grammar(): print('-加点后的文法-') j = 1 for i in doted_grammar: print('%d.%s' % (j, i0) j += 1# 显示读入文法def print_read_grammar(): print('-读入的文法-') j = 0 for i in grammar: print('(%d)%s' % (j, i) j += 1# 初始化NFAdef init_NFA(): global NFA for row in range(len(doted_gram
41、mar): NFA.append() for col in range(len(doted_grammar): NFArow.append('')# 找到点的位置def find_pos_point(one_grammar): return one_grammar.find('.')# 文法是否以start开头,以'.'开始def is_start(grammar_i, start): if grammar_i0.find(start, 0, 1) + grammar_i0.find('.', 3, 4) = 3: return
42、True else: return False# 查找以start开头,以'.'开始的文法,返回个数def find_node(start, grammar_id): num = 0 for i in doted_grammar: if is_start(i, start): grammar_idnum = doted_grammar.index(i) num += 1 return num# 构造NFAdef make_NFA(): global NFA grammar_id = for i in range(len(doted_grammar): grammar_id.ap
43、pend('') init_NFA() i = 0 for grammar_i in doted_grammar: pos_point = find_pos_point(grammar_i0) # 找到点的位置 if not pos_point + 1 = len(grammar_i0): NFAii + 1 = grammar_i0pos_point + 1 if grammar_i0pos_point + 1 in VN: # 点后面跟着非终结符 j = find_node(grammar_i0pos_point + 1, grammar_id) for k in rang
44、e(j): NFAigrammar_idk = '*' add_more(i, grammar_idk) i += 1# 查找关联def add_more(i, j): global NFA grammar_id = for k in range(len(doted_grammar): grammar_id.append('') pos_point = find_pos_point(doted_grammarj0) if not pos_point + 1 = len(doted_grammarj0): if doted_grammarj0pos_point +
45、 1 in VN: j = find_node(doted_grammarj0pos_point + 1, grammar_id) for k in range(j): NFAigrammar_idk = '*' add_more(i, grammar_idk)# 显示NFAdef print_NFA(): global NFA, doted_grammar print('-NFA邻接矩阵-') print(end=' ') for i in range(len(doted_grammar): print('%4d' % (i +
46、 1), end='') print() for i in range(len(doted_grammar): print('-', end='') print() for i in range(len(doted_grammar): print('%3d|' % (i + 1), end='') for j in range(len(doted_grammar): print('%4s' % NFAij, end='') print() for l in range(len(dot
47、ed_grammar): print('-', end='') print()# 初始化DFAdef init_DFA(): global DFA for row in range(len(doted_grammar): DFA.append() for col in range(len(doted_grammar): DFArow.append('')# 连接def add_state(to, fro): for i in range(len(doted_grammar): if not NFAtoi = '' and not
48、NFAtoi = '*': DFAtoi = NFAtoi if not NFAfroi = '' and not NFAfroi = '*': # from可连接的点 DFAtoi = NFAfroi# 构造DFAdef make_DFA(): global NFA, doted_grammar, DFA_node init_DFA() for i in range(len(doted_grammar): DFA_node.append() for j in range(len(doted_grammar): DFA_nodei.append(
49、'') for i in range(len(doted_grammar): if doted_grammari1 = 'false': k = 0 DFA_nodeik = doted_grammari0 k += 1 doted_grammari1 = 'true' for j in range(len(doted_grammar): if NFAij = '*': # 有弧 DFA_nodeik = doted_grammarj0 k += 1 doted_grammarj1 = 'true' add_state(i, j)# 显示DFAdef print_DFA(): global DFA, doted_g
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论