编译原理实验二语法分析器LL1实现精选.docx

上传人:b****8 文档编号:8959329 上传时间:2023-02-02 格式:DOCX 页数:21 大小:158.53KB
下载 相关 举报
编译原理实验二语法分析器LL1实现精选.docx_第1页
第1页 / 共21页
编译原理实验二语法分析器LL1实现精选.docx_第2页
第2页 / 共21页
编译原理实验二语法分析器LL1实现精选.docx_第3页
第3页 / 共21页
编译原理实验二语法分析器LL1实现精选.docx_第4页
第4页 / 共21页
编译原理实验二语法分析器LL1实现精选.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

编译原理实验二语法分析器LL1实现精选.docx

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

编译原理实验二语法分析器LL1实现精选.docx

编译原理实验二语法分析器LL1实现精选

编译原理程序设计实验报告

——表达式语法分析器的设计

班级:

计算机1306班姓名:

张涛学号:

20133967

实验目标:

用LL

(1)分析法设计实现表达式语法分析器

实验内容:

⑴概要设计:

通过对实验一的此法分析器的程序稍加改造,使其能够输出正确的表达式的token序列。

然后利用LL

(1)分析法实现语法分析。

⑵数据结构:

intop=0;//当前判断进度

charch;//当前字符

charnowword[10]="";//当前单词

charoperate[4]={'+','-','*','/'};//运算符

charbound[2]={'(',')'};//界符

structToken

{

intcode;

charch[10];

};//Token定义

structTokentokenlist[50];//Token数组

structTokentokentemp;//临时Token变量

structStack//分析栈定义

{

char*base;

char*top;

intstacksize;

};

⑶分析表及流程图

⑷关键函数:

intIsLetter(charch)//判断ch是否为字母

intIsDigit(charch)//判断ch是否为数字

intIskey(char*string)//判断是否为关键字

intIsbound(charch)//判断是否为界符

intIsboundnum(charch)//给出界符所在token值

intinit(STack*s)//栈初始化

intpop(STack*s,char*ch)//弹栈操作

intpush(STack*s,charch)//压栈操作

voidLL1();//分析函数

源程序代码:

(加入注释)

#include

#include

#include

#include

#include

 

intop=0;//当前判断进度

charch;//当前字符

charnowword[10]="";//当前单词

charoperate[4]={'+','-','*','/'};//运算符

charbound[2]={'(',')'};//界符

structToken

{

intcode;

charch[10];

};//Token定义

structTokentokenlist[50];//Token数组

structTokentokentemp;//临时Token变量

structStack//分析栈定义

{

char*base;

char*top;

intstacksize;

};

typedefstructStackSTack;

intinit(STack*s)//栈初始化

{

(*s).base=(char*)malloc(100*sizeof(char));

if(!

(*s).base)

exit(0);

(*s).top=(*s).base;

(*s).stacksize=100;

printf("初始化栈\n");

return0;

}

intpop(STack*s,char*ch)//弹栈操作

{

if((*s).top==(*s).base)

{

printf("弹栈失败\n");

return0;

}

(*s).top--;

*ch=*((*s).top);

printf("%c",*ch);

return1;

}

intpush(STack*s,charch)//压栈操作

{

if((*s).top-(*s).base>=(*s).stacksize)

{

(*s).base=(char*)realloc((*s).base,((*s).stacksize+10)*sizeof(char));

if(!

(*s).base)

exit(0);

(*s).top=(*s).base+(*s).stacksize;

(*s).stacksize+=10;

}

*(*s).top=ch;

*(*s).top++;

return1;

}

voidLL1();

intIsLetter(charch)//判断ch是否为字母

{

inti;

for(i=0;i<=45;i++)

if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))

return1;

return0;

}

intIsDigit(charch)//判断ch是否为数字

{

inti;

for(i=0;i<=10;i++)

if(ch>='0'&&ch<='9')

return1;

return0;

}

intIsbound(charch)//判断是否为界符

{

inti;

for(i=0;i<2;i++)

{

if(ch==bound[i])

{

returni+1;

}

}

return0;

}

intIsoperate(charch)//判断是否为运算符

{

inti;

for(i=0;i<4;i++)

{

if(ch==operate[i])

{

returni+3;

}

}

return0;

}

intmain()

{

FILE*fp;

intq=0,m=0;

charsour[200]="";

printf("请将源文件置于以下位置并按以下方式命名:

F:

\\2.txt\n");

if((fp=fopen("F:

\\2.txt","r"))==NULL)

{

printf("文件未找到!

\n");

}

else{

while(!

feof(fp)){

if(isspace(ch=fgetc(fp)));

else{

sour[q]=ch;

q++;

}

}

}

intp=0;

printf("输入句子为:

\n");

for(p;p<=q;p++)

{

printf("%c",sour[p]);

}

printf("\n");

intstate=0,nowlen=0;

BOOLEANOK=TRUE,ERR=FALSE;

inti,flagpoint=0;

for(i=0;i

{

if(sour[i]=='#')

tokenlist[m].code=='#';

switch(state)

{

case0:

ch=sour[i];

if(Isbound(ch))

{

if(ERR)

{

printf("无法识别\n");

ERR=FALSE;

OK=TRUE;

}

elseif(!

OK)

{

printf("<10,%s>标识符\n",nowword);

tokentemp.code=10;

tokentemp.ch[10]=nowword[10];

tokenlist[m]=tokentemp;

m++;

OK=TRUE;

}

state=4;

}

elseif(IsDigit(ch))

{

if(OK)

{

memset(nowword,0,strlen(nowword));

nowlen=0;

nowword[nowlen]=ch;

nowlen++;

state=3;

OK=FALSE;

break;

}else

{

nowword[nowlen]=ch;

nowlen++;

}

}

elseif(IsLetter(ch))

{

if(OK)

{

memset(nowword,0,strlen(nowword));

nowlen=0;

nowword[nowlen]=ch;

nowlen++;

OK=FALSE;

}else

{

nowword[nowlen]=ch;

nowlen++;

}

}

elseif(Isoperate(ch))

{

if(!

OK)

{

printf("<10,%s>标识符\n",nowword);

tokentemp.code=10;

tokentemp.ch[10]=nowword[10];

tokenlist[m]=tokentemp;

m++;

OK=TRUE;

}

printf("<%d,%c>运算符\n",Isoperate(ch),ch);

tokentemp.code=Isoperate(ch);

tokentemp.ch[10]=ch;

tokenlist[m]=tokentemp;

m++;

}

break;

case3:

if(IsLetter(ch))

{

printf("错误\n");

nowword[nowlen]=ch;

nowlen++;

ERR=FALSE;

state=0;

break;

}

if(IsDigit(ch=sour[i]))

{

nowword[nowlen]=ch;

nowlen++;

}

elseif(sour[i]=='.'&&flagpoint==0)

{

flagpoint=1;

nowword[nowlen]=ch;

nowlen++;

}

else

{

printf("<20,%s>数字\n",nowword);

i--;

state=0;

OK=TRUE;

tokentemp.code=20;

tokentemp.ch[10]=nowword[10];

tokenlist[m]=tokentemp;

m++;

}

break;

case4:

i--;

printf("<%d,%c>界符\n",Isbound(ch),ch);

tokentemp.code=Isbound(ch);

tokentemp.ch[10]=ch;

tokenlist[m]=tokentemp;

m++;

state=0;

OK=TRUE;

break;

}

}

printf("tokenlist值为%d\n",m);

intt=0;

tokenlist[m+1].code='r';

m++;

for(t;t

{

printf("tokenlist%d值为%d\n",t,tokenlist[t].code);

}

LL1();

printf("tokenlist值为%d\n",m);

if(op+1==m)

printf("OK!

!

!

");

else

printf("WRONG!

!

!

");

return0;

}

voidLL1()

{

STacks;

init(&s);

push(&s,'#');

push(&s,'E');

charch;

intflag=1;

do

{

pop(&s,&ch);

printf("输出栈顶为%c\n",ch);

printf("输出栈顶为%d\n",ch);

printf("当前p值为%d\n",op);

if((ch=='(')||(ch==')')||(ch=='+')||(ch=='-')||(ch=='*')||(ch=='/')||(ch==10)||(ch==20))

{

if(tokenlist[op].code==1||tokenlist[op].code==20||tokenlist[op].code==10||tokenlist[op].code==2||tokenlist[op].code==3||tokenlist[op].code==4||tokenlist[op].code==5||tokenlist[op].code==6)

op++;

else

{

printf("WRONG!

!

!

");

exit(0);

}

}

elseif(ch=='#')

{

if(tokenlist[op].code==0)

flag=0;

else

{

printf("WRONG!

!

!

@@@@@@@@@");

exit(0);

}

}

elseif(ch=='E')

{

printf("进入E\n");

if(tokenlist[op].code==10||tokenlist[op].code==20||tokenlist[op].code==1)

{

push(&s,'R');

printf("将R压入栈\n");

push(&s,'T');

}

}

elseif(ch=='R')

{

printf("进入R\n");

if(tokenlist[op].code==3||tokenlist[op].code==4)

{

push(&s,'R');

push(&s,'T');

printf("将T压入栈\n");

push(&s,'+');

}

if(tokenlist[op].code==2||tokenlist[op].code==0)

{

}

}

elseif(ch=='T')

{

printf("进入T\n");

if(tokenlist[op].code==10||tokenlist[op].code==20||tokenlist[op].code==1)

{

push(&s,'Y');

push(&s,'F');

}

}

elseif(ch=='Y')

{

printf("进入Y\n");

if(tokenlist[op].code==5||tokenlist[op].code==6)

{

push(&s,'Y');

push(&s,'F');

push(&s,'*');

}

elseif(tokenlist[op].code==3||tokenlist[op].code==2||tokenlist[op].code==0||tokenlist[op].code==4)

{

}

}

elseif(ch=='F')

{

printf("进入F\n");

if(tokenlist[op].code==10||tokenlist[op].code==20)

{

push(&s,10);

}

if(tokenlist[op].code==1)

{

push(&s,')');

push(&s,'E');

push(&s,'(');

}

}

else

{

printf("WRONG!

!

!

!

");

exit(0);

}

}while(flag);

}

程序运行结果:

(截屏)

输入:

((Aa+Bb)*(88.2/3))#

注:

如需运行请将文件放置F盘,并命名为:

2.txt

输出:

思考问题回答:

LL

(1)分析法的主要问题就是要正确的将文法化为LL

(1)文法。

在程序实现时将分析表的动作逐一实现即可。

最新文件仅供参考已改成word文本。

方便更改

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

当前位置:首页 > 总结汇报 > 学习总结

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

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