一.前言
今天又是一周一例的编译原理课,此次实验是实现算术表达式的部分功能(也可以说全部功能)。我花了2.3小时干完了!感觉干完了,仿佛没有了灵魂了。没有上次干词法分析那么有灵魂。没有什么快感。嗯嗯,就这样干完了。行了,废话不多说。直接上正餐。
(因为要写大学生必备实验报告,截图就是白底黑字)
二.内容要求
一、授课内容:
(一) 授课科目:编译原理
(二) 授课内容:实验二 递归下降分析程序设计
(三) 授课类型:实 验
二、教学目的要求:
1.目的:通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析方法。
2.要求:
(1) 选择最有代表性的语法分析方法,算符优先法、递归子程序法和状态矩阵法之一进行实验。
(2) 选择对各种常见的程序语言都通用的语法结构,如赋值语句(尤其指表达式)作为分析对象,并且与所选语法分析方法要比较贴切。
三、教学设想:
1.教学方法设想:先以例子讲解,然后学生动手实验,实验为主。
2.教具运用设想:多媒体。
四、教学过程:
1.题目
题目 编写一个递归下降子程序,实现加减乘除算术表达式的判断。 试采用具有递归功能的高级语言(如PASCAL等等)编制递归下降法的语法分析程序,并用它对FORTRAN语言算术表达式的一个简化子集进行语法分析。分析过程不嵌入任何语义动作。
分析对象的BNF定义如下:
〈算术表达式〉::=〈项〉|〈算术表达式〉+〈项〉|〈算术表达式〉-〈项〉
〈项〉::=〈因式〉|〈项〉*〈因式〉|〈项〉/〈因式〉
〈因式〉::=〈变量〉| (〈算术表达式〉)
〈变量〉::=〈字母〉
〈字母〉::=A|B|C|D|E|f|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z
三.实现的功能和代码
功能1.不加“#”也能判断,系统自动给用户输入的加“#”
截图:
功能2.可以识别小数和整数
功能3.可以识别标识符
功能4.可以错误定位(采取程序员计算数法,默认从0开始)
大写字母在编译原理一律认为是非终结符号。
代码:
#include <stdio.h>
#include<string.h>
int p,tz,i;//tz错误标志位,1表示有错
char st[80];//字符串
char ch;//每次取的字符
int flag;
char sym()//取下一个字符
{
return st[p];
}
void error(int n)//报错
{
printf("error%d\n",n);
}
void f() // F->i|(E)
{
void e();
void t();
char sym();
flag=1;//一次只能是一类,小数|整数|小写字母|标识符|算法表达式 |
ch=sym();
if((ch>='a'&&ch<='z'||ch=='_')&&flag){//识别标识符
flag=0;
while(ch>='a'&&ch<='z'||ch=='_'||ch>='0'&&ch<='9'){
p++;
ch=sym();
}
}
else if(ch>='a'&&ch<='z'&&flag)//识别小写字母
{
p++;
flag=0;
}
else if(ch >='0'&&ch<='9'||ch=='.'&&flag)//识别数(小数和整数) 新增功能
{
flag=0;
while(ch >='0'&&ch<='9')//识别整数
{
p++;
ch=sym();
}
if(ch=='.'){//识别小数
p++;
ch=sym();
while(ch >='0'&&ch<='9')
{
p++;
ch=sym();
}
}
}
else if(ch=='('&&flag)//识别算术表达式
{
flag=0;
p++;
e();
if(ch==')')
p++;
else{
error(p);
tz=1;
}
}
else //不是项或算数表达式
{
error(p);
tz=1;
}
}//end of f
void t() //T->F{*F|/F}
{
void f();
f();
ch=sym();
while(ch=='*'||ch=='/')
{
p++;
f();
ch=sym();
}
}
void e() //E->T{+T|-T}
{
t();
ch=sym();
while(ch=='+'||ch=='-')
{
p++;
t();
ch=sym();
}
}
void main()
{
printf("please input expression (end with #):");
gets(st);
strcat(st,"#");
p=0;
ch=sym();
/* if(ch=='#')
{
printf("finished\n");
//exit();
return ;
}*/
while(ch!='#')//循环,以#结束程序
{
e();
if(ch!='#'||tz==1)
{
printf("error,again\n");
tz=0;
}
else printf("right,again!\n");
printf("please input expression (end with #):");
fflush(stdin);
gets(st);
strcat(st,"#");
p=0;
ch=sym();
}
printf("finished\n");
}