当前位置:网站首页>编译原理研究性学习专题 2——递归下降语法分析设计原理与实现
编译原理研究性学习专题 2——递归下降语法分析设计原理与实现
2022-07-28 21:51:00 【dor.yang】
1 实验内容
完成以下描述赋值语句的 LL(1)文法的递归下降分析程序
G[S]: S→ V=E
E→ TE’
E’→ ATE’ | e
T→ FT’
T’→ MFT’ | E
F→ (E) | i
A→ + | -
M→ * | /
V→ i
设计说明:终结符号 i 为用户定义的简单变量,即标识符的定义。
2 实验要求
(1)输入串应是词法分析的输出二元式序列,即某算术表达式“专题 1” 的输出结果,输出为输入串是否为该文法定义的算术表达式的判断结果;
(2)递归下降分析程序应能发现简单的语法错误;
(3)设计两个测试用例(尽可能完备,正确和出错),并给出测试结果;
(4)选做:如有可能,考虑如何用文法描述 C 语言的 if 语句,使整个文 法仍然为 LL(1)文法,并使得你的递归下降程序可以分析赋值语句和 if 语句
3.程序功能描述
结合实验要求,完成实验二程序,具体实现功能为读取同目录下的实验一输出的词法判别的二元式文件,根据给定文法,按照递归下降分析的方式判断输入的语句是否合理。对于不合理的部分,在判定出错之后输出错误的点。
4.程序结构描述
由于语法是给定的,所以可以先完成first和follow集合的计算:
根据first和follow集合以及给定的文法,可以确定递归向下分析程序的结构。
所以程序的整体表达式结构为:
S的递归分析程序结构如下图
E的递归下降分析程序结构如下图:
E’的递归向下分析的结构图
T的递归下降分析程序结构如下:
T’的递归下降分析程序结构如下:
F的递归下降分析程序结构如下:
A的递归下降分析程序结构如下:
M的递归下降分析程序结构如下:
V的递归下降分析程序结构如下:
5.实现代码
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<iostream>
#include <cassert>
#include<fstream>
#define MAX_LINE 1024
using namespace std;
// 函数声明
void S();
void E();
void E_();
void T();
void T_();
void F();
void A();
void M();
void V();
// 定义一个长度为100的字符数组
char s[100];
// 用来作数组索引,当每次匹配成功存入数据时index自增1
int i;
// 用来标记语句是否正确
int SIGN;
int main()
{
// printf("请输入你的语句(记得在最后带上#)\n");
cout<<"读取文件可知输入语句:"<<endl;
FILE *fp;
char buf[MAX_LINE];
string shizi,like;
if((fp = fopen("text.txt","r"))!=NULL){
while(fgets(buf,MAX_LINE,fp) != NULL)
{
int len = strlen(buf);
buf[len-1] = '\0'; /*去掉换行符*/
printf("%s \n",buf);
int flag=0;
if(buf[1]=='1'){
like+='i';
}
for(int i=0;i<len;i++){
if(buf[i]=='"'&&flag==0){
i++;
while(buf[i]!='"'){
shizi+=buf[i];
if(buf[1]!='1'){
like+=buf[i];
}
i++;
}
}
}
}
}
shizi+='#';
like+='#';
fclose(fp);
cout<<"输入的语句为:"<<shizi<<endl;
cout<<"可以理解为:"<<like<<endl;
SIGN = 0;//语句是否正确用SIGN
i=0;
//将输入的式子按照修改为字符串格式char*
int length=like.length();
for(int i=0;i<length;i++){
s[i]=like[i];
}
// 当输入的第一个字符为#时,程序直接结束
if( s[0] == '#')
return 0;
S();
// 如果最后的字符以#结束则输出下面
if(s[i]=='#'&&SIGN==0){
printf("\n语句合法\n");
}else{
printf("\n语句不合法\n");
}
// printf("请输入你的语句(记得在最后带上#)\n");
// }
return 1;
}
void S()
{
if(SIGN==0)
{
printf("S检查 ");
// 当输入的字符串中首字母为a时
if(s[i]=='i'){
V();
if(SIGN==0&&s[i]=='='){
// printf("(%c) ",s[i]);
i++;
E();
}
else{
SIGN=1;
cout<<"S处出现错误"<<endl;
}
}
else{
SIGN=1;
cout<<"S处出现错误"<<endl;
}
}
}
void E()
{
if(SIGN==0){
printf("E ");
if(s[i]=='('||s[i]=='i'){
T();
if(SIGN==0){
if(s[i]=='+'||s[i]=='-'){
E_();
}
else if(s[i]==')'||s[i]=='#'){
return;
}
else{
SIGN=1;
cout<<"E处出现错误"<<endl;
}
}
}
else{
SIGN=1;
cout<<"E处出现错误"<<endl;
}
}
}
void E_()
{
if(SIGN==0){
printf("E' ");
if(s[i]=='+'||s[i]=='-'){
A();
if(SIGN==0){
if(s[i]=='('||s[i]=='i'){
T();
if(SIGN==0){
if(s[i]=='+'||s[i]=='-'){
E_();
}
else if(s[i]==')'||s[i]=='#') {
return;
}
else{
SIGN=1;
cout<<"E'处出现错误"<<endl;
}
}
}
else{
SIGN=1;
cout<<"E'处出现错误"<<endl;
}
}
}
else if(s[i]==')'||s[i]=='#'){
return;
}
else{
SIGN=1;
cout<<"E'处出现错误"<<endl;
}
}
}
void T()
{
if(SIGN==0){
printf("T ");
if(s[i]=='('||s[i]=='i'){
F();
if(SIGN==0){
if(s[i]=='*'||s[i]=='/'){
T_();
}
else if(s[i]=='+'||s[i]=='-'||s[i]==')'||s[i]=='#') {
return;
}
else{
SIGN=1;
cout<<"T处出现错误"<<endl;
}
}
}
else{
SIGN=1;
cout<<"T处出现错误"<<endl;
}
}
}
void T_()
{
if(SIGN==0){
printf("T' ");
if(s[i]=='*'||s[i]=='/'){
M();
if(SIGN==0){
F();
if(SIGN==0){
T_();
}
}
}
else if(s[i]=='+'||s[i]=='-'||s[i]==')'||s[i]=='#'){
return;
}
else{
SIGN=1;
cout<<"T'处出现错误"<<endl;
}
}
}
void F()
{
if(SIGN==0){
printf("F ");
if(s[i]=='('){
// printf("(%c) ",s[i]);
i++;
if(s[i]=='('||s[i]=='i'){
E();
if(SIGN==0){
if(s[i]==')'){
// printf("(%c) ",s[i]);
i++;
}
else{
SIGN=1;
cout<<"F处出现错误"<<endl;
}
}
}
else{
SIGN=1;
cout<<"F处出现错误"<<endl;
}
}
else if(s[i]=='i'){
// printf("(%c) ",s[i]);
i++;
}
else{
SIGN=1;
cout<<"F处出现错误"<<endl;
}
}
}
void A()
{
if(SIGN==0){
printf("A ");
if(s[i]=='+'||s[i]=='-'){
// printf("(%c) ",s[i]);
i++;
}
else{
SIGN=1;
cout<<"A处出现错误"<<endl;
}
}
}
void M()
{
if(SIGN==0){
printf("M ");
if(s[i]=='*'||s[i]=='/'){
// printf("(%c) ",s[i]);
i++;
}
else{
SIGN=1;
cout<<"M处出现错误"<<endl;
}
}
}
void V()
{
if(SIGN==0){
printf("V ");
if(s[i]=='i'){
// printf("(%c) ",s[i]);
i++;
}
else{
SIGN=1;
cout<<"V处出现错误"<<endl;
}
}
}
6.程序测试
按照实验要求,提供两个测试样例,一个正确一个错误:
首先是正确的测试样例,将a=b*(c+d)输入在input文件中,启动程序lab1,产生对应的二元式,这里为了便于判断和操作,将标识符的二元式输出修改为(1,‘符号’),得到的输出二元式如下:
接下来启动Lab2,可以得到如下结果:
将上图的输出部分单独显示:
读取文件可知输入语句:
(1,“a”)
(运算符,“=”)
(1,“b”)
(运算符,"“)
(分隔符,”(“)
(1,“c”)
(运算符,”+“)
(1,“d”)
(分隔符,”)")
输入的语句为:a=b(c+d)#
可以理解为:i=i*(i+i)#
S检查 V E T F T’ M F E T F E’ A T F T’
语句合法
其中倒数第二行的输出是进行递归下降分析的过程中,每一个非终结符号对应函数的使用的输出。
接下来是错误的测试样例:将a=b*(c+d输入在input文件中,启动程序lab1,产生对应的二元式,得到的输出二元式如下:
启动Lab2的程序之后得到的结果如下:
将程序输出部分单独显示:
读取文件可知输入语句:
(1,“a”)
(运算符,“=”)
(1,“b”)
(运算符,"“)
(分隔符,”(“)
(1,“c”)
(运算符,”+")
(1,“d”)
输入的语句为:a=b(c+d#
可以理解为:i=i*(i+i#
S检查 V E T F T’ M F E T F E’ A T F
F处出现错误
语句不合法
边栏推荐
- ACM SIGIR 2022 | 美团技术团队精选论文解读
- 苹果官网正在更新维护 Apple Store,国行 iPhone 13 / Pro 等产品将最高优惠 600 元
- 通过Wi-Fi 7实现极高吞吐量——洞察下一代Wi-Fi物理层
- 金仓数据库KingbaseES客户端编程接口指南-ODBC(5. 开发过程)
- What's special about this wireless router, which is popular in the whole network?
- 金仓数据库 KingbaseES V8.3至V8.6迁移最佳实践(3. KingbaseES移植能力支撑体系)
- XML modeling
- Huawei wireless device configuration uses WDS technology to deploy WLAN services
- CV语义分割模型小抄(2)
- 2022焊工(初级)上岗证题目及答案
猜你喜欢
[self] - brush questions array
Price for volume has encountered "six consecutive declines" in sales. Can Volvo, which is no longer safe, turn around?
Programmer growth Chapter 30: artifact of identifying true and false needs
深度剖析集成学习GBDT
Huawei wireless device configuration uses WDS technology to deploy WLAN services
2022G3锅炉水处理考试模拟100题模拟考试平台操作
网络流量监控工具iftop
【自】-刷题-峰值
通过Wi-Fi 7实现极高吞吐量——洞察下一代Wi-Fi物理层
字节8年女测试总监工作感悟—写给想转行或即将进入测试行业的女生们...
随机推荐
Runloop principle (II)
行泊一体迎爆发期,抢量产还是修技术护城河?
行泊ADAS摄像头前装搭载同比增长54.15%,TOP10供应商领跑
零念科技完成Pre-A轮融资,推动智能驾驶平台软件国产替代
Form label
【自】-刷题-BFS
超参数优化(网格搜索和贝叶斯优化)
Few people can really play in the "aftermarket" of the whole house intelligent fire collection
Achieve high throughput through Wi Fi 7 - insight into the next generation of Wi Fi physical layer
Object object
MyCms 自媒体商城 v3.6 发布,兼容微擎应用开发(Laravel框架)
What if win11 quick copy and paste cannot be used? Win11 shortcut copy and paste cannot be used
2022t elevator repair examination questions and simulation examination
通过Wi-Fi 7实现极高吞吐量——洞察下一代Wi-Fi物理层
金仓数据库KingbaseES 客户端编程接口指南 - ODBC特性支持约束
Mongodb index add, view, export, delete
可视化全链路日志追踪
What is utxo?
2022年R2移动式压力容器充装考题模拟考试平台操作
2022 R2 mobile pressure vessel filling test question simulation test platform operation