一、实验项目要求
1.实验目的
根据某一文法编制调试递归下降分析程序,以便对任意输入的符号串进行分析。本次实验的目的主要是加深对递归下降分析法的理解。
2.实验要求
对下列文法,用递归下降分析法对任意输入的符号串进行分析:
(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+i*i#
(3)输出结果:i+i*i#为合法符号串
备注:输入一符号串如i+i*#,要求输出为“非法的符号串”。
注意:
1.表达式中允许使用运算符(+-*/)、分割符(括号)、字符i,结束符#;
2.如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好);
二、理论分析或算法分析
1、程序设计:
(1)模块设计:将程序分成合理的多个模块(函数),每个模块做具体的同一事情。
(2)写出设计方案:模块关系简图、流程图、全局变量、函数接口等。
(3)程序编写:
①定义部分:定义常量、变量、数据结构。
②初始化:从文件将输入符号串输入到字符缓冲区中。
③利用递归下降分析法,对每个非终结符编写函数,在主函数中调用文法开始符号的函数。
三、实验方法
程序流程图如图所示:
四、实验结果分析
实验结果图
遇到的问题
(1)遇到如图所示的问题:
解决办法
(1)在文件顶部加入一行#define _CRT_SECURE_NO_WARNINGS后可以解决;
通过本次实验,学习了语法分析,让我对语法分析有了一定的认识和了解。递归下降分析法,是一种确定的自顶向下分析技术,它的实现思想是,对文法分别代表一种语法成分的每个非终结符号编写一个子程序,已完成非终结符号所对应的语法成分的分析任务。在分析过程中调用一系列过程或函数,对源程序进行语法语义分析直到整个程序处理结束;即使理解了理论知识,我也不一定会编程。
五、代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<dos.h>
#include<stdlib.h>
#include<string.h>
char a[50], b[50], d[500], e[10];
char ch;
int n1, i1 = 0, flag = 1, n = 5;
int E();
int E1();
int T();
int G();
int S();
int F();
void input();
void input1();
void output();
void main() /*递归分析*/
{
int f, p, j = 0;
char x;
d[0] = 'E';
d[1] = '=';
d[2] = '>';
d[3] = 'T';
d[4] = 'G';
d[5] = '#';
printf("递归下降分析程序,编制人:***,**号,******班\n");
printf("输入一以#结束的符号串(包括+ - * / ( ) i #,且长度小于50):");
do {
scanf("%c", &ch);
a[j] = ch;
j++;
} while (ch != '#');
n1 = j;
ch = b[0] = a[0];
printf("文法\t分析串\t\t\t分析字符\t\t剩余串\n");
f = E1();
if (f == 0) return;
if (ch == '#')
{
printf("accept\n");
p = 0;
x = d[p];
// {
// printf("%c",x);p=p+1;x=d[p]; /*输出推导式*/
// }
while (a[p] != '#')
printf("%c", a[p++]);
printf("为合法字符!\n");
}
else {
// printf("error\n");
j = 0;
while (a[j] != '#')
printf("%c", a[j++]);
printf("非法字符!\n");
printf("回车返回\n");
getchar(); getchar();
return;
}
printf("\n");
printf("回车返回\n");
getchar();
getchar();
}
int E1()
{
int f, t;
printf("E-->TG\t");
flag = 1;
input();
input1();
f = T();
if (f == 0) return(0);
t = G();
if (t == 0) return(0);
else return(1);
}
int E()
{
int f, t;
printf("E-->TG\t");
e[0] = 'E'; e[1] = '='; e[2] = '>'; e[3] = 'T'; e[4] = 'G'; e[5] = '#';
output();
flag = 1;
input();
input1();
f = T();
if (f == 0)
return(0);
t = G();
if (t == 0) return(0);
else return(1);
}
int T()
{
int f, t;
printf("T-->FS\t");
e[0] = 'T'; e[1] = '='; e[2] = '>'; e[3] = 'F'; e[4] = 'S'; e[5] = '#';
output();
flag = 1;
input();
input1();
f = F();
if (f == 0)
return(0);
t = S();
if (t == 0) return(0);
else return(1);
}
int G()
{
int f;
if (ch == '+')
{
b[i1] = ch;
printf("G-->+TG\t");
e[0] = 'G'; e[1] = '='; e[2] = '>'; e[3] = '+'; e[4] = 'T'; e[5] = 'G'; e[6] = '#';
output();
flag = 0;
input(); input1();
ch = a[++i1];
f = T();
if (f == 0)
return(0);
f = G();
if (f == 0)
return 0;
else return 1;
}
else if (ch == '-')
{
b[i1] = ch;
printf("G-->-TG\t");
e[0] = 'G'; e[1] = '='; e[2] = '>'; e[3] = '-'; e[4] = 'T'; e[5] = 'G'; e[6] = '#';
output();
flag = 0;
input(); input1();
ch = a[++i1];
f = T();
if (f == 0)
{
// printf("G=%d\n",f);
return(0);
}
f = G();
if (f == 0)
return 0;
else return 1;
}
else
{
printf("G-->^\t");
e[0] = 'G'; e[1] = '='; e[2] = '>'; e[3] = '^'; e[4] = '#';
output();
flag = 1;
input(); input1();
return(1);
}
}
int S()
{
int f, t;
if (ch == '*')
{
b[i1] = ch;
printf("S-->*FS\t");
e[0] = 'S'; e[1] = '='; e[2] = '>'; e[3] = '*'; e[4] = 'F'; e[5] = 'S'; e[6] = '#';
output();
flag = 0;
input(); input1();
ch = a[++i1];
f = F();
if (f == 0)
return(0);
t = S();
if (t == 0)
return(0);
else return(1);
}
else if (ch == '/')
{
b[i1] = ch;
printf("S-->/FS\t");
e[0] = 'S'; e[1] = '='; e[2] = '>'; e[3] = '/'; e[4] = 'F'; e[5] = 'S'; e[6] = '#';
output();
flag = 0;
input(); input1();
ch = a[++i1];
f = F();
if (f == 0)
return(0);
t = S();
if (t == 0)
return(0);
else return(1);
}
else
{
printf("S-->^\t");
e[0] = 'S'; e[1] = '='; e[2] = '>'; e[3] = '^'; e[4] = '#';
output();
flag = 1;
a[i1] = ch;
input(); input1();
return(1);
}
}
int F()
{
int f; int j;
if (ch == '(')
{
b[i1] = ch;
printf("F-->(E)\t");
e[0] = 'F'; e[1] = '='; e[2] = '>'; e[3] = '('; e[4] = 'E'; e[5] = ')'; e[6] = '#';
output();
flag = 0;
input(); input1();
ch = a[++i1];
f = E();
if (f == 0) return(0);
if (ch == ')')
{
b[i1] = ch;
printf("F-->(E)\t");
flag = 0; input(); input1();
ch = a[++i1];
}
else
{
printf("error\n");
j = 0;
while (a[j] != '#')
printf("%c", a[j++]);
printf("非法字符!\n");
return(0);
}
}
else if (ch == 'i')
{
b[i1] = ch;
printf("F-->i\t");
e[0] = 'F'; e[1] = '='; e[2] = '>'; e[3] = 'i'; e[4] = '#';
output();
flag = 0; input(); input1();
ch = a[++i1];
}
else {
printf("error\n");
j = 0;
while (a[j] != '#')
printf("%c", a[j++]);
printf("非法字符!\n");
return(0);
}
return(1);
}
void input()
{
int j = 0;
for (; j <= i1 - flag; j++)
printf("%c", b[j]); /*输出分析串*/
printf("\t\t\t");
printf("%c\t\t\t", ch); /*输出分析字符*/
}
void input1()
{
int j;
for (j = i1 + 1 - flag; j < n1; j++)
printf("%c", a[j]); /*输出剩余字符*/
printf("\n");
}
void output() { /*推导式计算*/
int m, k, j, q;
int i = 0;
m = 0; k = 0; q = 0;
i = n;
d[n] = '='; d[n + 1] = '>'; d[n + 2] = '#'; n = n + 2; i = n;
i = i - 2;
while (d[i] != '>'&&i != 0) i = i - 1;
i = i + 1;
while (d[i] != e[0]) i = i + 1;
q = i;
m = q; k = q;
while (d[m] != '>') m = m - 1;
m = m + 1;
while (m != q) {
d[n] = d[m]; m = m + 1; n = n + 1;
}
d[n] = '#';
for (j = 3; e[j] != '#'; j++) {
d[n] = e[j];
n = n + 1;
}
k = k + 1;
while (d[k] != '=') {
d[n] = d[k]; n = n + 1; k = k + 1;
}
d[n] = '#';
}