编译原理实验二语法分析器LL1实现.docx
- 文档编号:24525314
- 上传时间:2023-05-28
- 格式:DOCX
- 页数:21
- 大小:168.74KB
编译原理实验二语法分析器LL1实现.docx
《编译原理实验二语法分析器LL1实现.docx》由会员分享,可在线阅读,更多相关《编译原理实验二语法分析器LL1实现.docx(21页珍藏版)》请在冰豆网上搜索。
编译原理实验二语法分析器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)文法。 在程序实现时将分析表的动作逐一实现即可。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理 实验 语法 分析器 LL1 实现