编译原理实验LL1分析法综述.docx

上传人:b****6 文档编号:7158552 上传时间:2023-01-21 格式:DOCX 页数:12 大小:38.54KB
下载 相关 举报
编译原理实验LL1分析法综述.docx_第1页
第1页 / 共12页
编译原理实验LL1分析法综述.docx_第2页
第2页 / 共12页
编译原理实验LL1分析法综述.docx_第3页
第3页 / 共12页
编译原理实验LL1分析法综述.docx_第4页
第4页 / 共12页
编译原理实验LL1分析法综述.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

编译原理实验LL1分析法综述.docx

《编译原理实验LL1分析法综述.docx》由会员分享,可在线阅读,更多相关《编译原理实验LL1分析法综述.docx(12页珍藏版)》请在冰豆网上搜索。

编译原理实验LL1分析法综述.docx

编译原理实验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)分析法消除了文法的左递归性,而且克服了回溯,使程序运行的效率大大提升。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 解决方案

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1