当前位置:文档之家› 计算机编译原理实验报告

计算机编译原理实验报告

编译原理实验报告实验一词法分析设计一、实验功能:1、对输入的IXt文件内的内容进行词法分析:2、由文件流输入IesiJxi中的内容,对文件中的各类字符进行词法分析3、打印出分析后的结果;二、程序结构描述:(源代码见附录)1、分别利用k[],siu,s2[],s3[]构造关键字表,分界符表,算术运算符表和关系运算符表。

2、bool isletter(){}用来判断其是否为字母,是则返回IrUe,否则返回false;bool isdigit(){)用来判断其是否为数字,是则返回IrUe,否则返回false;bool iscalcu(){)用来判断是否为算术运算符,是则返回IrUe,否则返回false;bool reserve(string a∣∣){)用来判断某字符是否在上述四个表中,是则返向InIe,否则返回false;void concat(){)用来连接字符串;void getn(){)用来读取字符;void getb(){)用来对空格进行处理;void retract(){}某些必要的退格处理;int analysis(){}对一个单词的单词种别进行具体判断;在主函数中用switch决定输出。

3| file.txt -记事本文件(F)编辑⑹格式(O)查看(V) W(H)if i = O then i ++; a <= 3b%); 富F:\cpp\词法分析器.exeProcess exited after 2.503 seconds with return信按任意键继续∙.∙四、实验总结词法分析器一眼看上去很复杂,但深入的去做就会发现并没有一开始想象的那么困难。

对于一个字符的种别和类型可以用b∞l 函数来判断,对于关键字和标示符的识别(尤其是 3b)则费了一番功夫,最后对于常数的小数点问题处理更是麻烦。

另外,这个实验要设定好 时候退格,否则将会导致字符漏读甚至造成字符重复读取。

我认为,这个实验在程序实现上大体不算困难,但在细节的处理上则需要好好地下功夫 去想,否则最后的程序很可能会出现看上去没有问题,但实际上漏洞百出的状况。

将学过的知识应用到实际中并不简单,只有自己不断尝试将知识转化成程序才能避免眼 高手低,对于知识的理解也必将更加深刻。

单词*******分析结果如下美 二元序列 类型then+ +3b<l,if > <6,i> <4,=> 〈5.0) <l,then> <6,i> <3,++> <6,a> <4,<=> Error Error <2,>> <2,;>关标天常关OW ⅛:天ErEr 八芬键识系匿识术识系rorr 字符运字符运符运r O B-Tnvp1%E,E--? 符符算算位置<1,1> <1,2> <1,3〉 <1,4〉 <1,5> <1,6〉 <1,7〉 <2,1> <2,2〉《2,3》<2,4) <2,5〉 value 0实验二LL(I)分析法一、实验原理:1、写出LL(I)分析法的思想:当一个文法满足LL(I)条件时,我们就可以为它构造一个不带回溯的自上而下的分析程序,这个分析程序是有一组递归过程组成的,每个过程对应文法的一个非终结符。

实现LL(I)分析的一种有效的方法是使用一张分析表和一个站进行联合控制。

预测分析表是一个M[A,a]形式的矩阵,存储着分析规则;栈STACK用于存放文法符号。

从栈顶取符号,按照分析表给出的规则进行有步骤的分析。

2.实验要求实现的文法:(1)E->TG(2)G->+TG∣-TG(3)G->ε(4)T->FS(5)S->*FS∣∕FS(6)S->ε(7)F->(E)(8)F->i二、程序结构:SlringM⑸⑻用来定义分析表:CharinPUl[50]用来存放输入的句子;vector<char> analysis用来存放分析栈;bool flag = true用来判断是否成功的标志;reference(char a,char i){)查询分析表,其中a为分析栈顶符号,i为输入串符号;pro(char a,char in){)用以做出具体的分析;LL(I)依测分析程序流程三、实验结果:运行程序,输入需要分析的语句,结果如下:四、实验总结:本次试验用代码实现了LL(I)文法,在过程中对于非终结符向终结符转换的过程中出现了一些问题,之后通过向同学请教得已解决。

本代码中的分析表写在了主函数中,可以说本程序只对这一个文法有效,这也是这个程序的局限性。

实验三LR(I)分析法一、实验原理LR (1)分析法实验设计思想及算法(1)总控程序,也可以称为驱动程序。

对所有的LR分析器总控程序都是相同的。

(2)分析表或分析函数,不同的文法分析表将不同,同一个文法采用的LR分析器不同时,分析表将不同,分析表又可以分为动作表(ACTlON)和状态转换(GoTo) 表两个部分,它们都可用二维数组表示。

(3)分析栈,包括文法符号栈和相应的状态栈,它们均是先进后出栈。

分析器的动作就是由栈顶状态和当前输入符号所决定。

二、程序结构action[12][6]定义动作表;go[12][3]定义转换表:input[50]存放输入串;referaction(int s,char i){)查询action表,a为分析栈顶的状态,i为输入串的符号;refergo(int s,char i){}查询go 表;reduce(int n){ J 就近规约:analysis(int st,char in)( J 具体分析:LR分析器结构:♦其中:SP为栈指针,S[i]为状态栈,X[i]为文法符号栈。

状态转换表用GOTO[i, X]=j表示,规定当栈顶状态为i,遇到当前文法符号为X时应转向状态j, X为终结符或非终结符。

♦ ACTION[i, a]规定了栈顶状态为i时遇到输入符号a应执行。

动作有四种可能:(1)移进:action[i, a]= Sj:状态j移入到状态栈,把a移入到文法符号栈,其中i,j表示状态号。

(2)归约:action[i, a]=rk:当在栈顶形成句柄时,则归约为相应的非终结符A,即文法中有A- B 的产生式,若B 的长度为R(即IBI=R),则从状态栈和文法符号栈中自顶向下去掉R 个符号,即栈指针SP 减去R,并把A 移入文法符号栈内, j=GOTO[i,A]移进状态栈,其中i 为修改指针后的栈顶状态。

(3)接受 acc:当归约到文法符号栈中只剩文法的开始符号S 时,并且输入符号串已结束即 当前输入符是'#',则为分析成功。

(4)报错:当遇到状态栈顶为某一状态下出现不该遇到的文法符号时,则报错,说明输 入端不是该文法能接受的符号串。

用IP 指向W#的第一个得号a 是ip 所搐向的桁号分别从桂BW 出W 个 符号,令s'是当前桂Bi 状轰 JRa 和先讯T 入桂中.S 出产 生或A>0.出幡处”三、实验结果:输入需要规约的字符串,结果如下:“的心止Ss'圮Nfs'分别■人 箝号枝和状态枝: 使桢蔺济TrF 一个Process exited after 8.325 seconds with return ualue 0 请按任意键继续...四、实验总结1、与算符优先分析方法比较,用LR 分析时,设计特定出错处理子程序比较容易,因为不 会发生不正确的归约。

在分析表的每一个空项内,可以填入一个指示器,指向特定的出错处 理子程序,第一类错误的处理一般采用插入、删除或修改的办法,但要注意,不能从栈内移 去任何那种状态,它代表已成功地分析了程序中的某一部分。

2、LR 分析法的归约过程是规范推导的逆过程,所以LR 分析过程是一种规范归约过程。

LR 分析法正是给出一种能根据当前分析栈中的符号串(通常以状态表示)和向右顺序查看输入 串的K 个(KeO)符号就可唯一地确定分析器的动作是移进还是归约和用哪个产生式归约, 因而也就能唯一地确定句柄。

其中LR(O)分析器是在分析过程中不需向右查看输入符号,因 而它对文法的限制较大,然而,它是构造其它LR 类分析器的基础。

因此,首先应学好LR(O) 项目集规范族构造的基本原理和方法。

当K=I 时,已能满足当前绝大多数高级语言编译程 序实现的需要。

SLR(I)分析是为学习LR(I)分析做准备,LR(I)项目集族的构造是LALR(I) 分析器的构造原理和基础。

LALR(I)分析器是当前大多数高级程序设计语言编译程序所采 用的语法分析技术,也是编译程序语法分析器自动构造工具YACC 的实现基本原理。

由此, LR(0)、SLR(1 )> LALR(I). LR(I)四种分析器的构造方法都必须深入理解和掌握。

3、经过以上三个实验的锤炼,不得不说自己编译原理这门课的认识又提高了一个阶层,对 编译原理的知识运用更加深入,编写过程中遇到不少的问题,结合课本及强大的网络资源, 在完成的过程中得到很多收获,不仅来自于对知识点的了解更加深入,更是对自己编程能力 的一次很好的锻炼,希望有更多这样实验的机会。

4、本人很希望在完成实验后,老师可以根据自己讲的课本,将自己所写的程序花一段时间 来讲解,我想这样会对不会编写的是一种教学,对会了的同学是一种榜样效应,可以让我们 有个目标追求,这样我们收获了的也会更加准确与丰富。

辄i 入哈句,L)述箔束:i+i*it ∣ 符号栈0 05 n Hi 03 #F 02 #T 01 ItE 016 #E+ 0165 ttE*i 0163 «E*F 0169 #E+T 01697 ttE*T* 016975 ttE*T*i 0169710 ttE+T*F 0169 #E*T 01 ttE剩余输入串i÷i*itt +i∙∙itt +i*i# +i*i» ÷i*itt i*i# *itt *itt*itt itt tt tt It tt力5 642656475 ⅛s PrrSSrrSSr6r3rlACM 约约约归卷 5Λ归归归6Λ5Λ归归7Λ5Λ归*F 蒜>i>F>τ态态X>F态态>ix>E 丽 P-T-』奈F-T-菜F-T-E-汤¾ F:\cpp\LR(l).exeG0T0<6,F>=3 GOTO<6,T>=9GOTO<7,F>=10 ,GOTO<6,T>=9 ,G OTO<0,E>-1GOTO<0,F>-3 GOTO<0,T>=2 GOTO<0,E>=1附录:实验一源代码:#include <iostream>#include <string>#include <fstream>using namespace std;string k∣] = {“do",“end","for","if n,"fTscanfTthen∖”While”};//关键字string sl[]= ")",T,T};〃分界符string s2∣]= “*”「7",”++”,”」};〃算术运算符string s3[]= {y丁J!=");〃关系运算符string id[IOO];string ci[100];ifstream in;char ch;int row =l,col = 0;〃行数与列数int idcount = 0,cicount = 0;string strtoken;bool isletter(){∕/用来判断其是否为字母if(ch >= 'A, && ch <= 'z,)return true;elsereturn false;)bool isdigil(){∕/用来判断其是否为数字if(ch >= '0' && ch <= '9')return true;elsereturn false;)bo。

相关主题