概述
实现递归下降分析器
- 实验内容
- 开发环境
- 数据结构
- 1 符号栈
- 2 分析过程
- 3 数组
- 实验步骤
- 分析与设计
- 编程
- 1 全局变量
- 2 栈
- 3 数组
- 4 函数
- 5 伪代码
- 运行与调试
- 运行结果
- 所遇问题与解决方案
- 1 E’和T’的压栈
- 2 栈的实现
- 心得体会
- 实验代码
- 1 主函数main()
- 2 E()
- 3 E1()
- 4 T()
- 5 T1()
- 6 F()
- 7 print()
实验内容
用高级语言实现课本3.2文法的递归下降分析程序。
要求:
可使用书上提供的输入串i1*(i2+i3),也可以是自己定义的其他符号串;输出栈中所有内容,并给出分析结果。
开发环境
windows 10
visual studio 2019
数据结构
1 符号栈
栈是一种有存取限制的线性表,它只允许在一端进行插入或删除操作。遵循“先进先出”原则。
递归下降分析法是一种自顶向下的分析方法,文法的每个非终结符对应一个递归过程(函数),可用栈来表示分析过程。
2 分析过程
序号 | 符号栈 | 待分析字符 | 表达式 |
---|---|---|---|
0 | # | i*(i+i)# | |
1 | #E | i*(i+i)# | E→TE’ |
2 | #E’T | i*(i+i)# | T→FT’ |
3 | #E’T’F | i*(i+i)# | F→i |
4 | #E’T’ | i*(i+i)# | T’→*FT’ |
5 | #E’T’F | i*(i+i)# | F→(E) |
6 | #E’T’E | i*(i+i)# | E→TE’ |
7 | #E’T’E’T | i*(i+i)# | T→FT’ |
8 | #E’T’E’T’F | i*(i+i)# | F→i |
9 | #E’T’E’T’ | i*(i+i)# | T’→ε |
10 | #E’T’E’ | i*(i+i)# | E’→+TE’ |
11 | #E’T’E’T | i*(i+i)# | T→FT’ |
12 | #E’T’E’T’F | i*(i+i)# | F→i |
13 | #E’T’E’T’ | i*(i+i)# | T’→ε |
14 | #E’T’E’ | i*(i+i)# | E’→ε |
15 | #E’T’ | i*(i+i)# | T’→ε |
16 | #E’ | i*(i+i)# | E’→ε |
17 | # |
3 数组
1、分析串数组char token[token_size]:存放待分析串。
2、符号栈char stack[10] = {’#’}:存放符号栈内容,初始压入‘#’。
实验步骤
分析与设计
教材上的例题已然分析地较详细:
1、 已消除左递归。
2、 无回溯。
我们直接进行递归下降分析器的构造。
编程
1 全局变量
① token_len:int类型变量,存放待分析串的长度。
② step:int类型变量,记录当前分析步数。
2 栈
① char stack[10] = {’#’}:char类型数组,存放符号栈内容,初始压入‘#’。
② stack_top:int类型变量,为符号栈的栈顶指针。
3 数组
token[token_size]:cha类型数组,存放待分析串。
4 函数
① 非终结符表达式:
void E();
void E1();
void T();
void T1();
void F();
② 打印函数:void print()。
5 伪代码
见《编译原理教程(第四版)》P52-53
void match(token t){
if (lookahead == t)
lookahead = nexttoken;
else
error();
}
void E(){
T();
E();
}
void E'(){
if (lookahead == '+'){
match('+');
T();
E'();
}
}
void T(){
F();
T'();
}
void T'(){
if (lookahead == '*'){
match('*');
F();
T'();
}
}
void F(){
if (lookahead == 'i')
match('i');
else if (lookahead == '('){
match('(');
E();
if (lookahead == ')')
match(')');
else
error();
}
else
error();
}
运行与调试
根据调试情况进行相应的代码修改。
运行结果
所遇问题与解决方案
1 E’和T’的压栈
因为E’不属于一个字符,在考虑存放的时候本来是准备实现字符串数组的,问题有点多,所以就直接按照’E’和’’’两个字符来存储E’了,T’同理。
2 栈的实现
心得体会
对递归下降分析器的构造有了更深的理解,也更熟练地掌握了栈的实现。
实验代码
1 主函数main()
int main(void){
printf("请输入字符串(以#结束):"); //输入待分析字符串
while (token[lookahead] != '#'){ //如果没有按下#结束
char scan_char; //扫描字符
do{ //若没有扫描到结束符#,就继续扫描
scanf_s("%c", &scan_char,1);
token[token_len] = scan_char; //将扫描到的字符保存到待分析串数组中
token_len++;
} while (scan_char != '#');
printf("n");
printf("序号t");
printf("符号栈tt");
printf("待分析字符t");
printf("表达式n");
print(); //打印当前步骤信息
printf("n"); //换行
stack[++stack_top] = 'E'; //将E()压入栈中,开始分析
step++; //分析步数+1
E();
if (token[lookahead] == '#') //若待分析字符为#,说明符合文法
printf("n分析成功,合法字符串!");
else
printf("n分析失败,非法字符串!");
}
return 0;
}
2 E()
/*****************************************************************************
*函数名称:E()
*函数类型:void
*参数:void
*功能:分析文法,输出信息
*****************************************************************************/
void E(){
print(); //打印当前步骤信息
printf("E->TE'n"); //输出表达式
stack[stack_top] = 'E'; //将产生式右→左压栈
stack[++stack_top] = '''; //代表E'
stack[++stack_top] = 'T';
step++; //分析步数+1
T();
E1();
}
3 E1()
/*****************************************************************************
*函数名称:E1()
*函数类型:void
*参数:void
*功能:分析文法,输出信息
*****************************************************************************/
void E1(){
if (token[lookahead] == '+'){ //若待分析字符匹配‘+’
print(); //打印当前步骤信息
printf("E'->+TE'n"); //输出表达式
stack[--stack_top] = 'E'; //将产生式右→左压栈
stack[++stack_top] = ''';
stack[++stack_top] = 'T';
step++; //分析步数+1
lookahead++; //因为匹配到一个终结符,所以分析下一个字符
T();
E1();
}
else{
print(); //打印当前步骤信息
printf("E'->εn"); //输出表达式
stack[stack_top--] = NULL; //出栈
stack[stack_top--] = NULL; //E'虽然为一个非终结符,但占两个字符,T'同
step++; //分析步数+1
}
}
4 T()
/*****************************************************************************
*函数名称:T()
*函数类型:void
*参数:void
*功能:分析文法,输出信息
*****************************************************************************/
void T(){
print(); //打印当前步骤信息
printf("T->FT'n"); //输出表达式
stack[stack_top] = 'T'; //将产生式右→左压栈
stack[++stack_top] = ''';
stack[++stack_top] = 'F';
step++; //分析步数+1
F();
T1();
}
5 T1()
/*****************************************************************************
*函数名称:T1()
*函数类型:void
*参数:void
*功能:分析文法,输出信息
*****************************************************************************/
void T1(){
if (token[lookahead] == '*'){ //若待分析字符匹配‘*’
print(); //打印当前步骤信息
printf("T'->*FT'n"); //输出表达式
stack[--stack_top] = 'T'; //将产生式右→左压栈
stack[++stack_top] = ''';
stack[++stack_top] = 'F';
step++; //分析步数+1
lookahead++; //因为匹配到一个终结符,所以分析下一个字符
F();
T1();
}
else{
print(); //打印当前步骤信息
printf("T'->εn"); //输出表达式
stack[stack_top--] = NULL; //出栈
stack[stack_top--] = NULL;
step++; //分析步数+1
}
}
6 F()
/*****************************************************************************
*函数名称:F()
*函数类型:void
*参数:void
*功能:分析文法,输出信息
*****************************************************************************/
void F(){
if (token[lookahead] == 'i'){ //若待分析字符匹配‘i’
print(); //打印当前步骤信息
printf("F->in"); //输出表达式
stack[stack_top--] = NULL; //出栈
step++; //分析步数+1
lookahead++; //因为匹配到一个终结符,所以分析下一个字符
}
else if (token[lookahead] == '('){ //若待分析字符匹配‘(’
print(); //打印当前步骤信息
printf("F->(E)n"); //输出表达式
stack[stack_top] = 'E'; //将产生式右→左压栈
step++; //分析步数+1
lookahead++; //因为匹配到一个终结符,所以分析下一个字符
E();
if (token[lookahead] == ')'){ //若待分析字符匹配‘)’
lookahead++; //因为匹配到一个终结符,所以分析下一个字符
}
else{
printf("没有')'匹配!n");
return;
}
}
else{
printf("errorn");
return;
}
}
7 print()
/*****************************************************************************
*函数名称:print()
*函数类型:void
*参数:void
*功能:打印信息
*****************************************************************************/
void print(){
int i;
printf("%dt", step); //打印分析第step步
for (i = 0; i <= stack_top; i++) //输出分析栈中内容
printf("%c", stack[i]);
if (stack_top < 7) //每列对齐
printf("tt");
else
printf("t");
for (i = 0; i < lookahead; i++){ //若字符已被分析,它的位置置空,保持列对齐
token[i] = ' ';
printf("%c", token[i]);
}
for (i = lookahead; i < token_len; i++) //输出剩余待分析字符
printf("%c", token[i]);
printf("t"); //为输出表达式做准备
}
点击下载完整代码
最后
以上就是生动盼望为你收集整理的【编译原理】实验二:实现递归下降分析器实验内容开发环境数据结构实验步骤运行结果所遇问题与解决方案心得体会实验代码的全部内容,希望文章能够帮你解决【编译原理】实验二:实现递归下降分析器实验内容开发环境数据结构实验步骤运行结果所遇问题与解决方案心得体会实验代码所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复