词法语法分析中间代码生成.docx
- 文档编号:7584667
- 上传时间:2023-01-25
- 格式:DOCX
- 页数:27
- 大小:46.41KB
词法语法分析中间代码生成.docx
《词法语法分析中间代码生成.docx》由会员分享,可在线阅读,更多相关《词法语法分析中间代码生成.docx(27页珍藏版)》请在冰豆网上搜索。
词法语法分析中间代码生成
一、课程设计的目的
<<编译技术>>是理论与实践并重的课程,而其实验课要综合运用一、二年级所学的多门课程的内容,用来独立完成一个小型编译程序。
从而巩固和加强对词法分析、语法分析、语义分析、代码生成和报错处理等理论的认识和理解;进一步培养学生对完整系统的独立分析和设计的能力,进一步培养学生独立编程的能力。
二、课程设计的任务和要求
基本要求:
1.词法分析器产生下述小语言的单词序列
这个小语言的所有的单词符号,以及它们的种别编码和内部值如下表:
单词符号
种别编码
说明
sy_if
sy_then
sy_else
sy_while
sy_begin
sy_do
sy_end
a
semicolon
E
T
F
P
jinghao
tempsy
EA
EO
plus
times
becomes
mul
chuhao
chengfang
rop
lpaent
rpaent
ident
intconst
0
1
2
3
4
5
6
7
8
9
10
11
12
100
15
18
19
34
36
38
39
40
41
42
48
49
56
57
保留字if
保留字then
保留字else
保留字while
保留字begin
保留字do
保留字end
赋值语句
“;”
非终结符
非终结符
非终结符
非终结符
“#”
临时变量
Band
Bor
“+”
“*”
“:
=”
“-“
“/”
“^”
关系运算符
“(“
“)”
变量
整长量
对于这个小语言,有几点重要的限制:
首先,所有的关键字(如IF﹑WHILE等)都是“保留字”。
所谓的保留字的意思是,用户不得使用它们作为自己定义的标识符。
例如,下面的写法是绝对禁止的:
IF(5)=x
其次,由于把关键字作为保留字,故可以把关键字作为一类特殊标识符来处理。
也就是说,对于关键字不专设对应的转换图。
但把它们(及其种别编码)预先安排在一张表格中(此表叫作保留字表)。
当转换图识别出一个标识符时,就去查对这张表,确定它是否为一个关键字。
再次,如果关键字、标识符和常数之间没有确定的运算符或界符作间隔,则必须至少用一个空白符作间隔(此时,空白符不再是完全没有意义的了)。
例如,一个条件语句应写为
IFi>0i=1;
而绝对不要写成
IFi>0i=1;
因为对于后者,我们的分析器将无条件地将IFI看成一个标识符。
这个小语言的单词符号的状态转换图,如下图:
2.语法分析器能识别由加+、减-、乘*、除/、乘方^、括号()、操作数所组成的算术表达式,其文法如下:
E→E+T|E-T|T
T→T*F|T/F|F
F→P^F|P
p→(E)|i
使用的算法可以是:
预测分析法;递归下降分析法;算符优先分析法;LR分析法等。
3.中间代码生成器产生上述算术表达式的中间代码(四元式序列)
三.相关代码
#include
#include
#include
usingnamespacestd;
#defineACC-2
/************************************************/
#definesy_if0
#definesy_then1
#definesy_else2
#definesy_while3
#definesy_begin4
#definesy_do5
#definesy_end6
#definea7
#definesemicolon8//分号
#defineE9
#defineT10
#defineF11
#defineP12
#definejinghao100
#definetempsy15
#defineEA18/*Eand*/
#defineEO19/*Eor*/
#defineplus34
#definetimes36
#definebecomes38//等号或赋值
#definemul39//减号
#definechuhao40//除号/
#definechengfang41//^符号
#definerop42
#definelparent48//左括号
#definerparent49//右括号
#defineident56
#defineintconst57//整数
/********************************************/
charch='\0';//当前字符*/
intcount=0;//词计数
staticcharshibie[10]={""};//存放识别的字*/
intnum=0;
staticcharline[81]={""};//一行字符缓冲区*/
char*pline;//字符缓冲区指针*/
staticcharntab1[100][10];//标识符表
inttt1=0;
structntab
{
inttc;
intfc;
};
ntabntab2[200];
intlable=0;/*存放临时变量的表的定义*/
structrwords{
charsp[10];
intsy;
};
/*存放文件的结构*/
rwordsreswords[10]={{"if",sy_if},//保留字
{"do",sy_do},//保留字
{"else",sy_else},//保留字
{"while",sy_while},//保留字
{"then",sy_then},//保留字
{"begin",sy_begin},//保留字
{"end",sy_end},//保留字
{"and",101},//保留字
{"or",102},//保留字
{"not",103}};//保留字
structaa{//存放词法分析结果:
二元式
intsy1;
intpos;
};
aabuf[1000],/*词法分析结果缓冲区*/
n,/*当前字符*/
n1,/*当前表达式中的字符*/
sstack[100],///*符号栈*/
ibuf[100],//
stack[1000];//
intssp=0;//指向sstack[100]*/
intsp=0;/*状态栈的定义*/
intstack1[100];
intsp1=0;///*状态栈1的定义*/
aaoth;
//
structfourexp{
charop[10];
aaarg1;
aaarg2;
intresult;
};
fourexpfexp[200];///*四元式的结构*/
intnewt=0;/*临时变量*/
intnxq=100;/*nxq指向下一个形成的四元式的地址*/
aa*pbuf=buf;//指向词法分析缓冲区*/
intnlength=0;//标识符表的长度
intlnum=0;//源程序长度*/
//*******************************************************/LR表
staticintaction[19][13]=
/*0*/{{18,-1,-1,-1,-1,-1,9,-1,-1,1,6,3,13},
/*1*/{-1,2,4,-1,-1,-1,-1,-1,ACC,-1,-1,-1,-1},
/*2*/{18,-1,-1,-1,-1,-1,9,-1,-1,-1,5,3,13},
/*3*/{-1,106,106,106,106,-1,-1,106,106,-1,-1,-1,-1},
/*4*/{18,-1,-1,-1,-1,-1,9,-1,-1,-1,10,3,13},
/*5*/{-1,101,101,12,14,-1,-1,101,101,-1,-1,-1,-1},
/*6*/{-1,103,103,12,14,-1,-1,103,103,-1,-1,3,-1},
/*7*/{-1,109,109,109,109,109,-1,109,109,-1,-1,-1,-1},
/*8*/{-1,2,4,-1,-1,-1,-1,7,-1,-1,-1,-1,-1},
/*9*/{18,-1,-1,-1,-1,-1,9,-1,-1,8,6,3,13},
/*10*/{-1,102,102,12,14,-1,-1,102,102,-1,-1,-1,-1},
/*11*/{-1,107,107,107,107,-1,-1,107,107,-1,-1,-1,-1},
/*12*/{18,-1,-1,-1,-1,-1,9,-1,-1,-1,-1,16,13},
/*13*/{-1,108,108,108,108,15,-1,108,108,-1,-1,-1},
/*14*/{18,108,108,108,108,-1,-1,108,108,-1,-1,17,13},
/*15*/{18,-1,-1,-1,-1,-1,9,-1,-1,-1,-1,11,13},
/*16*/{-1,104,104,104,104,-1,-1,104,104,-1,-1,-1,-1},
/*17*/{-1,105,105,105,105,-1,-1,105,105,-1,-1,-1,-1},
/*18*/{-1,110,110,110,110,110,-1,110,110,-1,-1,-1,-1}};
//
ifstreamfile;
/************从文件读一行到缓冲区**************************/
voidreadline()
{
pline=line;
intss=0;
charaa;
file.get(aa);
while(aa!
='\n'&&!
file.eof())//eof()这个函数来判断文件是否为空或者是否读到文件结尾了
{
line[ss]=aa;
ss++;
file.get(aa);
}
line[ss]='\0';
pline=line;
}
/*******************从缓冲区读一个字符**************************/
voidreadch()
{
if(ch=='\0')
{
readline();//读一行到line数组
lnum++;//源程序行数加1
}
ch=*pline;//行首字符给ch
pline++;//pline指向line的下一字符
}
/*******************标识符和关键字的识别*************************/
intfind1(charspel[])//判断是否已是标识符表中的标识符
{
intss1=0;
intii=0;
while((ss1==0)&&(ii { if(! strcmp(spel,ntab1[ii]))//找到 ss1=1; ii++; } if(ss1==1)//找到则返回表中的位置 returnii-1; elsereturn-1; } voididentifer()//判断是否保留字 { intiii=0,j,k; intss=0; k=0; do//读1个词 { shibie[k]=ch; k++; readch(); }while(((ch>='a')&&(ch<='z'))||((ch>='0')&&(ch<='9'))); pline--; shibie[k]='\0'; while((ss==0)&&(iii<10)) { if(! strcmp(shibie,reswords[iii].sp))ss=1;//找到 iii++;//是哪个保留字 }/*关键字匹配*/ if(ss==1)//如果是保留字 { buf[count].sy1=reswords[iii-1].sy;//保留字代码 } else { buf[count].sy1=ident; j=find1(shibie);//查标识符表 if(j==-1)//没查到 { buf[count].pos=tt1; strcpy(ntab1[tt1],shibie);//加入表中 tt1++; nlength++; } else { buf[count].pos=j; } } count++; for(k=0;k<10;k++) shibie[k]='';//清空shibie字符数组 } /****************数字的识别************************/ voidnumber() { intivalue=0; intdigit; do { digit=ch-'0'; ivalue=digit; readch();//读字符 }while((ch>='0')&&(ch<='9')); buf[count].sy1=intconst; buf[count].pos=ivalue;//值 count++; pline--; } /*****************扫描主函数********************/ voidscan()//词法分析 { while(ch! ='~')//源程序尾 { switch(ch) { case'': break; case'a': case'b': case'c': case'd': case'e': case'f': case'g': case'h': case'i': case'j': case'k': case'l': case'm': case'n': case'o': case'p': case'q': case'r': case's': case't': case'u': case'v': case'w': case'x': case'y': case'z': identifer();break; case'0': case'1': case'2': case'3': case'4': case'5': case'6': case'7': case'8': case'9': number();break; case'<': readch(); if(ch=='=') { buf[count].pos=0; } else { if(ch=='>')buf[count].pos=4; else { buf[count].pos=1; pline--; } } count++; break; case'>': readch(); if(ch=='=') { buf[count].pos=2; } else { buf[count].pos=3; pline--; } count++; break; case'(': buf[count].sy1=lparent; count++; break; case')': buf[count].sy1=rparent; count++; break; case'#': buf[count].sy1=jinghao; count++; break; case'+': buf[count].sy1=plus; count++; break; case'-': buf[count].sy1=mul; count++; break; case'/': buf[count].sy1=chuhao; count++; break; case'*': buf[count].sy1=times; count++; break; case'^': buf[count].sy1=chengfang; count++; break; case': ': readch(); if(ch=='=') buf[count].sy1=becomes; count++; break; case'=': buf[count].sy1=rop; buf[count].pos=5; count++; break; case';': buf[count].sy1=semicolon; count++; break; } readch(); } buf[count].sy1=-1; } /********************displ************************/ voiddisp1() { inttemp1=0; printf("\n***************词法分析结果*************\n"); for(temp1=0;temp1 { cout< } } intreadnu()/*从二元式读一个字符*/ { if(pbuf->sy1>=0) { n.sy1=pbuf->sy1; n.pos=pbuf->pos; pbuf++; } else return-1; } intchange1(intchan) { switch(chan) { caseident: caseintconst: return0; caseplus: return1; casemul: return2; casetimes: return3; casechuhao: return4; casechengfang: return5; caselparent: return6; caserparent: return7; casejinghao: return8; caseE: return9; caseT: return10; caseF: return11; caseP: return12; } return-1; } /***********中间变量的生成************************/ intnewtemp() { newt++; returnnewt; } //p107 /***********************生成四元式***********************/ intgen(charop1[],structaaarg11,structaaarg22,intresult1) { strcpy(fexp[nxq].op,op1); fexp[nxq].arg1.sy1=arg11.sy1; fexp[nxq].arg1.pos=arg11.pos; fexp[nxq].arg2.sy1=arg22.sy1; fexp[nxq].arg2.pos=arg22.pos; fexp[nxq].result=result1; nxq++; returnnxq-1; } voidlrparse1(intnum) { intt; intlr=action[stack[sp].pos][change1(n1.sy1)];//动作表 if(lr==-1)//进行lr分析移进规约等 { cout<<"出错"< exit(0); } if((lr<19)&&(lr>=0)) { sp++; stack[sp].pos=lr; stack[sp].sy1=n1.sy1; if(! (n1.sy1>=E&&n1.sy1<=P)) { num++; ssp++; sstack[ssp].pos=n1.pos; sstack[ssp].sy1=n1.sy1; } n1.sy1=ibuf[num].sy1; n1.pos=ibuf[num].pos; lrparse1(num); } if((lr>=100)&&(lr<=110)) { switch(lr) { case100: break; case101: cout<<"E->E+T规约\n"; sp=sp-3; n1.sy1=E; t=newtemp(); gen("+",sstack[ssp-2],sstack[ssp],t+100); ssp=ssp
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 词法 语法分析 中间 代码 生成