编译原理实验LL1分析法综述.docx
《编译原理实验LL1分析法综述.docx》由会员分享,可在线阅读,更多相关《编译原理实验LL1分析法综述.docx(12页珍藏版)》请在冰豆网上搜索。
编译原理实验LL1分析法综述
编译原理程序设计实验报告
——表达式语法分析器的设计实现
班级:
计算机1306班姓名:
王利达学号:
20133959
实验目标:
使用LL
(1)分析法构造表达式语法分析器程序,判别算术表达式,给出判别结果。
实验内容:
一、概要设计
1.算术表达式文法:
E→T|Eω0T
T→F|Tω1F
F→i|(E)
其中ω0:
+-
ω1:
*/
i:
数字或常数
文法变换:
E→TM
M→ω0TM|ε
T→F|N
N→ω1FN|ε
F→i|(E)
其中ω0:
+-
ω1:
*/
i:
数字或常数
2.LL
(1)分析表
表1.LL
(1)分析表
i
+
-
*
/
(
)
#
E
MT,p
MT,p
M
MT,n
MT,n
ε,p
ε,p
T
NF,p
NF,p
N
NF,n
NF,n
ε,p
ε,p
F
ε,n
)E,n
)
ε,n
#
OK
二、数据结构
1.输入表达式
定义char型数组expstr为存放输入表达式的数组,
charexpstr[100];
2.分析栈
定义一个栈来进行LL
(1)分析。
栈中有bottom、top、stacksize等元素,用于程序调用栈和对栈操作。
typedefstruct//定义语法的栈
{
SElemType*bottom;//底
SElemType*top;//顶
intstacksize;
}SqStack;
(包括:
概要设计、数据结构、流程图、关键函数等
有选择填写)
源程序代码:
(加入注释)
#include
#include
#include
usingnamespacestd;
#defineSTACKSIZE30//栈大小
#defineSTACKINCREMENT10//栈增量
#defineOK1
#defineError0
#defineOVERFLOW-1
typedefcharSElemType;
typedefintStatus;
inti=0;
intcount1=0;
intcount2=0;//计数终结符的个数
charexpstr[100];
typedefstruct//定义语法的栈
{
SElemType*bottom;//底
SElemType*top;//顶
intstacksize;
}SqStack;
StatusInitStack(SqStack&S)//初始化栈
{
S.bottom=(SElemType*)malloc(STACKSIZE*sizeof(SElemType));
if(!
S.bottom)
exit(OVERFLOW);
S.top=S.bottom;
S.stacksize=STACKSIZE;
returnOK;
}
StatusPUSH(SqStack&S,SElemTypee)
{
if(S.top-S.bottom>=S.stacksize)
{
S.bottom=(SElemType*)realloc(S.bottom,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!
S.bottom)
exit(OVERFLOW);
S.top=S.bottom+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*(S.top)=e;
(S.top)++;
returnOK;
}
StatusPOP(SqStack&S,SElemType&e)
{
if(S.top==S.bottom)
returnError;
S.top--;
e=*(S.top);
returnOK;
}
voidwrong()//调用此函数,表示出错
{
cout<<"Wrong!
"<getchar();
exit(0);
}
boolch_judge(chars[],intn)//字符是否合法
{
if((s[n]=='(')||(s[n]==')')||(s[n]>='0'&&s[n]<='9')||(s[n]>='a'&&s[n]<='z')||(s[n]=='+')||(s[n]=='-')||(s[n]=='*')||(s[n]=='/')||(s[n]=='#'))
return1;
else
return0;
}
boolter_judge(charc)//终结符集合与非终结符集合
{
if((c=='(')||(c==')')||(c>='0'&&c<='9')||(c>='a'&&c<='z')||(c=='+')||(c=='-')||(c=='*')||(c=='/'))
return1;//终结符返回1
else//if(c=='E'||c=='E1'||c=='T'||c=='T1'||c=='F')
return0;//非终结符或#,返回0
}
boolnum_letter(chars[],inti)//判断当前字符是数字还是字母
{
if((s[i]>='0'&&s[i]<='9')||(s[i]>='a'&&s[i]<='z'))
{
i++;
while((s[i]>='0'&&s[i]<='9')||(s[i]>='a'&&s[i]<='z'))
{
i++;
count1++;
}
while(count1!
=0)
{
i--;
count1--;
}
i--;
return1;//是字母或数字返回1
}
else
return0;//不是字母或数字返回0
}
voidLL1(SqStack&S,chars[],inti)//LL1文法分析函数
{
SElemTypee;
PUSH(S,'#');
PUSH(S,'E');
while(s[i]!
='#')
{
if(ch_judge(s,i))
{
POP(S,e);
if(!
(ter_judge(e)))//是非终结符
{
if(e=='#'&&s[i]=='#')
break;//表达式正确
elseif(e=='#'&&s[i]!
='#')
wrong();
elseif(e!
='#')//分析表匹配
{
switch(e)
{
case'E':
if(num_letter(s,i)||s[i]=='(')
{
e='M';//E'M
PUSH(S,e);
e='T';
PUSH(S,e);
break;
}
else
wrong();
case'M':
if(s[i]=='+'||s[i]=='-')
{
e='M';
PUSH(S,e);
e='T';
PUSH(S,e);
e=s[i];
PUSH(S,e);
break;
}
elseif(s[i]==')'||s[i]=='#')
{
break;
}
else
wrong();
case'T':
if(num_letter(s,i)||s[i]=='(')
{
e='N';//T'N
PUSH(S,e);
e='F';
PUSH(S,e);
break;
}
else
wrong();
case'N':
if(s[i]=='+'||s[i]=='-'||s[i]==')'||s[i]=='#')
{
break;
}
elseif(s[i]=='*'||s[i]=='/')
{
e='N';
PUSH(S,e);
e='F';
PUSH(S,e);
e=s[i];
PUSH(S,e);
break;
}
else
wrong();
case'F':
if(num_letter(s,i))
{
while((s[i]>='0'&&s[i]<='9')||(s[i]>='a'&&s[i]<='z'))//将连续的终结符压栈
{
e=s[i];
PUSH(S,e);
i++;
count2++;//给连续终结符计数
}
i--;//使s[i]为连续终结符即一个整数的最后一字
break;
}
elseif(s[i]=='(')
{
e=')';
PUSH(S,e);
e='E';
PUSH(S,e);
e='(';
PUSH(S,e);
break;
}
else
wrong();
default:
wrong();
}
}
}
else
{
if((s[i]>='0'&&s[i]<='9')||(s[i]>='a'&&s[i]<='z'))//如果是数字或字母则依次计数
{
while(ter_judge(e))
{
if(e==s[i])
{
i--;
POP(S,e);
}
else
wrong();
}
while(count2!
=0)
{
i++;
count2--;
}
PUSH(S,e);
i++;
}
else//如果是+-*/则直接比较
{
if(e==s[i])
i++;
else
wrong();
}
}
}
else
wrong();
}
}
intmain()
{
SqStackS;
InitStack(S);
cout<<"LL
(1)\nPleaseentertheexpressionandendwiththe\"#\":
"<cin>>expstr;
LL1(S,expstr,i);
cout<<"Right!
"<getchar();
return0;
}
程序运行结果:
(截屏)
图1.正确的算术表达式(((a+b)*(c/B)))的判断
图2.错误的算术表达式a/b++的判断
思考问题回答:
(如果有)
LL
(1)分析法和递归下降子程序法在语法分析中同属于自顶向下分析法,LL
(1)分析法相对于递归下降子程序法的优势是:
LL
(1)分析法消除了文法的左递归性,而且克服了回溯,使程序运行的效率大大提升。