编译原理实验报告2

合集下载

编译原理实验报告

编译原理实验报告

编译原理实验报告一、实验目的本次编译原理实验的主要目的是通过实践加深对编译原理中词法分析、语法分析、语义分析和代码生成等关键环节的理解,并提高实际动手能力和问题解决能力。

二、实验环境本次实验使用的编程语言为 C/C++,开发工具为 Visual Studio 2019,操作系统为 Windows 10。

三、实验内容(一)词法分析器的设计与实现词法分析是编译过程的第一个阶段,其任务是从输入的源程序中识别出一个个具有独立意义的单词符号。

在本次实验中,我们使用有限自动机的理论来设计词法分析器。

首先,我们定义了单词的种类,包括关键字、标识符、常量、运算符和分隔符等。

然后,根据这些定义,构建了相应的状态转换图,并将其转换为程序代码。

在实现过程中,我们使用了字符扫描和状态转移的方法,逐步读取输入的字符,判断其所属的单词类型,并将其输出。

(二)语法分析器的设计与实现语法分析是编译过程的核心环节之一,其任务是在词法分析的基础上,根据给定的语法规则,判断输入的单词序列是否构成一个合法的句子。

在本次实验中,我们采用了自顶向下的递归下降分析法来实现语法分析器。

首先,我们根据给定的语法规则,编写了相应的递归函数。

每个函数对应一种语法结构,通过对输入单词的判断和递归调用,来确定语法的正确性。

在实现过程中,我们遇到了一些语法歧义的问题,通过仔细分析语法规则和调整函数的实现逻辑,最终解决了这些问题。

(三)语义分析与中间代码生成语义分析的任务是对语法分析所产生的语法树进行语义检查,并生成中间代码。

在本次实验中,我们使用了四元式作为中间代码的表示形式。

在语义分析过程中,我们检查了变量的定义和使用是否合法,类型是否匹配等问题。

同时,根据语法树的结构,生成相应的四元式中间代码。

(四)代码优化代码优化的目的是提高生成代码的质量和效率。

在本次实验中,我们实现了一些基本的代码优化算法,如常量折叠、公共子表达式消除等。

通过对中间代码进行分析和转换,减少了代码的冗余和计算量,提高了代码的执行效率。

编译原理语法分析实验报告

编译原理语法分析实验报告

编译原理语法分析实验报告第一篇:编译原理语法分析实验报告实验2:语法分析1.实验题目和要求题目:语法分析程序的设计与实现。

实验内容:编写语法分析程序,实现对算术表达式的语法分析。

要求所分析算术表达式由如下的文法产生。

E→E+T|E-T|TT→T*F|T/F|F F→id|(E)|num实验要求:在对输入表达式进行分析的过程中,输出所采用的产生式。

方法1:编写递归调用程序实现自顶向下的分析。

方法2:编写LL(1)语法分析程序,要求如下。

(1)编程实现算法4.2,为给定文法自动构造预测分析表。

(2)编程实现算法4.1,构造LL(1)预测分析程序。

方法3:编写语法分析程序实现自底向上的分析,要求如下。

(1)构造识别所有活前缀的DFA。

(2)构造LR分析表。

(3)编程实现算法4.3,构造LR分析程序。

方法4:利用YACC自动生成语法分析程序,调用LEX自动生成的词法分析程序。

实现(采用方法1)1.1.步骤:1)对文法消除左递归E→TE'E'→+TE'|-TE'|εT→FT'T'→*FT'|/FT'|εF→id|(E)|num2)画出状态转换图化简得:3)源程序在程序中I表示id N表示num1.2.例子:a)例子1 输入:I+(N*N)输出:b)例子2 输入:I-NN 输出:第二篇:编译原理实验报告编译原理实验报告报告完成日期 2018.5.30一.组内分工与贡献介绍二.系统功能概述;我们使用了自动生成系统来完成我们的实验内容。

我们设计的系统在完成了实验基本要求的前提下,进行了一部分的扩展。

增加了声明变量类型、类型赋值判定和声明的变量被引用时作用域的判断。

从而使得我们的实验结果呈现的更加清晰和易懂。

三.分系统报告;一、词法分析子系统词法的正规式:标识符(|)* 十进制整数0 |(1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)* 八进制整数0(1|2|3|4|5|6|7)(0|1|2|3|4|5|6|7)* 十六进制整数0x(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)* 运算符和分隔符 +| * | / | > | < | = |(|)| <=|>=|==;对于标识符和关键字: A5—〉 B5C5 B5—〉a | b |⋯⋯| y | z C5—〉(a | b |⋯⋯| y | z |0|1|2|3|4|5|6|7|8|9)C5|ε综上正规文法为: S—〉I1|I2|I3|A4|A5 I1—〉0|A1 A1—〉B1C1|ε C1—〉E1D1|ε D1—〉E1C1|εE1—〉0|1|2|3|4|5|6|7|8|9 B1—〉1|2|3|4|5|6|7|8|9 I2—〉0A2 A2—〉0|B2 B2—〉C2D2 D2—〉F2E2|ε E2—〉F2D2|εC2—〉1|2|3|4|5|6|7 F2—〉0|1|2|3|4|5|6|7 I3—〉0xA3 A3—〉B3C3 B3—〉0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f C3—〉(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)|C3|εA4—〉+ |-| * | / | > | < | = |(|)| <=|>=|==; A5—〉 B5C5 B5—〉a | b |⋯⋯| y | z C5—〉(a | b |⋯⋯| y | z |0|1|2|3|4|5|6|7|8|9)C5|ε状态图流程图:词法分析程序的主要数据结构与算法考虑到报告的整洁性和整体观感,此处我们仅展示主要的程序代码和算法,具体的全部代码将在整体的压缩包中一并呈现另外我们考虑到后续实验中,如果在bison语法树生成的时候推不出目标的产生式时,我们设计了报错提示,在这个词的位置出现错误提示,将记录切割出来的词在code.txt中保存,并记录他们的位置。

编译原理实验报告模版-语义分析 (2) (1)

编译原理实验报告模版-语义分析 (2) (1)

编译原理课程实验报告
实验3:语义分析
姓名包福顺院系软件学院学号1113710305 任课教师陈鄞指导教师
实验地点软件学院三楼机房实验时间
实验课表现出勤、表现得分实验报告
得分
实验总分操作结果得分
一、需求分析得分
要求:阐述语义分析系统所要完成的各个功能,并给出如下语言成分所对应的语义动作•函数定义(或过程定义)
•变量说明
•赋值
•表达式
•循环
•分支
二、概要设计得分
要求:给出系统概要设计,以及必要的系统宏观层面设计图,如系统框架图、数据流图、功能模块结构图等以及相应的文字说明。

注意符号表的相关处理以及错误处理。

三、详细设计及实现得分
要求:对如下工作进行展开描述
(1) 核心数据结构的设计
(2) 主要功能函数说明
(3) 程序核心部分的程序流程图
四、实验结果及分析得分
要求:对实验结果进行描述和分析,基本内容包括:
(1)针对一测试程序输出其语义分析结果;
(2)输出针对此测试程序对应的语义错误报告;
(3)输出针对此测试程序经过语义分析后的符号表;
(4)对实验结果进行分析。

注:其中的测试样例需先用已编写的词法分析程序进行处理。

指导教师评语:
日期:。

编译原理实验报告总结

编译原理实验报告总结

编译原理实验报告总结一、实验目的编译原理是计算机科学中的一门重要课程,通过实验可以更深入地理解编译过程的各个阶段,包括词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成等。

本次编译原理实验的目的主要有以下几点:1、加深对编译原理理论知识的理解和掌握,将抽象的概念通过实际操作转化为具体的实现。

2、培养实际动手能力和解决问题的能力,通过编写代码实现编译程序的各个模块,提高编程技能和调试能力。

3、熟悉编译程序的开发流程和工具,掌握相关编程语言和开发环境的使用。

4、培养团队合作精神和沟通能力,在实验过程中与小组成员共同探讨、解决问题,提高协作效率。

二、实验环境本次实验使用的编程语言为 C/C++,开发环境为 Visual Studio 2019。

同时,使用了一些辅助工具,如调试工具、代码管理工具等,以提高开发效率和代码质量。

三、实验内容1、词法分析任务:使用正则表达式或有限自动机实现对输入源程序的词法分析,将源程序分解为一个个单词,并识别出单词的类型,如标识符、关键字、常量、运算符等。

实现方法:采用有限自动机的方法,设计状态转移图,根据输入字符的类型进行状态转移,最终确定单词的类型。

遇到的问题及解决方法:在处理一些边界情况时,如字符串中的转义字符,出现了识别错误。

通过仔细分析正则表达式和有限自动机的规则,对代码进行了相应的修改和完善,解决了问题。

2、语法分析任务:使用自顶向下或自底向上的语法分析方法,对词法分析得到的单词序列进行语法分析,构建语法树。

实现方法:选择了自顶向下的递归下降分析法,根据语法规则编写递归函数,逐个处理单词,构建语法树。

遇到的问题及解决方法:在处理复杂的语法结构时,出现了回溯和左递归的问题,导致分析效率低下。

通过消除左递归和提取公共因子,优化了语法分析算法,提高了分析效率。

3、语义分析任务:在语法分析的基础上,进行语义分析,检查语法正确的程序是否在语义上也是正确的,如类型匹配、变量未定义等。

编译原理实验报告

编译原理实验报告

编译原理实验报告一、实验目的编译原理是计算机科学中的重要学科,它涉及到将高级编程语言转换为计算机能够理解和执行的机器语言。

本次实验的目的是通过实际操作和编程实践,深入理解编译原理中的词法分析、语法分析、语义分析以及中间代码生成等关键环节,提高我们对编译过程的认识和编程能力。

二、实验环境本次实验使用的编程语言为C++,开发环境为Visual Studio 2019。

此外,还使用了一些相关的编译工具和调试工具,如 GDB 等。

三、实验内容(一)词法分析器的实现词法分析是编译过程的第一步,其任务是将输入的源程序分解为一个个单词符号。

在本次实验中,我们使用有限自动机的理论来设计和实现词法分析器。

首先,定义了各种单词符号的类别,如标识符、关键字、常量、运算符等。

然后,根据这些类别设计了相应的状态转换图,并将其转换为代码实现。

在实现过程中,使用了正则表达式来匹配输入字符串中的单词符号。

对于标识符和常量等需要进一步处理的单词符号,使用了相应的规则进行解析和转换。

(二)语法分析器的实现语法分析是编译过程的核心环节之一,其任务是根据给定的语法规则,分析输入的单词符号序列是否符合语法结构。

在本次实验中,我们使用了递归下降的语法分析方法。

首先,根据实验要求定义了语法规则,并将其转换为相应的递归函数。

在递归函数中,通过对输入单词符号的判断和处理,逐步分析语法结构。

为了处理语法错误,在分析过程中添加了错误检测和处理机制。

当遇到不符合语法规则的输入时,能够输出相应的错误信息,并尝试进行恢复。

(三)语义分析及中间代码生成语义分析的目的是对语法分析得到的语法树进行语义检查和语义处理,生成中间代码。

在本次实验中,我们使用了三地址码作为中间代码的表示形式。

在语义分析过程中,对变量的定义和使用、表达式的计算、控制流语句等进行了语义检查和处理。

对于符合语义规则的语法结构,生成相应的三地址码指令。

四、实验步骤(一)词法分析器的实现步骤1、定义单词符号的类别和对应的正则表达式。

编译原理课程实验报告

编译原理课程实验报告
思考题3:如果在语法分析中遇到了语法错误,是应该中断语法分析呢,还是应该进行适当处理后继续语法分析,你是怎么处理的?
五、实验体会
指导教师评语:
日期:
编译原理课程实验报告实验2语法分析院系姓名任课教师实验地点实验课表现学号出勤表现得分操作结果得分指导教师实验时间实验报告得分实验总分一实验目的要求需分析本次实验的基本目的并综述你是如何实现这些目的的二实验内容要求对如下工作进行展开描述1给出如下语言成分的文法描述函数定义或过程定义变量说明赋值表达式循环分支2语法分析程序的总体结构及物理实现3语法分析表及其数据结构和查找算法4语法分析表的生成算法5错误处理错误的位置及类型等三实验结果要求将实验获得的结果进行描述基本内容包括1针对一测试程序输出其语法分析结果2输出针对此测试程序对应的语法错误报告注其中的测试样例需先用已编写的词法分析程序进行处理
变量说明
赋值
表达式
循环
分支
(2)语法分析程序的总体结构及物理实现
(3)语法分析表及其数据结构和查找算法
(4)语法分析表的生成算法
(5)错误处理
错误的位置及类型等
三、实验结果
要求:将实验获得的结果进行描述,基本内容包括:
(1)针对一测试程序输出其语法分析结果;
(2)输出针对此测试程序对应的语法错误报告;
编译原理课程实验报告
实验2:语法分析
姓名
院系
学号
任课教师
指导教师
实验地点
实验时间
实验课表现
出勤、表现得分
实验报告
得分
实验总分
操作结果得分
一、实验目的
要求:需分析本次实验的基本目的,并综述你是如何实现这些目的的?
二、实验内容
要求:对如下工作进行展开描述

编译原理实验报告LL(2)分析法

编译原理实验报告LL(2)分析法

课程编译原理实验名称实验二 LL(1)分析法实验目的1.掌握LL(1)分析法的基本原理;2.掌握LL(1)分析表的构造方法;3.掌握LL(1)驱动程序的构造方法。

一.实验内容及要求根据某一文法编制调试LL(1)分析程序,以便对任意输入的符号串进行分析。

本次实验的目的主要是加深对预测分析LL(1)分析法的理解。

对下列文法,用LL(1)分析法对任意输入的符号串进行分析:(1)E->TG(2)G->+TG(3)G->ε(4)T->FS(5)S->*FS(6)S->ε(7)F->(E)(8)F->i程序输入一以#结束的符号串(包括+*()i#),如:i+i*i#。

输出过程如下:步骤分析栈剩余输入串所用产生式1 E i+i*i# E->TG... ... ... ...二.实验过程及结果代码如下:#include<iostream>#include "edge.h"using namespace std;edge::edge(){cin>>left>>right;rlen=right.length();if(NODE.find(left)>NODE.length())NODE+=left;}string edge::getlf(){return left;}string edge::getrg(){return right;}string edge::getfirst(){return first;}string edge::getfollow(){return follow;}string edge::getselect(){return select;}string edge::getro(){string str;str+=right[0];return str;}int edge::getrlen(){return right.length();}void edge::newfirst(string w){int i;for(i=0;i<w.length();i++)if(first.find(w[i])>first.length())first+=w[i];}void edge::newfollow(string w){int i;for(i=0;i<w.length();i++)if(follow.find(w[i])>follow.length()&&w[i]!='@')follow+=w[i];}void edge::newselect(string w){int i;for(i=0;i<w.length();i++)if(select.find(w[i])>select.length()&&w[i]!='@')select+=w[i];}void edge::delfirst(){int i=first.find('@');first.erase(i,1);}int SUM;string NODE,ENODE;//计算firstvoid first(edge ni,edge *n,int x){int i,j;for(j=0;j<SUM;j++){if(ni.getlf()==n[j].getlf()){if(NODE.find(n[j].getro())<NODE.length()){for(i=0;i<SUM;i++)if(n[i].getlf()==n[j].getro())first(n[i],n,x);}elsen[x].newfirst(n[j].getro());}}}//计算followvoid follow(edge ni,edge *n,int x){int i,j,k,s;string str;for(i=0;i<ni.getrlen();i++){s=NODE.find(ni.getrg()[i]);if(s<NODE.length()&&s>-1) //是非终结符if(i<ni.getrlen()-1) //不在最右for(j=0;j<SUM;j++)if(n[j].getlf().find(ni.getrg()[i])==0){if(NODE.find(ni.getrg()[i+1])<NODE.length()){for(k=0;k<SUM;k++)if(n[k].getlf().find(ni.getrg()[i+1])==0){n[j].newfollow(n[k].getfirst());if(n[k].getfirst().find("@")<n[k].getfirst().length())n[j].newfollow(ni.getfollow());}}else{str.erase();str+=ni.getrg()[i+1];n[j].newfollow(str);}}}}//计算selectvoid select(edge &ni,edge *n){int i,j;if(ENODE.find(ni.getro())<ENODE.length()){ni.newselect(ni.getro());if(ni.getro()=="@")ni.newselect(ni.getfollow());}elsefor(i=0;i<ni.getrlen();i++){for(j=0;j<SUM;j++)if(ni.getrg()[i]==n[j].getlf()[0]){ni.newselect(n[j].getfirst());if(n[j].getfirst().find('@')>n[j].getfirst().length())return;}}}//输出集合void out(string p){int i;if(p.length()==0)return;cout<<"{";for(i=0;i<p.length()-1;i++){cout<<p[i]<<",";}cout<<p[i]<<"}";}//连续输出符号void outfu(int a,string c){int i;for(i=0;i<a;i++)cout<<c;}//输出预测分析表void outgraph(edge *n,string (*yc)[50]){int i,j,k;bool flag;for(i=0;i<ENODE.length();i++){if(ENODE[i]!='@'){outfu(10," ");cout<<ENODE[i];}}outfu(10," ");cout<<"#"<<endl;int x;for(i=0;i<NODE.length();i++){outfu(4," ");cout<<NODE[i];outfu(5," ");for(k=0;k<ENODE.length();k++){flag=1;for(j=0;j<SUM;j++){if(NODE[i]==n[j].getlf()[0]){x=n[j].getselect().find(ENODE[k]);if(x<n[j].getselect().length()&&x>-1){cout<<"->"<<n[j].getrg();yc[i][k]=n[j].getrg();outfu(9-n[j].getrlen()," ");flag=0;}x=n[j].getselect().find('#');if(k==ENODE.length()-1&&x<n[j].getselect().length()&&x>-1){cout<<"->"<<n[j].getrg();yc[i][j]=n[j].getrg();}}}if(flag&&ENODE[k]!='@')outfu(11," ");}cout<<endl;}}//分析符号串int pipei(string &chuan,string &fenxi,string (*yc)[50],int &b){char ch,a;int x,i,j,k;b++;cout<<endl<<" "<<b;if(b>9)outfu(8," ");elseoutfu(9," ");cout<<fenxi;outfu(26-chuan.length()-fenxi.length()," "); cout<<chuan;outfu(10," ");a=chuan[0];ch=fenxi[fenxi.length()-1];x=ENODE.find(ch);if(x<ENODE.length()&&x>-1){if(ch==a){fenxi.erase(fenxi.length()-1,1);chuan.erase(0,1);cout<<"'"<<a<<"'匹配";if(pipei(chuan,fenxi,yc,b))return 1;elsereturn 0;}elsereturn 0;}else{if(ch=='#'){if(ch==a){cout<<"分析成功"<<endl;return 1;}elsereturn 0;}elseif(ch=='@'){fenxi.erase(fenxi.length()-1,1);if(pipei(chuan,fenxi,yc,b))return 1;elsereturn 0;}else{i=NODE.find(ch);if(a=='#'){x=ENODE.find('@');if(x<ENODE.length()&&x>-1)j=ENODE.length()-1;elsej=ENODE.length();}elsej=ENODE.find(a);if(yc[i][j].length()){cout<<NODE[i]<<"->"<<yc[i][j];fenxi.erase(fenxi.length()-1,1);for(k=yc[i][j].length()-1;k>-1;k--)if(yc[i][j][k]!='@')fenxi+=yc[i][j][k];if(pipei(chuan,fenxi,yc,b))return 1;elsereturn 0;}elsereturn 0;}}}void main(){edge *n;string str,(*yc)[50];int i,j,k;bool flag=0;cout<<"请输入上下文无关文法的总规则数:"<<endl;cin>>SUM;cout<<"请输入具体规则(格式:左部右部,@为空):"<<endl;n=new edge[SUM];for(i=0;i<SUM;i++)for(j=0;j<n[i].getrlen();j++){str=n[i].getrg();if(NODE.find(str[j])>NODE.length()&&ENODE.find(str[j])>ENODE.length()) ENODE+=str[j];}//计算first集合for(i=0;i<SUM;i++){first(n[i],n,i);}//outfu(10,"~*~");cout<<endl;for(i=0;i<SUM;i++)if(n[i].getfirst().find("@")<n[i].getfirst().length()){if(NODE.find(n[i].getro())<NODE.length()){for(k=1;k<n[i].getrlen();k++){if(NODE.find(n[i].getrg()[k])<NODE.length()){for(j=0;j<SUM;j++){if(n[i].getrg()[k]==n[j].getlf()[0]){n[i].newfirst(n[j].getfirst());break;}}if(n[j].getfirst().find("@")>n[j].getfirst().length()){n[i].delfirst();break;}}}}}//计算follow集合for(k=0;k<SUM;k++){for(i=0;i<SUM;i++){if(n[i].getlf()==n[0].getlf())n[i].newfollow("#");follow(n[i],n,i);}for(i=0;i<SUM;i++){for(j=0;j<SUM;j++)if(n[j].getrg().find(n[i].getlf())==n[j].getrlen()-1)n[i].newfollow(n[j].getfollow());}}//计算select集合for(i=0;i<SUM;i++){select(n[i],n);}for(i=0;i<NODE.length();i++){str.erase();for(j=0;j<SUM;j++)if(n[j].getlf()[0]==NODE[i]){if(!str.length())str=n[j].getselect();else{for(k=0;k<n[j].getselect().length();k++)if(str.find(n[j].getselect()[k])<str.length()){flag=1;break;}}}}//输出cout<<endl<<"非终结符";outfu(SUM," ");outfu(SUM," ");cout<<"Follow"<<endl;outfu(5+SUM,"-*-");cout<<endl;for(i=0;i<NODE.length();i++){for(j=0;j<SUM;j++)if(NODE[i]==n[j].getlf()[0]){outfu(3," ");cout<<NODE[i];outfu(SUM+4," ");out(n[j].getfirst());outfu(SUM+4-2*n[j].getfirst().length()," ");out(n[j].getfollow());cout<<endl;break;}}outfu(5+SUM,"-*-");cout<<endl<<"判定结论:";if(flag){cout<<"该文法不是LL(1)文法!"<<endl;return;}else{cout<<"该文法是LL(1)文法!"<<endl;}//输出预测分析表cout<<endl<<"预测分析表如下:"<<endl;yc=new string[NODE.length()][50];outgraph(n,yc);string chuan,fenxi,fchuan;cout<<endl<<"请输入符号串:";cin>>chuan;fchuan=chuan;fenxi="#";fenxi+=NODE[0];i=0;cout<<endl<<"预测分析过程如下:"<<endl;outfu(7," ");cout<<"分析栈";outfu(10," ");cout<<"剩余输入串";outfu(8," ");cout<<"推导所用产生式或匹配";if(pipei(chuan,fenxi,yc,i))cout<<endl<<"输入串"<<fchuan<<"是该文法的句子!"<<endl;elsecout<<endl<<"输入串"<<fchuan<<"不是该文法的句子!"<<endl;}截屏如下:三.实验中的问题及心得这次实验让我更加熟悉了LL(1)的工作流程以及LL(1)分析表的构造方法。

昆明理工编译原理实验报告2

昆明理工编译原理实验报告2

昆明理工大学信息工程与自动化学院学生实验报告( 2014 — 2015 学年 第1学期 )课程名称:编译原理 开课实验室:信自楼445 时间:2014年12月15日 一、实验目的及要求目的:编制一个语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析。

要求:在实验一词法分析的基础上,采用递归子程序法或其他适合的语法分析方法,实现其语法分析程序。

要求编译后能检查出语法错误。

已知待分析的C 语言子集的语法,用EBNF 表示如下: <程序>→main()<语句块> <语句块> →‘{’<语句串>‘}’ <语句串> → <语句> {; <语句> };<语句> → <赋值语句> |<条件语句>|<循环语句> <赋值语句>→ID=<表达式><条件语句>→if ‘(‘条件’)’<语句块> <循环语句>→while ’(‘<条件>’)‘<语句块> <条件> → <表达式><关系运算符> <表达式> <表达式> →<项>{+<项>|-<项>}年级、专业、班学号姓名成绩实验项目名称 实验二 语法分析器指导教师李亚教师评语该同学是否了解实验原理: A.了解□ B.基本了解□ C.不了解□ 该同学的实验能力: A.强 □ B.中等 □ C.差 □ 该同学的实验是否达到要求: A.达到□B.基本达到□C.未达到□ 实验报告是否规范: A.规范□ B.基本规范□ C.不规范□是否有运行结果与分析: A.详细□ B.一般 □ C.没有 □ 是否有总结与体会: A.详细□B.一般 □C.没有 □教师签名: 年 月 日<项> → <因子> {* <因子> |/ <因子>}<因子> →ID|NUM| ‘(’<表达式>‘)’<关系运算符> →<|<=|>|>=|==|!=二、实验原理及基本技术路线图(方框原理图或程序流程图)开始调用打开对话框输入文法优化输入的文法并判断文法合法性获取文法的终结符和非终结符对文法求SELECT集并判断合法性构造文法分析法输入并分析句子结束三、所用仪器、材料(设备名称、型号、规格等或使用软件)1台PC及visual c++ 6.0软件四、实验方法、步骤(或:程序代码或操作过程)#include <iostream>#include <string>using namespace std;char prog[80],token[8];char ch;int syn,p,m,n,sum,k=0;char *key[6]={"main","int","char","if","else","while"};void scaner();void lrparser();void yucu();void statement();void expression();void term();void factor();void main(){p=0;cout<<"语法分析"<<endl;cout<<"请输入字符串,以@结尾:"<<endl;do {ch = getchar(); prog[p++]=ch;}while(ch!='@');p=0;scaner();lrparser();}void scaner(){sum=m=0;for(n=0;n<8;n++) token[n]=NULL;ch=prog[p++];while(ch==' ') ch=prog[p++];if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){while((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')||(ch>='0'&&ch<='9')){token[m++]=ch; ch=prog[p++];}token[m++]='\0';p--;syn=10;for(n=0;n<6;n++)if(strcmp(token,key[n])==0){syn=n+1; break;}}else if(ch>='0'&&ch<='9'){while(ch>='0'&&ch<='9'){sum=sum*10+ch-'0';ch=prog[p++];}p--;syn=20;}elseswitch(ch){case '<': m=0;token[m++]=ch;ch=prog[p++];if(ch=='<') {syn=33; token[m++]=ch;}else if(ch=='=') {syn=35; token[m++]=ch;}break;case '>': m=0;token[m++]=ch;ch=prog[p++];if(ch=='=') {syn=34; token[m++]=ch;}else {syn=32; p--;}break;case '=':token[m++]=ch;ch=prog[p++];if(ch=='='){ syn=36;token[m++]=ch;}else{ syn=21;p--;}break;case ':': m=0;token[m++]=ch;ch=prog[p++];if(ch=='=') {syn=18; token[m++]=ch;}else {syn=17; p--;}break;case '+': syn=22; token[0]=ch; break;case '-': syn=23; token[0]=ch; break;case '*': syn=24; token[0]=ch; break;case '/': syn=25; token[0]=ch; break;case ';': syn=31; token[0]=ch; break;case '(': syn=26; token[0]=ch; break;case ')': syn=27; token[0]=ch; break;case '@': syn=0; token[0]=ch; break;default : syn=-1;}}void lrparser(){if(syn==1){scaner();yucu();if(syn=6){scaner();if(syn==0 && (k==0))cout<<"\nsuccess\n"<<endl;}else{if(k!=1)cout<<"\nwhile error\n"<<endl;k=1;}}else{cout<<"\nmain error\n"<<endl;k=1;}return;}void yucu(){statement();while(syn==31){scaner();statement();}return;}void statement(){if(syn==10){scaner();if(syn==18){scaner();expression();}else{cout<<"\nscentence error\n"<<endl;k=1;}}return;}void expression(){term();while(syn==22||syn==23){scaner();term();}return;}void term(){factor();while(syn==24||syn==25){scaner();factor();}return;}void factor(){if(syn==10||syn==20)scaner();else if(syn==26){scaner();expression();if(syn==27)scaner();else{cout<<"( error"<<endl;k=1;}}else{cout<<"expression error"<<endl;k=1;}return;}五、实验过程原始记录( 测试数据、图表、计算等)六、实验结果、分析和结论(程序运行结果、改进、收获)本实验在词法分析的基础上,对提取出的标识符进行语法判断。

编译原理实验二:消除文法的左递归.doc

编译原理实验二:消除文法的左递归.doc

编译原理实验报告实验名称消除文法的左递归实验时间2013年11月12日院系计算机科学与电子技术系班级11计算机软件学号JV114001 JV114095 JP114065 姓名唐茹韩强强徐思维1.试验目的:输入:任意的上下文无关文法。

输出:消除了左递归的等价文法。

2.实验原理:1.直接左递归的消除消除产生式中的直接左递归是比较容易的。

例如假设非终结符P 的规则为:P →P α / β其中,β是不以P 开头的符号串。

那么,我们可以把P 的规则改写为如下的非直接左递归形式: P →βP ’P ’→αP ’ / ε这两条规则和原来的规则是等价的,即两种形式从P 推出的符号串是相同的。

设有简单表达式文法G[E]: E →E+T/ T T →T*F/ F F →(E )/ I经消除直接左递归后得到如下文法: E →TE ’E ’ →+TE ’/ ε T →FT ’T ’ →*FT ’/ εF →(E )/ I考虑更一般的情况,假定关于非终结符P 的规则为P →P α1 / P α2 /…/ P αn / β1 / β2 /…/βm其中,αi (I =1,2,…,n )都不为ε,而每个βj (j =1,2,…,m )都不以P 开头,将上述规则改写为如下形式即可消除P 的直接左递归:P →β1 P ’ / β2 P ’ /…/βm P ’P ’ →α1P ’ / α2 P ’ /…/ αn P ’ /ε 2.间接左递归的消除直接左递归见诸于表面,利用以上的方法可以很容易将其消除,即把直接左递归改写成直接右递归。

然而文法表面上不存在左递归并不意味着该文法就不存在左递归了。

有些文法虽然表面上不存在左递归,但却隐藏着左递归。

例如,设有文法G[S]:S →Qc/ c Q →Rb/ b R →Sa/ a虽不具有左递归,但S 、Q 、R 都是左递归的,因为经过若干次推导有 S ⇒Qc ⇒Rbc ⇒SabcQ ⇒Rb ⇒Sab ⇒Qcab R ⇒Sa ⇒Qca ⇒Rbca就显现出其左递归性了,这就是间接左递归文法。

编译原理实验报告二

编译原理实验报告二

深圳大学实验报告课程名称:编译原理实验项目名称:语法分析--递归下降法学院:计算机与软件专业:软件工程指导教师:张小建报告人:文成学号:2011150259 班级: 2 实验时间:2013-12-25实验报告提交时间:2013-12-26教务部制一、实验目的:掌握自顶向下的语法分析法——递归下降法。

二、实验内容:用递归下降法对如下所定义的逻辑表达式进行语法分析。

1 L→ L || A2 L→ A3 A→ A && R4 A→ R5 R→ [ L ]6 R→ ! L7 R→ E >= E8 R→ E > E9 R→ E <= E10 R→ E < E11 R→ E == E12 R→ E != E13 R→ E14 E→ E + T15 E→ T16 T→ T * F17 T→ F18 F→ ( E )19 F→ n // 数20 F→ i // 标识符三、实验设计:1、消除该文法的左递归(产生式1、3、14、16);产生式(1)L→ L || A (2)L→ A消除左递归得到:L→ A L' L'→ || A L' | з产生式(3)A→ A && R (4)A→ R消除左递归得到:A→ RA' A'→ && RA' | з产生式(14)E→ E + T (15)E→ T消除左递归得到:E→ TE' E'→ + TE' | з产生式(16)T→ T * F (17)T→ F消除左递归得到:T→ FT' T'→ *FT' | з2、通过抽取公共左因子(产生式7 ~ 12),对该文法进行LL(1)改造;产生式7~127 R→ E >= E8 R→ E > E9 R→ E <= E10 R→ E < E11 R→ E == E12 R→ E != E抽取公共左因子:R→ ER'R'→ >=E | >E | <=E | <E | ==E | !=E3、证明最终得到的文法为LL(1)文法。

编译原理Lab2

编译原理Lab2

编译原理实验报告实验名称:语法分析器设计与实现实验日期: 2016.1.13学生姓名:学生学号:一、实验目的加深对语法分析器的工作过程的理解;加强对语法分析方法的掌握;能够采用一种编程语言实现简单的语法分析程序;能够使用自己编写的分析程序对简单的程序段进行语法分析。

通过本实验,应达到以下目标:1.掌握从源程序文件中读取有效字符的方法和产生源程序的内部表示文件的方法。

2.掌握语法分析的实现方法。

3.上机调试编出的语法分析程序。

二、实验内容编写语法分析程序,利用实验一词法分析的结果,逐个读入经过词法分析生成的Token 序列。

根据定义好的句型,构造LR(1)分析表,根据该表对输入串进行规约,并输出规约序列。

语法分析是编译过程中的一个阶段,在词法分析后进行。

也可以和词法分析结合在一起进行,由语法分析程序调用词法分析程序来获得当前单词供语法分析使用。

输入:Token序列输出:规约序列三、实验方案1.程序的功能:从destination.txt文件读入Token序列,在syntax.txt文件中写入规约序列,格式为X->Y。

2.实现方案:采用LR(1)文法实现:a)定义上下文无关文法(CFG)b)根据CFG构造分层有限自动机c) 根据分层有限自动机构造LR(1)分析表c) 使用LR(1)分析表设计程序四、实验假设定义上下文无关文法如下:S’->SS->if S else SS->if SS->S;SS->EE->(E)E->E+TE->E-TE->TT->T*FT->T/FT->FF->idF->num五、相关的有限自动机根据上下文无关文法构造分层有限自动机(略)六、构造LR(1)分析表根据有限自动机构造LR(1)分析表如下:对于表中的冲突项:r2/S30冲突: 因为if的优先级高于;,所以应该将if S.;S左边的if S归约为S,故应保留r2。

编译原理-语法分析实验二

编译原理-语法分析实验二

华北水利水电学院编译原理实验报告2010~2011学年第二学期 xxxx 级计算机专业班级: xxxxx 学号: xxxxx 姓名: xxx一、实验目的通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析方法。

二、实验要求⑴选择最有代表性的语法分析方法,如LL(1)分析法、算符优先法或LR分析法⑵选择对各种常见程序语言都用的语法结构,如赋值语句(尤指表达式)作为分析对象,并且与所选语法分析方法要比较贴切。

⑶实习时间为6小时。

三、实验内容选题1:使用预测分析法(LL(1)分析法)实现语法分析:(1)根据给定文法,先求出first集合、follow集合和select集合,构造预测分析表(要求预测分析表输出到屏幕或者输出到文件);(2)根据算法和预测分析表分析给定表达式是否是该文法识别的正确的算术表达式(要求输出归约过程)(3)给定表达式文法为:G(E): S→TEE→+TE | εT→FKK→*FK |εF→(S)|i(4)分析的句子为:(i+i)*i和i+i)*i四、程序源代码#include "stdafx.h"#include "SyntaxAnalysis.h"#include "SyntaxAnalysisDlg.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_ char THIS_FILE[] = __FILE__; #endif/////////////////////////////////////////// // CAboutDlg dialog used for App Aboutclass CAboutDlg : public CDialog{public:CAboutDlg();// Dialog Data//{{AFX_DATA(CAboutDlg)enum { IDD = IDD_ABOUTBOX };//}}AFX_DATA// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CAboutDlg)protected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support//}}AFX_VIRTUAL// Implementationprotected://{{AFX_MSG(CAboutDlg)//}}AFX_MSGDECLARE_MESSAGE_MAP()};CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD){//{{AFX_DATA_INIT(CAboutDlg)//}}AFX_DATA_INIT}voidCAboutDlg::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CAboutDlg)//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)//{{AFX_MSG_MAP(CAboutDlg)// No message handlers//}}AFX_MSG_MAPEND_MESSAGE_MAP()// CSyntaxAnalysisDlg dialogCSyntaxAnalysisDlg::CSyntaxAnalysisDlg(CWnd * pParent /*=NULL*/): CDialog(CSyntaxAnalysisDlg::IDD, pParent){//{{AFX_DATA_INIT(CSyntaxAnalysisDl g)m_strCode = _T("");m_strResult = _T("");//}}AFX_DATA_INIT// Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);}voidCSyntaxAnalysisDlg::DoDataExchange(CDataExc hange* pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CSyntaxAnalysisDlg)DDX_Control(pDX, IDC_LIST1, m_ListCtrl);DDX_Text(pDX, IDC_EDIT_Code, m_strCode);DDX_Text(pDX, IDC_EDIT_Result, m_strResult);//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CSyntaxAnalysisDlg, CDialog)//{{AFX_MSG_MAP(CSyntaxAnalysisDlg)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDC_BTN_Analysis, OnBTNAnalysis)//}}AFX_MSG_MAPEND_MESSAGE_MAP()// CSyntaxAnalysisDlg message handlersBOOL CSyntaxAnalysisDlg::OnInitDialog(){CDialog::OnInitDialog();ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX < 0xF000);CMenu* pSysMenu = GetSystemMenu(FALSE);if (pSysMenu != NULL){CString strAboutMenu;strAboutMenu.LoadString(IDS_ABOUTBO X);if (!strAboutMenu.IsEmpty()){pSysMenu->AppendMenu(MF_SEPARATOR);pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);}}SetIcon(m_hIcon, TRUE);// Set big iconSetIcon(m_hIcon, FALSE);// Set small icon// TODO: Add extra initialization here//初始化给定文法m_VN[0]="S";m_VN[1]="E";m_VN[2]="T";m_VN[3]="K";m_VN[4]="F";m_VT[0]="i";m_VT[1]="+";m_VT[2]="*";m_VT[3]="(";m_VT[4]=")";m_Gl[0]=0;m_Gr[0]="TE";m_Gl[1]=1;m_Gr[1]="+TE";m_Gl[2]=1;m_Gr[2]="ε";m_Gl[3]=2;m_Gr[3]="FK";m_Gl[4]=3;m_Gr[4]="*FK";m_Gl[5]=3;m_Gr[5]="ε";m_Gl[6]=4;m_Gr[6]="(S)";m_Gl[7]=4;m_Gr[7]="i";Cal_Symbol();Cal_First();Cal_Follow();DrawMList();return TRUE; // return TRUE unless you set the focus to a control}void CSyntaxAnalysisDlg::OnSysCommand(UINT nID, LPARAM lParam){if ((nID & 0xFFF0) == IDM_ABOUTBOX){CAboutDlg dlgAbout;dlgAbout.DoModal();}else{CDialog::OnSysCommand(nID, lParam);}} void CSyntaxAnalysisDlg::OnPaint(){if (IsIconic()){CPaintDC dc(this);SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);// Center icon in client rectangleint cxIcon = GetSystemMetrics(SM_CXICON);int cyIcon = GetSystemMetrics(SM_CYICON);CRect rect;GetClientRect(&rect);int x = (rect.Width() - cxIcon + 1) / 2;int y = (rect.Height() - cyIcon + 1) / 2;// Draw the icondc.DrawIcon(x, y, m_hIcon);}else{CDialog::OnPaint();}}CSyntaxAnalysisDlg::OnQueryDragIcon(){return (HCURSOR) m_hIcon;}void CSyntaxAnalysisDlg::Cal_Symbol() //求出能推出ε的非终结符{int i,j,k,nEnd;CString Gr[8];for (i=0;i<5;i++)m_nFlags[i]=0; //置初值,0表示否for (i=0;i<8;i++){Gr[i]=m_Gr[i];if (Gr[i]=="ε"){m_nFlags[m_Gl[i]]=1;//1表示是,即能推出ε}}do{nEnd=0;for (i=0;i<5;i++) //检查每一个非终结符{if (m_nFlags[i]==1) //如果该非终结符能推出ε,就将所有表达式右部删去该终结符{for(j=0;j<8;j++) //查找每一个表达式{if (Gr[j].IsEmpty()||Gr[j]=="ε") continue;for (k=0;k<Gr[j].GetLength();k++) //查找表达式右部的每一个字符{if (Gr[j].GetAt(k)==m_VN[i]) //找到该终结符{Gr[j]=Gr[j].Left(k)+Gr[j].Right(Gr[ j].GetLength()-k-1); //删去该终结符nEnd=1;break;}}if (Gr[j].IsEmpty()) m_nFlags[m_Gl[j]]=1; //如果右部为空,就在表中填是}}}} while(nEnd);}void CSyntaxAnalysisDlg::Cal_First() //求各非终结符的First集合{int i,j,k,nEnd,n;CString strFirst;for (i=0;i<5;i++){for (j=0;j<6;j++)m_First[i][j]=0;}for (i=0;i<8;i++){if (m_Gr[i].Left(2)=="ε"){m_First[m_Gl[i]][5]=1;continue;}strFirst=m_Gr[i].GetAt(0);for (j=0;j<5;j++){if(strFirst==m_VT[j]) //如果右部第一个字符是终结符{m_First[m_Gl[i]][j]=1;break;}}}do{nEnd=0;for (i=0;i<8;i++){n=0;strFirst=m_Gr[i].GetAt(0);do{for(j=0;j<5;j++){if (strFirst==m_VN[j]) //如果右部第一个字符是非终结符{for (k=0;k<6;k++){if(m_First[m_Gl[i]][k]!=m_First[j][k]){m_First[m_Gl[i]][k]=m_First[j][k];nEnd=1;}}if(m_First[j][5]==1&&n<m_Gr[i].GetLength()-1) //前一字符能推出ε,则下一字符的first集也包含于first(x)strFirst=m_Gr[i].GetAt(++n);elsestrFirst="";break;}}if (j==5) break;}while(!strFirst.IsEmpty());}} while(nEnd);}void CSyntaxAnalysisDlg::Cal_Follow() //求各非终结符的Follow集合{}void CSyntaxAnalysisDlg::DrawMList() //构造预测分析表{int i,j;for (i=0;i<5;i++){for (j=0;j<6;j++){m_M[i][j]="";}}m_M[0][0]="TE";m_M[0][3]="TE";m_M[1][1]="+TE";m_M[1][4]="ε";m_M[1][5]="ε";m_M[2][0]="FK";m_M[2][3]="FK";m_M[3][1]="ε";m_M[3][2]="*FK";m_M[3][4]="ε";m_M[3][5]="ε";m_M[4][0]="i";m_M[4][3]="(S)";m_ListCtrl.SetExtendedStyle(LVS_EX_ GRIDLINES);m_ListCtrl.InsertColumn(0,"",LVCFMT _CENTER,50);m_ListCtrl.InsertColumn(1,"i",LVCFM T_CENTER,50);m_ListCtrl.InsertColumn(2,"+",LVCFM T_CENTER,50);m_ListCtrl.InsertColumn(3,"*",LVCFM T_CENTER,50);m_ListCtrl.InsertColumn(4,"(",LVCFM T_CENTER,50);m_ListCtrl.InsertColumn(5,")",LVCFM T_CENTER,50);m_ListCtrl.InsertColumn(6,"#",LVCFM T_CENTER,50);for (i=0;i<5;i++){m_ListCtrl.InsertItem(i,m_VN[i]);for (j=0;j<6;j++){if(!m_M[i][j].IsEmpty())m_ListCtrl.SetItemText(i,j+1,"→"+m_M[i][j]);}}}void CSyntaxAnalysisDlg::OnBTNAnalysis() {UpdateData(true);if (m_strCode.IsEmpty()){MessageBox("请输入要分析的句子!","提醒");return;}if (Analysis())m_strResult+="归约过程如下:\r\n\r\n"+m_sPro.Right(m_sPro.GetLength( )-3);UpdateData(false);}//主要的程序算法BOOL CSyntaxAnalysisDlg::Analysis(){CString stack[100];int pStack;//定义一个顺序栈stack[0]="#";stack[1]="S";pStack=1;//初始化栈int n=0;CString sStack,sCode,str,strCode,strPro;int i,j;strCode=m_strCode+"#"; //输入串m_sPro="<= S";strPro="S";while (1){if (n==m_strCode.GetLength()&&pStack==0) //分析成功{m_strResult="符合给定文法.";return true;}sStack=stack[pStack];//栈顶字符sCode=strCode.GetAt(n);//剩余输入串的首字符if (sStack==sCode) //匹配{pStack--;n++;continue;}for (i=0;i<5;i++){if (sStack==m_VN[i])break;}if (i==5){m_strResult="不符合给定文法!";return false;}for (j=0;j<5;j++){if (sCode==m_VT[j])break;}if (j==5&&sCode!="#") {m_strResult="不可识别的字符: "+sCode; return false;}str=m_M[i][j]; if (str.IsEmpty()) {m_strResult="不符合给定文法!"; return false;}if (str=="ε") { strPro=strPro.Left(n)+strPro.Right(strPro.GetLength()-n-1);m_sPro="<="+strPro+"\r\n"+m_sPro;pStack--; continue;}strPro=strPro.Left(n)+str+strPro.Right(strPro.GetLength()-n-1);m_sPro="<="+strPro+"\r\n"+m_sPro; pStack--;for(j=0;j<str.GetLength();j++) {pStack++;stack[pStack]=str.GetAt(str.GetLength()-j-1); }}五、运行结果分析句子(i+i)*i正确并写出归约此次实验我继续使用VC++6.0平台编译程序,见面力求简洁,以满足实验功能为主。

编译原理实验报告

编译原理实验报告

编译原理实验报告一、实验目的本次实验的目的是了解编译原理的基本知识,并运用所学知识实现一个简单的词法分析器。

二、实验内容1.设计一个词法分析器,能够识别并输出源程序中的关键字、标识符、常数和运算符等。

2.设计并实现一个词法分析器的算法。

3.对编写的词法分析器进行测试。

三、实验过程1.设计词法分析器的算法在设计词法分析器的时候,需要先了解源程序的基本构成,了解关键字、标识符、常数和运算符等的特点,以及它们在源程序中的表示形式。

然后,根据这些特点,设计一个适合的算法来进行词法分析。

2.实现词法分析器根据设计好的算法,在编程语言中实现词法分析器。

在实现过程中,需要根据不同的词法单元,设计相应的正则表达式来进行匹配和识别。

3.测试词法分析器编写几个简单的测试用例,对词法分析器进行测试。

检查输出结果是否正确,并根据实际情况对词法分析器进行调试和优化。

四、实验结果经过测试,词法分析器能够正确识别并输出源程序中的关键字、标识符、常数和运算符等。

测试用例的输出结果与预期结果一致。

五、实验总结通过本次实验,我学习了编译原理的基本知识,掌握了词法分析器的设计和实现方法。

在实验过程中,我遇到了一些困难和问题,但通过仔细思考和查阅文献资料,最终成功地完成了实验任务。

这次实验不仅帮助我巩固了所学知识,还提高了我的编程能力和解决问题的能力。

通过实践,我深刻体会到了编译原理在软件开发中的重要性和作用,并对将来的学习和工作有了更好的规划和方向。

通过本次实验,我对编译原理的相关知识有了更深入的理解和掌握,对词法分析器的设计和实现方法有了更加清晰的认识。

同时,我还学会了如何进行实验报告的撰写,提高了我的文档写作能力。

通过本次实验,我不仅实现了实验的目标,还提高了自己的综合素质和能力。

编译原理实验报告-语法分析

编译原理实验报告-语法分析

编译原理课程实验报告实验2:语法分析
三、系统设计得分
要求:分为系统概要设计和系统详细设计。

(1)系统概要设计:给出必要的系统宏观层面设计图,如系统框架图、数据流图、功能模块结构图等以及相应的文字说明。

1)系统的数据流图:
说明
说明:本语法分析器是基于上一个实验词法分析器的基础上,通过在界面写或者是导入源程序,词法分析器将源程序识别的词法单元传递给语法分析器,语法分析器验证这个词法单元组成的串是否可以由源语言的文法生成,能够输出语法分析的结果,文法的first集、follow 集和预测分析表,当然也可以以易于理解的方式报告语法错误。

2)系统框架图
本系统框架主要是三部分,一部分是词法分析,负责识别源程序的词法单元识别,并将其存
因为预测分析表实在是过于庞大,因此本处分段截取预测分析表,下面的表是接在上面表的右侧。

(3)针对一测试程序输出其句法分析结果;
测试程序:
语法分析结果:
语法分析树:
(4)输出针对此测试程序对应的语法错误报告;
带错误的测试程序:
语法错误报告:
(5)对实验结果进行分析。

总结:
本语法分析器具有强大的语法分析功能
●允许变量的连续声明,比如int a,b,c;
●允许声明的同时赋值,比如string c = “你好”;
●允许对数组的声明和引用,同时进行赋值,比如char[4] a = {‘a’,’b’,’c’,’d’};a[0] = ‘m’;
●支持多种类型的声明和赋值,比如int,short,long,flaot,double,char,string,boolean
的声明和赋值;
●允许声明和使用一个过程函数,比如:。

编译原理上机实验报告

编译原理上机实验报告

编译原理上机实验报告一、实验目的本次实验旨在通过实践的方式理解和掌握编译原理中的一些重要概念和技术,包括词法分析、语法分析和语义分析等。

通过实验的操作,了解和体验编译器的工作过程,深入理解编译原理的相关理论知识。

二、实验环境本次实验使用了Java语言作为编程语言,使用Eclipse作为开发环境,实验所需的相关工具和库已经提前配置完成。

三、实验内容本次实验主要分为三个部分,分别是词法分析、语法分析和语义分析。

1.词法分析词法分析是编译器的第一个阶段,也是最基础的阶段。

在本次实验中,我们首先需要实现一个词法分析器,该分析器可以将源代码分割成一个个的词法单元,将其存储到一个词法单元表中。

我们首先需要定义一些词法单元的模式,比如关键字、标识符、常量等。

然后,我们使用正则表达式和有限自动机的思想来实现一个可以识别各种模式的词法分析器。

2.语法分析语法分析是编译器的第二个阶段,其目的是将词法单元表中的内容按照语法规则进行分析,生成一个语法树。

在本次实验中,我们需要实现一个递归下降的语法分析器。

我们首先需要定义一些语法规则,然后根据这些规则逐条实现相应的语法分析函数。

最终,我们可以通过递归调用这些函数,将源代码转换成语法树的形式。

3.语义分析语义分析是编译器的第三个阶段,其目的是对语法树进行进一步的检查和处理。

在本次实验中,我们需要实现一个简单的语义分析器。

我们可以在语法分析的基础上,增加一些语义规则,然后对生成的语法树进行检查。

比如,我们可以检查变量的定义和使用是否一致,是否存在未定义的变量等。

最终,我们可以通过语义分析器发现和纠正一些潜在的错误。

四、实验总结通过本次实验,我深入学习了编译原理的相关知识,并通过实践中加深了对这些知识的理解和掌握。

实验中,我了解到了词法分析、语法分析和语义分析在编译器设计中的重要性,也学会了如何使用相关工具和技术来实现这些功能。

通过实验,我发现编译原理是一门非常有趣且实用的课程,它既涉及到理论知识,又需要实践操作。

编译原理——语法分析程序设计实验报告

编译原理——语法分析程序设计实验报告

实验二语法分析程序设计[实验目的]:1.了解语法分析的主要任务。

2.熟悉编译程序的编制。

[实验内容]:根据某文法,构造一基本递归下降语法分析程序。

给出分析过程中所用的产生式序列。

[实验要求]:1.选择一个文法,进行实验,可选的文法包括以下三个:P190 4.8P190 4.9P190 4.102.设计语法分析程序的输出形式(输出应为语法树或推导),一个可以参考的例子,可见图1。

3.编写递归下降语法分析程序(参考P148-149 Topdown parsing byrecursive-descent),实现基本的递归下降分析器,能够分析任给的符号串是否为该文法所定义的合法句子。

实验报告中要说明分析使用的方法。

4.根据所作业题选项e所给出的input,生成并输出分析过程中所用的产生式序列(show the actions of parser):1 产生式12 产生式2……5.自已设计一个不合法的句子,作为输出进行分析,给出结果。

[实验过程]本次实验选择的文法为P190 4.8lexp->atom|listatom->number|identifierlist->(lexp-seq)lexp-seq->lexp lexp-seq1.写出实现的算法,并画流程图。

本次实验采用递归下降算法,算法流程图如下图1-1:图1-1 算法流程图2.根据你选择的文法,分析左递归或左因子是否会影响本算法的结果。

会影响本算法的结果。

递归下降分析法要求的文法是LL(1)文法,需要消除左递归和左因子的影响。

如果存在左因子,对相同的字符跳转到不同的函数,无法实现递归。

3.列举实验设计过程中出现的问题及解决的方法(至少3条,选择实验中最困扰的问题)。

1).会多次输出accept/error结果解决方案:所有的递归函数返回类型为int,若accept返回1,error返回0,在main主函数中统一判断输出语句。

编译原理实验报告2-词法分析程序的设计.

编译原理实验报告2-词法分析程序的设计.

实验2 词法分析程序的设计一、实验目的掌握计算机语言的词法分析程序的开发方法。

二、实验内容编制一个能够分析三种整数、标识符、主要运算符和主要关键字的词法分析程序。

三、实验要求1、根据以下的正规式,编制正规文法,画出状态图;标识符<字母>(<字母>|<数字字符>)*十进制整数0 | ((1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)*)八进制整数0(1|2|3|4|5|6|7)(0|1|2|3|4|5|6|7)*十六进制整数0x(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)*运算符和界符+ - * / > < = ( ) ;关键字if then else while do2、根据状态图,设计词法分析函数int scan( ),完成以下功能:1)从文本文件中读入测试源代码,根据状态转换图,分析出一个单词,2)以二元式形式输出单词<单词种类,单词属性>其中单词种类用整数表示:0:标识符1:十进制整数2:八进制整数3:十六进制整数运算符和界符,关键字采用一字一符,不编码其中单词属性表示如下:标识符,整数由于采用一类一符,属性用单词表示运算符和界符,关键字采用一字一符,属性为空3、编写测试程序,反复调用函数scan( ),输出单词种别和属性。

四、实验环境PC微机DOS操作系统或Windows 操作系统Turbo C 程序集成环境或Visual C++ 程序集成环境五、实验步骤1、根据正规式,画出状态转换图;2、根据状态图,设计词法分析算法;观察状态图,其中状态2、4、7、10(右上角打了星号)需要回调一个字符。

声明一些变量和函数:ch: 字符变量,存放最新读进的源程序字符。

strToken: 字符串变量,存放构成单词符号的字符串。

(完整)编译原理实验报告(词法分析器 语法分析器)

(完整)编译原理实验报告(词法分析器 语法分析器)

编译原理实验报告实验一一、实验名称:词法分析器的设计二、实验目的:1,词法分析器能够识别简单语言的单词符号2,识别出并输出简单语言的基本字。

标示符。

无符号整数.运算符.和界符。

三、实验要求:给出一个简单语言单词符号的种别编码词法分析器四、实验原理:1、词法分析程序的算法思想算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号.2、程序流程图(1)主程序(2)扫描子程序3、各种单词符号对应的种别码五、实验内容:1、实验分析编写程序时,先定义几个全局变量a[]、token[](均为字符串数组),c,s( char型),i,j,k(int型),a[]用来存放输入的字符串,token[]另一个则用来帮助识别单词符号,s用来表示正在分析的字符.字符串输入之后,逐个分析输入字符,判断其是否‘#’,若是表示字符串输入分析完毕,结束分析程序,若否则通过int digit(char c)、int letter(char c)判断其是数字,字符还是算术符,分别为用以判断数字或字符的情况,算术符的判断可以在switch语句中进行,还要通过函数int lookup(char token[])来判断标识符和保留字。

2 实验词法分析器源程序:#include 〈stdio.h〉#include <math.h>#include <string。

h>int i,j,k;char c,s,a[20],token[20]={’0’};int letter(char s){if((s〉=97)&&(s〈=122)) return(1);else return(0);}int digit(char s){if((s〉=48)&&(s<=57)) return(1);else return(0);}void get(){s=a[i];i=i+1;}void retract(){i=i-1;}int lookup(char token[20]){if(strcmp(token,"while")==0) return(1);else if(strcmp(token,"if")==0) return(2);else if(strcmp(token,"else”)==0) return(3);else if(strcmp(token,"switch”)==0) return(4);else if(strcmp(token,"case")==0) return(5);else return(0);}void main(){printf(”please input string :\n");i=0;do{i=i+1;scanf("%c",&a[i]);}while(a[i]!=’#’);i=1;j=0;get();while(s!=’#'){ memset(token,0,20);switch(s){case 'a':case ’b':case ’c':case ’d':case ’e’:case ’f’:case 'g’:case ’h':case 'i':case ’j':case 'k’:case ’l':case 'm’:case 'n':case ’o':case ’p':case ’q’:case 'r’:case 's’:case 't’:case ’u’:case ’v’:case ’w’:case ’x':case ’y':case ’z’:while(letter(s)||digit(s)){token[j]=s;j=j+1;get();}retract();k=lookup(token);if(k==0)printf("(%d,%s)”,6,token);else printf("(%d,—)",k);break;case ’0':case ’1’:case ’2':case ’3':case '4’:case '5’:case ’6':case ’7’:case ’8’:case '9’:while(digit(s)){token[j]=s;j=j+1;get();}retract();printf(”%d,%s",7,token);break;case '+':printf(”(’+',NULL)”);break;case ’-':printf("(’-',null)");break;case ’*':printf(”('*’,null)");break;case '<':get();if(s=='=’) printf(”(relop,LE)”);else{retract();printf("(relop,LT)");}break;case ’=':get();if(s=='=’)printf("(relop,EQ)");else{retract();printf(”('=',null)”);}break;case ’;':printf(”(;,null)");break;case ' ’:break;default:printf("!\n”);}j=0;get();} }六:实验结果:实验二一、实验名称:语法分析器的设计二、实验目的:用C语言编写对一个算术表达式实现语法分析的语法分析程序,并以四元式的形式输出,以加深对语法语义分析原理的理解,掌握语法分析程序的实现方法和技术.三、实验原理:1、算术表达式语法分析程序的算法思想首先通过关系图法构造出终结符间的左右优先函数f(a),g(a)。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

学生学号实验课成绩武汉理工大学学生实验报告书实验课程名称编译原理开课学院计算机科学与技术学院指导老师姓名饶文碧学生姓名学生专业班级—学年第学期实验课程名称:编译原理实验项目名称单词的词法分析实验成绩实验者专业班级组别同组者实验日期第一部分:实验分析与设计(可加页)一、实验内容描述(问题域描述)完成对某一种常用高级语言(如Pascal、C语言、PL/0语言)的各类单词进行词法分析,即对源程序从左到右进行扫描,对组成源程序的字符串拼接成为单词;并把其转换成属性字输出。

实验要求:(1)选择常用高级程序设计语言(如 Pascal、C语言、PL/0语言)的源程序作为词法分析对象。

(2)根据教学要求和学生具体情况,从上列语言之一中选取它的一个适当大小的子集,可以选取一类典型单词,也可以尽可能使各种类型的单词都能兼顾到。

其基本要求是:对源程序从左到右进行扫描,对组成源程序的字符串拼接成为单词,并把其转换成属性字输出。

二、实验基本原理与设计(包括实验方案设计,实验手段的确定,试验步骤等,用硬件逻辑或者算法描述)#include<string.h>#include<stdio.h>#include<stdlib.h>#include<ctype.h>char *table[7]={" ","main","int","if","then","else","return"},TOKEN[20],ch;//定义关键字int lookup(char *TOKEN){ //关键字匹配函数int m,i;for(i=1;i<6;i++){if((m=strcmp(TOKEN,table[i]))==0)return(i);}return(0);}void out(int c,char *TOKEN){ //输出函数printf("(%d,%s)\n",c,TOKEN);}void scanner(FILE *fp){ //扫描函数char TOKEN[20]={'\0'};char ch;int i,c;ch=fgetc(fp); //获取字符指针fp并自动指向下一个字符 if(isalpha(ch)){ //判断该字符是否是字母TOKEN[0]=ch;ch=fgetc(fp);i=1;while(isalnum(ch)){ //判断该字符是否是字母或数字TOKEN[i]=ch;i++;ch=fgetc(fp);}TOKEN[i]='\0';fseek(fp,-1,1); //回退一个字符c=lookup(TOKEN);if(c==0)out(6,TOKEN); //输出标识符else out(c,TOKEN); //输出关键字}elseif(isdigit(ch)){ //判断是否是数字TOKEN[0]=ch;ch=fgetc(fp);i=1;while(isdigit(ch)){TOKEN[i]=ch;i++;ch=fgetc(fp);}TOKEN[i]='\0';fseek(fp,-1,1);out(7,TOKEN);}else{TOKEN[0]=ch;switch(ch){case'{':out(17,TOKEN);break;case'}':out(18,TOKEN);break;case',':out(14,TOKEN);break;case';':out(15,TOKEN);break;case'<':ch=fgetc(fp);TOKEN[1]=ch;if(ch=='='){out(9,TOKEN);}else if(ch=='>'){out(11,TOKEN);}else {fseek(fp,-1,1);out(8,TOKEN);}break;case'=':out(10,TOKEN);break;case'>':ch=fgetc(fp);TOKEN[1]=ch;if(ch=='=') out(13,TOKEN); else {fseek(fp,-1,1);out(12,TOKEN);}break;default:printf("error!\n");break;}}}void main(){ FILE *fp;if((fp=fopen("D:\\ZHT.txt","r"))==NULL){//读取文件内容,并返回文件指针,该指针指向文件的第一个字符 fprintf(stderr,"error opening.\n");exit(1);}do{ch=fgetc(fp);if(ch=='#') //文件以#结尾作为扫描结束条件break;if(ch==' ') //如果是空格,自动跳到下个字符scanner(fp);else{fseek(fp,-1,1); //如果不是空格,则回退一个字符并扫描 scanner(fp);}}while(ch!='#');return(0);}三、主要仪器设备及耗材VC6.0第二部分:实验调试与结果分析(可加页)一、调试过程(包括调试方法描述、实验数据记录,实验现象记录,实验过程发现的问题等)在扫描源程序字符串时一旦识别出关键字、分隔符、标识符、无符号常数中之一即以单词形式各类单词均采用相同的结构,即二元式编码形式输出。

每次调用词法分析程序它均能自动继续扫描下去形成下一个单词,直至整个源程序全部扫描完毕,并形成相应的单词串形式的源程序。

二、实验结果及分析(包括结果描述、实验现象分析、影响因素讨论、综合分析和结论等)三、实验小结、建议及体会1、通过本次实验对词法分析的过程有了进一步的了解,并把理论知识应用于试验。

2、在编写程序过程中也遇到了很多困难,不过最终通过老师同学的帮助得到了解决。

为以后编程积累了一些小知识。

3、程序实现功能很有限,以后会继续改进。

实验课程名称:编译原理实验项目名称赋值语句的翻译程序设计实验成绩实验者专业班级组别同组者实验日期第一部分:实验分析与设计(可加页)一、实验内容描述(问题域描述)对于常用高级语言(如Pascal、C语言)的源程序从左到右进行扫描,把其中赋值语句用所学过的语法分析方法进行语法分析,采用最有代表性的语义分析方法将其转换为中间代码形式表示输出。

实验要求(1)选择最有代表性的语法分析方法,如算符优先法(或简单优先法)、递归下降分析法、LL分析法和LR分析法之一进行语法分析。

(2)选择对各种常见程序语言都通用的语法结构,如赋值语句(尤指表达式)作为分析对象,并且与所选语法分析方法要比较贴切。

(3)选择最有代表性的语义分析方法,如语法制导翻译方法进行语义翻译工作。

(4)实习时间为4~6小时。

二、实验基本原理与设计(包括实验方案设计,实验手段的确定,试验步骤等,用硬件逻辑或者算法描述)void main(){int g,h,i,j,l,p,y,z,count;int a[10]; //状态栈int ni[10]; //存放输出逆波兰式的参数char b[10]; //符号栈char str[10]; //放输入的表达式char c1;int top1,top2,top3,top,topn,m,n;char x;char copy[10]; //放Si,ri,看移进还是归约char copy1[10];char vt[6]={'+','*','i','(',')','#'}; //存放非终结符char vn='E';//存放终结符char *LR[4]={"E->E+E","E->E*E","E->(E)","E->i"}; //存放产生式};top1=0;top2=0;top3=0;top=0;topn=0;a[0]=0;y=a[0];b[0]='#';count=0;z=0;cout<<"文法G[E]:"<<endl;cout<<'\t'<<"(1) E::=E+E"<<endl;cout<<'\t'<<"(2) E::=E*E"<<endl;cout<<'\t'<<"(3) E::=(E)|i"<<endl;cout<<"文法G[E]合法句子举例: i+i*i"<<endl;cout<<"*************************************************************"<< endl;cout<<"请输入符号串:"<<endl;cin>>str;l = strlen(str);str [ l ] = '#';for(i=l+1;i<10;i++){str[i]=NULL;}cout<<endl<<'\t'<<'\t'<<"符号串"<<str<<" 分析过程如下:"<<endl;cout<<"-----------------------------------------------------------------"<<endl;cout<< "步骤" << '\t' << "状态栈" << '\t' << '\t' << "符号栈" << '\t' << '\t' << "输入串" << '\t' <<'\t'<< "ACTION "<<'\t'<<"GOTO"<<endl;do{y=z;m=0;n=0; //y,z指向状态栈栈顶g=top;j=0;x=str[top];count++;cout<<count <<'\t';while(m<=top1){ //输出状态栈cout<<a[m];m=m+1;}cout<<'\t'<<'\t';while(n<=top2){ //输出符号栈cout<<b[n];n=n+1;}cout<<'\t'<<'\t';str[top-1] = ' ';cout<<str; //输出输入串cout<<'\t'<<'\t';while(x!=vt[j]&&j<=6) j++; //vt[6]={'+','*','i','(',')','#'}存放终结符 if(j==6&&x!=vt[j]){cout<<endl<<"-----------------------------------------------------------------"<<endl;cout<<endl<<"输入字符串不是该文法的一个句子!"<<endl;cout<<endl<<"按任意数字或字母键,回车退出!"<<endl;cin>>i;return;}if(action[y][j]==NULL){cout<<endl<<"-----------------------------------------------------------------"<<endl;cout<<endl<<"输入字符串不是该文法的一个句子!"<<endl;cout<<endl<<"按任意数字或字母键,回车退出!"<<endl;cin>>i;return;}else//cout<<"y="<<y<<"j="<<j<<" "<<action[y][j];strcpy(copy,action[y][j]);if(copy[0]=='S'){ //处理移进z=copy[1]-'0';top1=top1+1;top2=top2+1;a[top1]=z; //a[10]状态栈b[top2]=x; //b[10]符号栈 x=str[top]top=top+1;i=0;while(copy[i]!='#'){cout<<copy[i];i++;}cout<<endl;}//cout<<"y="<<y<<"j="<<j<<" "<<action[y][j];if(copy[0]=='r'){ //处理归约i=0;while(copy[i]!='#'){cout<<copy[i];i++;}h=copy[1]-'0';ni[topn]=h;topn=topn+1;h=h-1;strcpy(copy1,LR[h]);//*LR[4]={"E->E+E#","E->E*E#","E->(E)#","E->i#"}存放产生式 //while(copy1[0]!=vn[0]) k++; //vn[1]={'E'}存放非终结符 l=strlen(LR[h]);top1=top1-l+3;y=a[top1];//cout<<"top1="<<top1;//y=h-1;p=goto1[y];top2=top2-l+4;top1=top1+1;a[top1]=p;b[top2]=copy1[0];z=p;cout<<'\t';cout<<p<<endl;}}while(action[y][j]!="acc");cout<<"acc"<<endl;cout<<endl<<"-------------------------------------------------------------"<<endl;cout<<endl<<"输入字符串是该文法的一个句子!"<<endl;cout<<"中间代码的逆波兰式如下:"<<endl;for(i=0;i<10;i++){if(ni[i]==1)cout<<"EEE+="<<endl;if(ni[i]==2)cout<<"EEE*="<<endl;if(ni[i]==3)cout<<"EE()="<<endl;if(ni[i]==4)cout<<"iE="<<endl;}cout<<endl<<"按任意数字或字母键,回车退出!"<<endl;cin>>i;}三、主要仪器设备及耗材VC6.0第二部分:实验调试与结果分析(可加页)一、调试过程(包括调试方法描述、实验数据记录,实验现象记录,实验过程发现的问题等)用LR分析法完成此次文法分析的关键在于构造该文法的分析表,以及如何运用该分析表完成移入和归约的过程,从而完成整个文法的分析。

相关文档
最新文档