一、实验目的:
根据某一文法编制调试递归下降分析程序,以便对任意输入的符号串进行分析。本次实验的目的主要是加深对递归下降分析法的理解。
二、实验预习提示
1、递归下降分析法的功能
词法分析器的功能是利用函数之间的递归调用模拟语法树自上而下的构造过程。
2、递归下降分析法的前提
改造文法:消除二义性、消除左递归、提取左因子,判断是否为LL(1)文法,
3、递归下降分析法实验设计思想及算法
为G的每个非终结符号U构造一个递归过程,不妨命名为U。
U的产生式的右边指出这个过程的代码结构:
(1)若是终结符号,则和向前看符号对照,
若匹配则向前进一个符号;否则出错。
(2)若是非终结符号,则调用与此非终结符对应的过程。当A的右部有多个产生式时,可用选择结构实现。
具体为:
(1)对于每个非终结符号U→X1| X2|…| Xn处理的方法如下:
U( )
{
Read(ch);//当前符号
If ch in First(X1) 调用X1的子程序;
else if ch in First(X2) 调用X2的子程序;
…
else error()
}
(2)对于每个右部X1→Y1 Y 2…Y n的处理架构如下:
调用Y1的子程序;
调用Y 2的子程序;
…
调用Y n的子程序
(3)如果右部为空,则不处理。
(4)对于右部中的每个符号Yi
① 如果Yi为终结符号:
if(Yi= = 当前的符号)
{
Read(ch);//
return;
}
else error()
② 如果Yi为非终结符号,直接调用相应的子过程Yi()
三、实验过程和指导:
(一)准备:
1.阅读课本有关章节,
2.考虑好设计方案;
3.设计出模块结构、测试数据,初步编制好程序。
(二)程序要求:
程序输入/输出示例:
对下列文法,用递归下降分析法对任意输入的符号串进行分析:
(1)E→TG
(2)G→+TG|-TG
(3)G→ε
(4)T→FS
(5)S→*FS|/FS
(6)S→ε
(7)F→(E)
(8)F→i
输出的格式如下:
(1)递归下降分析程序,编制人:姓名,学号,班级
(2)输入以#结束的符号串(包括+—/()i#):在此位置输入符号串例如:i+ii#
(3)输出结果:i+i*i#为合法符号串
备注:输入符号串如i+i*#,要求输出为“非法的符号串”。
注意:1.表达式中允许使用运算符(+-*/)、分割符(括号)、字符i,结束符#;
2.如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好);
3.对学有余力的同学,可以详细的输出推导的过程,即详细列出每一步使用的产生式。
(三)程序思路(仅供参考):
0.定义部分:定义常量、变量、数据结构。
1.初始化:从文件将输入符号串输入到字符缓冲区中。
2.利用递归下降分析法分析,对每个非终结符编写函数,在主函数中调用文法开始符号的函数。
(四)练习该实验的目的和思路:
程序开始变得复杂起来,需要利用到程序设计语言的知识和大量编程技巧,递归下降分析法是一种较实用的分析法,通过这个练习可大大提高软件开发能力。通过练习,掌握函数间相互调用的方法。
(二)为了能设计好程序,注意以下事情:
1.模块设计:将程序分成合理的多个模块(函数),每个模块做具体的同一事情。
2.写出(画出)设计方案:模块关系简图、流程图、全局变量、函数接口等。
3.编程时注意编程风格:空行的使用、注释的使用、缩进的使用等。
四、实验过程
实验代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define LEN 255
bool flag=true;
char src[LEN];
int i;
void E();
void T();
void G();
void F();
void S();
int main(){
printf("编制人:周江峰,20161209719,计科1601\n");
printf("请输入字符串(以#结束):");
scanf("%s",&src);
i=0;
E();
if(src[i]=='#'&&flag==true){
printf("语句合法");
}else
{printf("不合法");}
return 0;
}
void E(){
printf("E=>TG");
T();
G();
}
void T(){
printf("T=>FS");
F();
S();
}
void G(){
if(src[i]=='+'){
i++;
printf("G->+TG");
T();
G();
}else if(src[i]=='-'){
printf("G->-TG");
i++;
T();
G();
}
}
void F(){
if(src[i]=='('){
i++;
E();
if(src[i]==')')
{ i++;
printf("F->(E)");}
else flag=false;
}
else if(src[i]=='i')
{ printf("F->i");
i++;}
else flag=false;
}
void S(){
if(src[i]=='*'){
i++;
F();
S();
}else if(src[i]=='/'){
i++;
F();
S();
}
}
注:文件后缀为.cpp
五、实验结果
本文图片均来自课堂实验 如有侵权 联系速删