表达式语法分析设计
一、 实验目的:
熟悉并设计一个表达式的语法分析器
二、实验内容:
1.设计表达式的语法语法分析器算法
2.编写代码并上机调试运行通过
要求: 输入------------ 表达式
输出------------ 表达式语法是否正确
三、 设计概要:
运用算术表达式的 LL(1) 分析算法来设计的表达式的语法分析器。
LL(1)文法是一种自上而下的语法分析方法,它是从文法的识别符
号出发,生成句子的最左推导,从左到右扫描源程序,每次向前查看 1
个字符,便能确定当前应该选择的产生式。
LL(1)分析需要用到一个分析表 M 和一个符号栈 S,分析表 M 是
一个矩阵,它的元素可以存放一个非终结符的产生式,表明当符号栈 S
的栈顶元素非终结符遇到当前输入字符时,所应选择的产生式;M 的元
素还可以是存放一个出错标志,说明符号栈 S 的栈顶元素非终结符不应
该遇到当前输入字符(终结符)。
重复调用 LL(1)分析方法对每一个输入字符进行分析,直到输入栈
为空为止。
四、 源程序(包含注释)
“stack.h”//栈的定义
#define STACK_INIT_SIZE 10 // 存储空间初始分配量
#define STACKINCREMENT 2 //存储空间分配增量
typedef struct
{
char *base;
char *top;
int stacksize;
}SqStack; // 顺序栈
void InitStack(SqStack *S)
{ //构造一个空栈 S
(*S).base=(char *)malloc(STACK_INIT_SIZE*sizeof(char));
if(!(*S).base)
exit(-2); //存储分配失败
(*S).top=(*S).base;
(*S).stacksize=STACK_INIT_SIZE;
}
*)realloc((*S).base,((*S).stacksize+STACKINCREMENT)*sizeof(char));
void Push(SqStack *S,char e)
{ //插入元素 e 为新的栈顶元素
if((*S).top-(*S).base>=(*S).stacksize)
{
(*S).base=(char
if(!(*S).base)
exit(-2);
(*S).top=(*S).base+(*S).stacksize;
(*S).stacksize+=STACKINCREMENT;
}
*((*S).top)++=e;
void Pop(SqStack *S,char *e)
{ //若栈不空,则删除 S 的栈顶元素,用 e 返回其值,并返回 OK;否则返回 ERROR
if((*S).top==(*S).base)
printf("stack is empty!");
*e=*(--(*S).top);
int GetTop(SqStack S,char *e)
{ //若栈不空,则用 e 返回 S 的栈顶元素,并返回 OK;否则返回 ERROR
}
}
}
if(S.top>S.base)
{
*e=*(S.top-1);
return 1;
}
else
return 0;
“LL1.c”//LL(1)语法分析器
#include
#include
#include
#include"stack.h"
#define MAXLENGTH 50
typedef enum{E,G,T,S,F}nofinal;
typedef enum{i,add,mul,lp,rp,$}final;
char *M[5][6]={
SqStack Sq;
"E->TG","error","error","E->TG","error","error",
"error","G->+TG","error","error","G->#","G->#",
"T->FS","error","error","T->FS","error","error",
"error","S->#","S->*FS","error","S->#","S->#",
"F->i","error","error","F->(E)","error","error"
};
int isfinalsymbol(char top)
{
//是否为终结符
if ((top=='i')||(top=='+')||(top=='*')||(top=='(')||
(top==')')||(top=='$'))
else
return 1;
return 0;
}
void analyze(char *M[5][6],char *p) //作预测分析
{
//记录栈顶元素
char top;
char *temp;
char *a;
nofinal nf;
final fl;
a=p;
GetTop(Sq,&top);
//取栈顶元素
while(top!='$')
{
if(top=='#')
{
//为空
Pop(&Sq,&top);
}
else if(isfinalsymbol(top)||(top=='$'))
{
//栈顶是终结符
if(top==*a)
{
Pop(&Sq,&top);
a++;
printf("表达式语法不正确,程序退出.");
getchar();
exit(1);
}
else
{
}
}
else
{
printf("表达式语法不正确!");
getchar();
exit(1);
//栈顶不是终结符
if(top=='E')
nf=E;
else if(top=='G')
nf=G;
nf=T;
nf=S;
else if(top=='T')
else if(top=='S')
else if(top=='F')
nf=F;
if(*a=='i')
fl=i;
else if(*a=='+')
fl=add;
else if(*a=='*')
fl=mul;
else if(*a=='(')
else if(*a==')')
else if(*a=='$')
fl=lp;
fl=rp;
fl=$;
else
{
}
if(strcmp(M[nf][fl],"error")!=0)
{
Pop(&Sq,&top);
temp=strrev(strdup(M[nf][fl])); //反序进栈
while(*temp!='>')
{
Push(&Sq,*temp);
temp++;
}
}
else
{
}
}
printf("表达式语法不正确!");
getchar();
exit(1);
GetTop(Sq,&top);
//取栈顶元素
}
}
int main()
{
nofinal n;
final f;
char exp[MAXLENGTH];
InitStack(&Sq);
Push(&Sq,'$');
Push(&Sq,'E');
//进栈
//进栈
list:
符):\n",MAXLENGTH);
printf(" 输 入 一 个 表 达 式 可 以 包 含 (+,*,(,),i) 以 $ 结 束 ( 不 超 过 %d 个 字
gets(exp);
if(strlen(exp)>MAXLENGTH||(strstr(exp,"$")==NULL))
{
printf("字符过长或者没有以$结束,请重新输入\n");
goto list;
}
analyze(M,exp);
printf("表达式语法正确!");
getchar();
return 0;
}
五、 测试数据及运行结果:
六、 思考题:
语法分析的任务是什么?
答:语法分析的任务是在词法分析的基础上将单词序列组合成各类语法短
语,语法分析程序判断源程序在结构上是否正确。