编译原理实验课程设计

文件地址:链接: https://pan.baidu.com/s/1T8u0iwhKttFNNsVgNZSUeA 提取码: 02d1
在这里插入图片描述
编译原理实验课程设计
-词法语法分析综合设计
1 概述
通过C++实现词法语法综合分析,可以通过用户输入判断用户所需要实现的功能,做出相对应的操作。
2 实验目标

  1. 理解并掌握词法,语法分析的原理与方法。
  2. 能够使用某种语言实现词法,语法分析程序。
  3. 对编译的基本概念,原理和方法有完整和清楚的理解,并能正确而熟练的运用。
    3 实验算法描述
    3.1 实验要求
    在程序开始位置输入对应功能字母编码,通过键盘字母选择,进行词法分析、语法分析、综合分析
    在综合设计中,采用词法分析程序作为语法分析程序子程序的方法,实现词法、语法分析。
    词法分析、语法分析、综合分析通过键盘字母选择
    输入数据:程序段。
    输出结果:词法分析结果和语法分析结果和综合分析结果,包括错误列表。
    在这里插入图片描述 图1 主函数界面

3.2 本实验概述
本次实验采用C++、C语言编写词法语法分析器,要求通过字母调用之前做的两次手动实验。通过输入数字母a,实现C++语言子集符号的识别,即,词法分析。通过输入字母b,对之前输入的单词符号进行语法分析。通过输入数字母c,实现对语法和词法的综合分析。在输出abc以外的字母给予错误提示。其中对于语法分析本实验采用递归下降法。
4 技术分析
4.1 词法语法分析
本次实验主要用到的是一些基本c++、c语言的语法,如简单的判断语句if 和分支语句switch。
4.1.1词法分析
词法分析是编译程序进行编译时第一个要进行的任务,主要是对源程序进行编译预处理(去除注释、无用的回车换行找到包含的文件等)之后,对整个源程序进行分解,分解成一个个单词,对于一个具体的源程序而言,在扫描字符串时识别出一个单词,若这个单词的类型是关键字、标识符等就一此文字形式输出,每次调用词法分析程序,它都能够自动的继续扫描下去,形成下一个单词,制单源程序结束。我们把这些单词有且只有五类,分别是标识符、保留字、常数、运算符、界符。词法分析面向的对象是单个的字符,目的是把它们组成有效的单词(字符串);而语法的分析则是利用词法分析的结果作为输入来分析是否符合语法规则并且进行语法制导下的语义分析,最后产生四元组(中间代码),进行优化(可有可无)之后最终生成目标代码。可见词法分析是所有后续工作的基础,如果这一步出错,比如明明是‘<=’却被拆分成‘<’和‘=’就会对下文造成不可挽回的影响。因此,在进行词法分析的时候一定要定义好这五种符号的集合。下面构造的一个C++、C语言子集。
第一类:标识符 letter(letter | digit)* 无穷集
第二类:常数 (digit)+ 无穷集
第三类:关键字"void",“main”,“break”,“include”,“begin”,“end”,“if”,“else”,“while”,“switch”
第四类:分界符 ‘/’、‘//’、 { } " " ’ 等
第五类:运算符 <、<=、>、>=、=、+、-、
、/、^、等
概括的说,词法分析器在其工作过程中,一般应完成下列的任务:
(1) 识别出源程序中的各个单词符号,并将其转换成内部编码形式:
(2) 删除无用的空白字符、回车字符以及其他非实质性字符;
(3) 删除注释;
(4) 进行词法检查,报告所发现的错误
在这里插入图片描述
4.1.2语法分析:
语法分析是编译过程的一个逻辑阶段。语法分析的任务是在词法分析的基础上将单词序列组合成各类语法短语,如“程序”,“语句”,“表达式”等等.语法分析程序判断源程序在结构上是否正确.源程序的结构由上下文无关文法描述.语法分析程序可以用YACC等工具自动生成。完成语法分析任务的程序称为语法分析器,或语法分析程序。按照源语言的语法规则,从词法分析的结果中识别出相应的语法范畴,同时进行语法检查。
语法分析器的功能是按照源语言的语法规则,从词法分析的结果中识别出相应的语法范畴,同时进行语法检查。
给定文法G和字符串( ∈VT*),检查、判定 ∈L(G)?即检查、判定是否是文法G所能产生的合法的句子,同时报告和处理语法错误。
语法分析方法有自上而下语法分析方法(本实验使用该方法)
自上而下语法分析方法,即给定文法G和源程序串r。从G的开始符号S出发,通过反复使用产生式对句型中的非终结符进行替换(推导),逐步推导出r 。
分析的主旨是选择产生式的合适的侯选式进行推导,逐步使推导结果与src匹配.在定义部分,将语法分析中first follow文法和集合分分别存入数组,在后面输出时直接输出即可。
(1)语法分析的文法如下:
E->TG
G->+TG|-TG|
F->(E)|i
T->FS
S->*FS|/FS|
(2)语法树分析示例:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
(3)预测分析表
在这里插入图片描述
(4)First和Follow集合
在这里插入图片描述
4.1.3综合分析
对于综合分析,通过调用词法和语法完成操作,实现对输入的内容进行语法词法两次分析并输出结果,技术上就是将词法语法分析函数作为子程序来使用。
5 设计与实现
5.1 设计思路
5.1.1分析:
1.主函数:在考虑主函数的时候并没有把全部的代码都放在一个.cpp里,这样看起来也会比较的麻烦,所以对于单独复杂但是重要的功能是一.h的文件加载在主函数的头文件中的,这样降低了耦合度,使得后期对单一功能进行修改变得简单,给后期维护带来了极大的便利。
2.在语法分析器的设计过程中由于手动输入较为麻烦,此部分设计为输入一个.txt的文件名,对文件里面的程序内容进行一一的分析,
3.在综合分析的函数中,通过对词法语法的函数实现中综合分析,把输入的内容同时做语法、词法分析并输出。同时将输入的内容以文件的形式存储起来,便于后期的查找,当我们输入复杂的内容时,若多次输入是一件很繁琐的事情,这个时候不就可以直接打开我们写入内容存储的那个的文件,进行复制即可,方便快捷。
如下以流程图的方式介绍设计完整思路。
主函数流程图:
在这里插入图片描述
B功能模块流程图:
在这里插入图片描述
C功能模块流程图:在这里插入图片描述
词法分析流程图在这里插入图片描述
词法分析状态转换图在这里插入图片描述
语法分析我们在本实验中是给定了文法对其进行分析的,我们给定的文法是LL1文法,也就是说,整个程序的文法是固定的,在输入部分输入我们需要分析的串,对其进行分析,并判断他的合法性。主要也是用简单的C/C++语言输出语句、if条件语句进行分析的。当然我们的侧重点是对语法进行分析功能的实现,编程技术不是重难点,所以代码设计相对简单。
语法分析中内部主流程序如下流程图所示
在这里插入图片描述
①函数E()语法分析流程图如下:在这里插入图片描述
②、对函数T()语法分析流程图如下:在这里插入图片描述
③、对函数F()语法分析流程图如下:在这里插入图片描述
④、对函数G()语法分析流程图如下:在这里插入图片描述
⑤、对函数S()语法分析流程图如下:在这里插入图片描述
在这里插入图片描述
⑧printYC()在这里插入图片描述
综合分析功能流程图:在这里插入图片描述
5.2 实现方法
本实验采用C++、C编码,其中主要编写了以下几个函数及功能:
//词法分析核心函数
void analyze(FILE *fpin) //对输入串进行分析
bool isKey(char * token)//判断是否为关键字
bool isDigit(char digit) //判断是否为数字

//语法分析核心函数
void printFF()//输出FIRST FOLLOW集合
void printYC()//输出语法预测分析表
void printWF()//输出文法
void T()//被调函数T()
void E()//被调函数E()
void G()//被调函数E()
void F()//被调函数F()
void S()//被调函数S()
在主函数中,我们把语法词法两个功能加载成.h的文件导入在头文案中,
主函数如下:
#include
#include <stdlib.h>
#include “cffx.h”
#include “yffx.h”
int main(){
printf(“请选择执行的操作:(a 或 b 或 c)\n”);
cout<<" a.词法分析\n b.语法分析\n c.综合分析\n"<<endl;
char num;
switch(num=getchar()){
case ‘a’:{ char input[30];
FILE fpin;
cout<<“请输入文件名字:\n”<<endl;
for(;😉{
cin>>input;
if((fpin=fopen(input,“r”))!=NULL)
{ cout<<"\n
*******词法分析结果***********“<<endl;
analyze(fpin);
cout<<”\n文件词法分析已读取完…“<<endl;
fclose(fpin);
return 0;
}
else{
cout<<“打开文件失败,请重试!!!\n”<<endl;
cout<<”\n失败原因可能如下:\n1.文件名输入有误!!!\n2.文件不存在!!!\n3.文件后缀没有加!!!\n4.当前文件不在改文件夹下!!!“<<endl;
fclose(fpin);
}
}
break;
}
case ‘b’:{
int a;
for(i=0;i<4;i++)
{
printf(”\t查看文法请输入1\n\t查看First Follow输入2\n\t查看预测分析表请输入3\n\t进行语法分析请输入4\n\t直接退出整个程序请输入5\n");
scanf(“%d”,&a);
if (a1)
printWF();//输出文法
else if (a
2)
printFF();//输出First follow集合
else if (a3)
printYC();//输出预测分析表
else if (a
4)
{
printf(“\n下面进行语法分析”);
printf("\n请输入字符串(仅输入‘i’,‘+’,‘-’,‘
’,‘(’,‘)’,‘/’)以#结束):“);
scanf(”%s",&src);
i=0;
E();
if(src[i]‘#’&&flag1)
printf(“语句合法!”);
else
printf(“不合法!!!”);
}
else if (a5)
{
break;
}
}//for
break;
}
case ‘c’:{
char input[30];
char input1[30];
FILE *fpin,*fpin1;
int a;
printf(“\t查看文法请输入1\n\t查看First Follow输入2\n\t查看预测分析表请输入3\n\t进行综合分析请输入4\n\t直接退出整个程序请输入5\n”);
scanf(“%d”,&a);
if (a
1)
printWF();//输出文法
else if (a2)
printFF();//输出First follow集合
else if (a
3)
printYC();//输出预测分析表
else if (a5)
{
break;
}
else if (a
4)
{
cout<<“请输入文件名字(用于存储输入的内容,建议以.txt为后缀,方便输出):\n”<<endl;
cin>>input;
if((fpin=fopen(input,“w+”))==NULL){
cout<<“无法打开文件!”<<endl;
exit(0);
}else{
printf("请输入字符串(仅输入‘i’,‘+’,‘-’,‘
’,‘(’,‘)’,‘/’)以#结束):“);
scanf(”%s",&src);
fprintf(fpin, “%s”, src);
fclose(fpin);
cout<<“请输入要读取的文件名字(与之前输入存储输入信息文件名保持一致):\n”<<endl;
cin>>input1;
printf(“\n下列是进行综合分析结果\n”);
if((fpin1=fopen(input1,“r”))!=NULL){
cout<<“词法分析结果*”<<endl;
analyze(fpin1);
cout<<“\n已读取完…\n”<<endl;
fclose(fpin1);
cout<<“语法分析结果*”<<endl;
i=0;
E();
if(src[i]‘#’&&flag1)
printf(“语句合法”);
else
printf(“不合法”);
}
}
}
break;
}
default :
printf(“你真调皮\n\n”);
printf(“我的主人们暂时还没有给我设置那么多功能,请在a、b、c里面选择!!!\n”);exit(0);
}
return 0;
}
yyfx.h和cffx.h完整见附录文件,在此不再一一展示。
5.3 测试及测试用例
1.输入a,执行词法分析功能:再次输入data.txt(有注释) 和test.txt(注释有错误)分别测试
结果分别如下:(只截取末尾部分)
在这里插入图片描述
2.输入b执行语法分析功能:输入i+i#(正确示例),输入123(错误示例)
结果图如下:
在这里插入图片描述
3.输入c执行综合功能,输入i+i#在这里插入图片描述
其他错误及正确实例详见下表测试用例:在这里插入图片描述
在这里插入图片描述
5.4 实验结果及分析
词法分析器结果图(成功案例部分截图)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
其他错误提示案例在这里插入图片描述
优缺点:优点编程较简易易理解,缺点就是我们的代码并没有复杂的功能,这一点是需要改进的。在执行语法分析功能时,我们只能输入LL(1)文法,而不能输入其他的。

6 总结
经过这次实验,我们对编译原理有了更近一步的理解,让我们知道了词法分析的功能是输出把它组织成单个程序,让我们了解到如何设计、编写并调试词法分析程序,对语法规则有明确的定义;编写的分析程序能够进行正确的语法分析;对于遇到的语法错误,能够做出简单的错误处理,给出简单的错误 提示,保证顺利完成语法分析过程,并且通过实验的练习,加强了对基本概念的理解和应用,对以后的学习也打下了基础。目前程序也存在着少量不足 之处,主要是语法分析部分还有不完善的地方,错误报告也有待改进,希望 在经过进一步的学习后,这些问题能逐步解决。

参考文献:《编译原理(第四版)》刘铭、骆婷等 电子工业出版社
《编译技术》张莉、杨海燕等 高等教育出版社
附录文件:yyfx.h、cffx.h、data.txt、test.txt(均在文件夹中给出)
《测试用例表》*2、《种别编码表》、《状态转换图》

  • 11
    点赞
  • 158
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
山东大学编译原理实验C是指山东大学计算机科学与技术专业的编译原理实践课程中,学生需要使用C语言进行编写的实验项目。编译原理是计算机科学中的重要基础课程,主要研究如何将源代码转换为可执行的程序。在这门课程中,学生将学习如何设计和实现编译器,了解编译过程中的词法分析、语法分析、语义分析、中间代码生成等关键技术。 在山东大学编译原理实验C中,学生将通过编写C语言程序,实现这些编译器的各个模块。通过实验,学生能够深入理解编译器的工作原理和实现过程,加深对编译原理的理解。实验内容可能包括编写词法分析器,实现对源代码的词法分析和生成记号流;编写语法分析器,实现对记号流的语法分析和生成抽象语法树;编写语义分析器,对生成的抽象语法树进行语义检查和类型推导等。 在实验过程中,学生需要掌握C语言的基本语法和相关的数据结构,熟悉编程环境和工具,如gcc编译器、调试工具等。同时,学生需要学习和理解编译原理中的相关理论知识,如正则表达式、文法、自动机等,以便能够正确地进行实验设计和实现。 通过山东大学编译原理实验C,学生能够加深对编译原理的理解,并提升编程和软件设计的能力。这门实践课程为学生今后从事编译器设计和开发、编程语言实现等相关领域的研究提供了坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值