编译原理词法分析器语法分析器实验报告.docx
- 文档编号:8966202
- 上传时间:2023-05-16
- 格式:DOCX
- 页数:21
- 大小:388.93KB
编译原理词法分析器语法分析器实验报告.docx
《编译原理词法分析器语法分析器实验报告.docx》由会员分享,可在线阅读,更多相关《编译原理词法分析器语法分析器实验报告.docx(21页珍藏版)》请在冰点文库上搜索。
编译技术
班
级
网络 0802
学
号3080610052
姓名
叶晨舟
指导老师 朱 玉 全
2011年7 月4日
一、目的
编译技术是理论与实践并重的课程, 而其实验课要综合运用一、 二年级所学的多门课程
的内容,用来完成一个小型编译程序。
从而巩固和加强对词法分析、语法分析、语义分析、代码生成和报错处理等理论的认识和理解;培养学生对完整系统的独立分析和设计的能力,进一步培养学生的独立编程能力。
二、任务及要求
基本要求:
1.词法分析器 产生下述小语言的单词序列
这个小语言的所有的单词符号,以及它们的种别编码和内部值如下表:
单词符号
种别编码
助记符
内码值
DIM
1
$DIM
-
IF
2
$IF
-
DO
3
$DO
-
STOP
4
$STOP
-
END
5
$END
-
标识符
6
$ID
-
常数(整)
7
$INT
内部字符串
=
8
$ASSIGN
标准二进形式
+
9
$PLUS
-
*
10
$STAR
-
**
11
$POWER
-
,
12
$COMMA
-
(
13
$LPAR
-
)
14
$RPAR
-
对于这个小语言,有几点重要的限制:
首先,所有的关键字(如IF﹑WHILE等)都是“保留字”。
所谓的保留字的意思是,用户不得使用它们作为自己定义的标示符。
例如,下面的写法是绝对禁止的:
IF (5)=x
其次,由于把关键字作为保留字,故可以把关键字作为一类特殊标示符来处理。
也就是说,对于关键字不专设对应的转换图。
但把它们(及其种别编码)预先安排在一张表格中(此表叫作保留字表) 。
当转换图识别出一个标识符时,就去查对这张表,确定它是否为一个关键字。
再次,如果关键字、标识符和常数之间没有确定的运算符或界符作间隔,则必须至少用一个空白符作间隔(此时,空白符不再是完全没有意义的了)。
例如,一个条件语句应写为
而绝对不要写成
IFi>0i=1;
IFi>0i=1;
因为对于后者,我们的分析器将无条件地将 IFI 看成一个标识符。
这个小语言的单词符号的状态转换图,如下图:
2.语法分析器能识别由加+减-乘*除/乘方^括号()操作数所组成的算术表达式,其文法如下:
E→E+T|E-T|T
T→T*F|T/F|FF→P^F|Pp→(E)|i
使用的算法可以是:
预测分析法;递归下降分析法;算符优先分析法;
LR分析法等。
3.中间代码生成器 产生上述算术表达式的中间代码(四元式序列)
三、实现过程
给出各题目的详细算法描述,数据结构和函数说明,流程图。
开始
输入源文
件路径
否
路径是否有
效
是
打开源文件
初始化文件指针
识别指针内容
文件结束?
是
结束
否
是空格,空白或换
行吗
否
是字母吗
否
是数字吗
否
是界符吗
将字符加入字符数
否
组Word[]
是
是
是
跳过该字符
将字符加入字符数
组Word[]
将字符加
入字符数组Word[]
将字符
加入字符数组Word[]
指向下一字符
指向下一字符
是
将字符
加入字符数组
Word[]
指向下一字符
是
是字母惑数字
吗
识别指针内容
输出word
为界符
输出Word
内容为不可识别
回退
否
是数字吗
将word与关键
字表key进行匹配
否
输出word为
普通标示符
否
匹配?
输出word
为常数
指向下一字符
是
输出word
为关键字
1、词法分析器的流程图
2、语法分析器主程序图
3、中间代码生成器流程图:
四、源程序
词法分析器:
#include
#include
{
//分析表存储结构
charm[100];
}table;
tableM[100][100]; //定义分析表
typedefstructstacknode //定义栈内元素节点 (带头结点(为空)的 )
{
chardata;
structstacknode*next;
}stackk;
voidinitlink(stackk*&s)
{
//初始化新栈
s=(stackk*)malloc(sizeof(stackk));s->next=NULL;
}
voidpoplink(stackk*&s)
{
stackk*p;charv;
if(s->next!
=NULL)
{
//顶元素出栈
}
free(p);
}
p=s->next;v=p->data;
s->next=p->next;
voidpushlink(stackk*&s,charx) //新元素入栈
{
stackk*p;
p=(stackk*)malloc(sizeof(stackk));p->data=x;
p->next=s->next;s->next=p;
}
voiddisplay(stackk*s)
{
//打印 现实显示 栈内元素
stackk*p;inti=0,j;charst[100];p=s->next;
while(p!
=NULL)
{
st[i++]=p->data;p=p->next;
}
for(j=i-1;j>=0;j--)
printf("%c",st[j]);
for(j=0;j<16-i;j++) //打印对齐格式
printf("%c",'');
}
chargettop(stackk*s)
{
//返回栈顶元素值
if(s->next==NULL)return0;
else
returns->next->data;
}
intfind(charc,chararray[])
{
inti;
intflag=0;for(i=0;i<100;i++)
{
if(c==array[i])flag=1;
//查找函数,
}
returnflag;
}
intlocation(charc,chararray[])// 定位函数,指出字符所在位置
{
inti;
for(i=0;i<100;i++)
{
if(c==array[i])
returni;
}
}
voiderror()
{
//出错函数定义
printf("%15c 出错!
\n",'');
}
voidanalyse(charVn[],charVt[])
{
inti,j,m,p,q,length,t,h;charw,X;
charstr[100];opt0:
scanf("%s",str);for(i=0;i { if(! find(str[i],Vt)) { printf("输入字符串有误 ! 请重新输入! ");gotoopt0; break; } } stackk*st;initlink(st);pushlink(st,'#'); pushlink(st,Vn[0]); //#与识别符号入栈j=0; h=1; w=str[0]; printf("步骤%-12c分析栈%-24c剩余输入串%-12c所用产生式\n",'','','');opt1: printf("%-16d",h); //显示步骤 h++; display(st);X=gettop(st);poplink(st); for(intk=0;k<14+j;k++) printf("%c",''); //显示分析栈中内容 //上托栈顶符号放入 X //打印对齐格式 for(t=j;t { printf("%c",str[t]); //显示剩余字符串 } if(find(X,Vt)&&X! ='#') //分析栈的栈顶元素和剩余输入串的第一个元素相比较 { if(X==w) { printf("%15c匹配\n",X);j++; w=str[j];gotoopt1; } else error(); } else { if(X=='#') { if(X==w) { } else { } else printf("%8c是该文法的句子! \n",''); error(); p=location(X,Vn);q=location(w,Vt); char*S1="null",*S2="NULL";if(strcmp(M[p][q].m,S1)==0||strcmp(M[p][q].m,S2)==0)// 查找产生式 error(); else { charstr0[100];strcpy(str0,M[p][q].m); printf("%15c-->%s\n",X,str0); //显示对应的产生式 if(strcmp(str0,"$")==0)gotoopt1; else { length=strlen(str0); //逆序进栈for(m=length-1;m>=0;m--) { pushlink(st,str0[m]); } gotoopt1; } } } } } intmain() { inti,k,n,r; charVn[100],Vt[100],select; printf("******************************************************************\n"); printf("printf(" 对任意输入LL (1)文法的分析表,判断验证字符串是否为该文法的句子并能给出分析和演示过程。 \n"); \n"); printf("******************************************************************\n");opt2: printf("请输入各终结符( #号表示结束 )Vt[i]: \n"); for(i=0;i<100;i++) { scanf("%c",&Vt[i]); if(Vt[i]=='#') { r=i;break; } } printf("请输入非终结符个数 scanf("%d",&n);getchar(); : \n"); for(i=0;i { printf("请输入非终结符 Vn[%d]: \n",i); scanf("%c",&Vn[i]);getchar(); printf("请输入此非终结符对应各终结符的产生式右部 (null或NULL表示出错;$表示空串): \n"); for(k=0;k<=r;k++) { } } opt3: scanf("%s",M[i][k].m);getchar(); opt4: { } } printf("请输入要分析的字符串,且以 #结束: \n");analyse(Vn,Vt); printf("******************** 请选择***********************\n"); printf(" 1: 输入字符串 \n"); printf(" 2: 输入新分析表 \n"); printf(" 0: 退出 \n");printf("*************************************************\n"); cin>>select;switch(select) case'1': {gotoopt3;break;}case'2': {gotoopt2;} case'0': {break;} default: {printf(" 输入错误! 请重新选择: "); gotoopt4;break;} return0; 运行结果: 语法分析器 源程序: #include intsyn,p,m=0,n,row,sum=0; char*rwtab[20]={"dim","if","do","stop","end","and","begin","bool","case","char", "false","for","int","not","or","set","then","true","until","while" }; voidscaner() { for(n=0;n<9;n++)token[n]=NULL;ch=prog[p++]; while(ch=='') { ch=prog[p];p++; } if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')) { m=0; while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')) { token[m++]=ch;ch=prog[p++]; } token[m++]='\0';p--; syn=21;for(n=0;n<20;n++) { if(strcmp(token,rwtab[n])==0) { syn=n+1;break; } } } elseif((ch>='0'&&ch<='9')) { { sum=0;while((ch>='0'&&ch<='9')) { } } p--; sum=sum*10+ch-'0';ch=prog[p++]; syn=7+15;if(sum>32767) syn=-1; } elseswitch(ch) { case'=': syn=8+15;token[0]=ch;break;case'+': syn=9+15;token[0]=ch;break;case'*': m=0; token[m++]=ch;ch=prog[p++];if(ch=='*') { } else { } syn=11+15;token[m++]=ch; syn=10+15;p--; break; case',': syn=12+15;token[0]=ch;break;case'(': syn=13+15;token[0]=ch;break;case')': syn=14+15;token[0]=ch;break;case'#': syn=0;token[0]=ch;break;case'<': m=0;token[m++]=ch; ch=prog[p++];if(ch=='>') { syn=17+15;token[m++]=ch; } elseif(ch=='=') { } else { } syn=16+15;token[m++]=ch; syn=15+15;p--; break;case'>': m=0;token[m++]=ch; ch=prog[p++];if(ch=='=') { } else { syn=19+15;token[m++]=ch; syn=18+15;p--; } break;case': ': m=0;token[m++]=ch; ch=prog[p++];if(ch=='=') { } else { } syn=21+15;token[m++]=ch; syn=20+15;p--; break;case'/': syn=22+15;token[0]=ch;break;case'-': syn=23+15;token[0]=ch;break;case';': syn=24+15;token[0]=ch;break;default: syn=-1;break; } } voidmain() { p=0; row=1;cout< cout<<"*************************** 小 型 词 法 分 析 器 **********************************"< cout<<"请输入一段程序(以 #结束): ";do { cin.get(ch);prog[p++]=ch; } while(ch! ='#'); p=0; cout< *********************************"< cout<<" 种别编码 自身值"< { scaner(); switch(syn) { case22 : cout<<" ("< "< break; case-1: cout<<" Errorinrow"< "< default: cout<<" ("< "< } } while(syn! =0); } 运行结果: } 中间代码生成器源程序 : 表达式生成四元式递归子程序法 #include #defineDEFAULT_SIZE100 charEMachine(charw); //表达式E的自动机charTMachine(charw); //表达式T的自动机charFMachine(charw); //表达式F的自动机boolZMachine(); //表达式Z的自动机stringintToString(inta); //整形变成字符串形函数 classstack //栈类定义 { private: inttop; string*stacka;intmaxsize; public: stack(intsize=DEFAULT_SIZE); ~stack(){delete[]stacka;}voidpush(conststring&item);stringpop(void); stringgettop(void)const; boolempty(void)const{return(top==-1);} boolfull(void)const{return(top==maxsize-1);}voidclear(void){top=-1;} }; stack: : stack(intsize) { //栈类的构造函数 top=-1;maxsize=size; stacka=newstring[maxsize]; if(! stacka) { cerr<<"allocatememoryfailed."< exit (1); } } voidstack: : push(conststring&item) { //压栈操作 if(full()) { cerr<<"stackfull,cannotpush."< } top++; stacka[top]=item; } stringstack: : pop(void) { //出栈操作 if(empty()) { cerr<<"stackempty,cannotpop."< (1); } stringitem=stacka[top];top--; returnitem; } stringstack: : gettop(void)const{ if(empty()) { //取栈顶操作 cerr<<"stackempty,cannotgettop."< exit (1); } returnstacka[top]; } staticstackwordStack; //符号栈 staticintnoOfQuet=0; //静态四元式个数记录 staticintnoOfT=1; //静态状态个数记录 voidmain(){ //主函数 charyesOrNo; //
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理 词法 分析器 语法 实验 报告