内容简介:
一、设计目的
了解用算符优先法对表达进行语法分析的方法,掌握自顶向下的预测语法分析程序的手工构造方法。
二、设计内容
对简单表达式文法构造算符优先分析器。
三、设计要求
1、对下列简单表达式文法G[ E’]构造算符优先关系表。
E’ →# E #
E → E + T | T
T → T * F | F
F → P / F |P
P → ( E )|i
2、根据算符优先关系表,使用栈结构来实现算符优先分析:设置两个栈:存放运算符的OPTR栈和存放操作数或运算结果的OPND栈。具体算法描述如下:
(1)首先置操作数OPND栈为空栈,将#入运算符OPTR栈。
(2)依次读入表达式中每个单词,若是操作数则进OPND栈,若是运算符则转(3)。
(3)当前设读入的运算符为θ2,查找算符优先关系表,比较θ2与OPTR栈顶元素θ1 :
若θ1﹤θ2,则θ2进OPTR栈,转(2);
若θ1=θ2, 如θ2为#,则分析成功,否则OPTR栈顶元素θ1出栈,并转(2);
若θ1>θ2,则出栈OPND栈顶元素存放到b,又出栈其新栈顶元素存放到a,再出栈OPTR栈顶元素至t,进行运算r=a t b (t为运算符),并将结果r存入栈OPND后转(2);
(4)若θ1和θ2之间无优先关系,则报错。
从键盘输入表达式,利用算符优先法求出其值,如输入表达式有错,则给出报错提示。表达式以“#”结尾。
四、运行结果
1、从键盘输入表达式串: 10+15*4#
输出: 70
2、从键盘输入表达式串:10+*15+
输出: The expression is error!
五、提示
构造算符优先关系表如下:
+-*/()i#
+﹥﹥﹤﹤﹤﹥﹤﹥
-﹥﹥﹤﹤﹤﹥﹤﹥
*﹥﹥﹥﹥﹤﹥﹤﹥
/﹥﹥﹥﹥﹤﹥﹤﹥
(﹤﹤﹤﹤﹤=﹤
)﹥﹥﹥﹥﹥﹥
i﹥﹥﹥﹥﹥﹥
#﹤﹤﹤﹤﹤﹤=
参考严蔚敏等编著、清华大学出版社出版的C语言版《数据结构》P52-P54的表达式求值算法。
基于算符优先分析方法的表达式语法分析器
【设计目的】
了解用算符优先法对表达进行语法分析的方法,掌握自顶向下的预测语法分析程序的手工构造方法。
【设计内容】
对简单表达式文法构造算符优先分析器。
【设计要求】
对下列简单表达式文法G[ E],构造算符优先关系表。
E’ →# E #
E → E + T | T
T → T * F | F
F → P / F |P
P → ( E )|i
2、根据算符优先关系表,使用栈结构来实现算符优先分析:设置两个栈:存放运算符的OPTR栈和存放操作数或运算结果的OPND栈。具体算法描述如下:
(1)首先置操作数OPND栈为空栈,将#入运算符OPTR栈。
(2)依次读入表达式中每个单词,若是操作数则进OPND栈,若是运算符则转(3)。
(3)当前设读入的运算符为θ2,查找算符优先关系表,比较θ2与OPTR栈顶元素θ1 :
若θ1﹤θ2,则θ2进OPTR栈,转(2);
若θ1=θ2, 如θ2为#,则分析成功,否则OPTR栈顶元素θ1出栈,并转(2);
若θ1>θ2,则出栈OPND栈顶元素存放到b,又出栈其新栈顶元素存放到a,再出栈OPTR栈顶元素至t,进行运算r=a t b (t为运算符),并将结果r存入栈OPND后转(2);
(4)若θ1和θ2之间无优先关系,则报错。
3、从键盘输入表达式,利用算符优先法求出其值,如输入表达式有错,则给出报错提示。表达式以“#”结尾。
【算法思想】
本题采用算符优先关系表对一个表达式进行求值,首先我们根据文法构造算符优先关系表。如上文所说,构造两个栈:存放运算符的OPTR栈和存放操作数或运算结果的OPND栈。首先置操作数OPND栈为空栈,将#入运算符OPTR栈。
依次读入表达式中每个单词,若是操作数则进OPND栈,若是运算符,则将其与OPTR栈顶运算符比较优先关系,对于不同的情况做出不同处理。在此过程中,若出现左右括号不匹配,操作数栈的元素参加运算数目不够等情况则报错。
【变量与函数说明】
数据结构的定义:
1、int table[7][7]://存放算符优先关系表的二维数组
2、存放运算符的OPTR栈:
typedef struct optr
{
int mem[10];
int top;
int bottom;
int sizemax;
}*OPTR;
3、存放操作数或运算结果的OPND栈:
typedef struct opnd
{
int mem[10];
int top;
int bottom;
int sizemax;
}*OPND;
函数说明:
1、OPTR栈的相关操作函数:
OPTR OPTRInit();int OPTRPop(OPTR s);void OPTRPush(int s,OPTR S)
2、OPND栈的相关操作函数:
OPND OPNDInit();int OPNDPop(OPTR s);void OPNDPush(int s,OPND S)
3、void main()
主函数主要实现以下任务:
首先置操作数OPND栈为空栈,将#入运算符OPTR栈;
读取字符串,提取字符串中的数字, 进OPND栈;
剩余的是运算符或括号,分别进行处理:将栈顶操作符与当前操作符进行优先对比,
都为#,分析成功,打印结果。
若栈顶操作符>当前操作符,则出栈OPND栈顶元素存放到i,又出栈其新栈顶元素存放到j,根据不同运算符进行计算并将结果r存入栈OPND。
若栈顶操作符﹤当前操作符,则将当前操作符入栈OPTR。
若栈顶操作符与当前操作符没有优先关系,报错。
【实验源代码】
#include ﹤stdio.h﹥
#include ﹤string.h﹥
#include ﹤ctype.h﹥
#include ﹤stdlib.h﹥
#define add 0
#define mim 1
#define mul 2
#define div 3
#define zuokuo 4
#define youkuo 5
#define end 6 //各个符号在算符优先关系表二维数组中的行号或列号
。。。。。。。。。
/*******存放运算符的OPTR栈的结构定义和相关操作函数******** */
typedef struct optr
{
int mem[10];
int top;
int bottom;
int sizemax;
}*OPTR;
OPTR OPTRInit()
{
OPTR s;
s=(OPTR)malloc(sizeof(struct optr));
s-﹥top=s-﹥bottom=-1;
return s;
}
int OPTRPop(OPTR s)
{
int i;
if(s-﹥top==-1) printf("The eession is error!There is no element in OPTR\n");
else
{
s-﹥top--;
i=s-﹥top+1;
i=s-﹥mem[i];
return i;
}
}
void OPTRPush(int s,OPTR St)
{
int i;
if(St-﹥top==9)printf("the OPTR is full\n");
else
{
St-﹥top++;
i=St-﹥top;
St-﹥mem[i]=s;
}
}
/************存放操作数或运算结果的OPND栈的结构定义和相关操作函数***********/
typedef struct opnd
{
int mem[10];
int top;
int bottom;
int sizemax;
}*OPND;
OPND OPNDInit()
{
OPND s;
s=(OPND)malloc(sizeof(struct opnd));
s-﹥top=s-﹥bottom=-1;
return s;
}
int OPNDPop(OPND s)
{
int i;
int j;
if(s-﹥top==-1)printf("The eession is error!There is no element in OPND\n");
else
{
s-﹥top--;
i=s-﹥top+1;
j=s-﹥mem[i];
return j;
}
}
void OPNDPush(int s,OPND St)
{
int i;
if(St-﹥top==9) printf("the OPND is full\n");
else
{
St-﹥top++;
i=St-﹥top;
St-﹥mem[i]=s;
}
}
void error( char *m) /**错误输出函数**/
{
printf("%s\n",m);
exit(1);
}
【运行结果】
相关说明:
1、下载本站部分资料,需要注册成为本站会员。如果你尚未注册或登录,请首先注册或登录。
2、48小时内下载同一文件,不重复扣金币。
3、下载后请用WinRAR或WinZIP解压缩后使用。
4、如采用迅雷等下载工具下载失败,请直接用浏览器下载。
5、如仍有其他下载问题,请看常见问题解答。
下载地址: