词法语法分析中间代码生成Word文档格式.docx
- 文档编号:20700808
- 上传时间:2023-01-25
- 格式:DOCX
- 页数:27
- 大小:46.41KB
词法语法分析中间代码生成Word文档格式.docx
《词法语法分析中间代码生成Word文档格式.docx》由会员分享,可在线阅读,更多相关《词法语法分析中间代码生成Word文档格式.docx(27页珍藏版)》请在冰豆网上搜索。
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<
iostream>
fstream>
//对文件的操作是通过stream的子类fstream(filestream)来实现的
#include<
string>
//<
头文件定义了在std(标准)空间中的string相关的函数
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]='
}
/*******************从缓冲区读一个字符**************************/
voidreadch()
if(ch=='
)
readline();
//读一行到line数组
lnum++;
//源程序行数加1
ch=*pline;
//行首字符给ch
pline++;
//pline指向line的下一字符
/*******************标识符和关键字的识别*************************/
intfind1(charspel[])//判断是否已是标识符表中的标识符
intss1=0;
intii=0;
while((ss1==0)&
(ii<
nlength))//没找到且表长度内
if(!
strcmp(spel,ntab1[ii]))//找到
ss1=1;
ii++;
if(ss1==1)//找到则返回表中的位置
returnii-1;
elsereturn-1;
voididentifer()//判断是否保留字
intiii=0,j,k;
k=0;
do//读1个词
shibie[k]=ch;
k++;
readch();
}while(((ch>
a'
)&
(ch<
z'
))||((ch>
0'
9'
)));
pline--;
shibie[k]='
while((ss==0)&
(iii<
10))
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-'
ivalue=digit;
//读字符
}while((ch>
));
buf[count].sy1=intconst;
buf[count].pos=ivalue;
//值
/*****************扫描主函数********************/
voidscan()//词法分析
while(ch!
~'
)//源程序尾
switch(ch)
case'
:
break;
b'
c'
d'
e'
f'
g'
h'
i'
j'
k'
l'
m'
n'
o'
p'
q'
r'
s'
t'
u'
v'
w'
x'
y'
identifer();
1'
2'
3'
4'
5'
6'
7'
8'
number();
'
readch();
if(ch=='
{
buf[count].pos=0;
}
else
if(ch=='
)buf[count].pos=4;
else
{
buf[count].pos=1;
pline--;
}
count++;
break;
readch();
buf[count].pos=2;
buf[count].pos=3;
pline--;
('
buf[count].sy1=lparent;
)'
buf[count].sy1=rparent;
#'
buf[count].sy1=jinghao;
+'
buf[count].sy1=plus;
-'
buf[count].sy1=mul;
/'
buf[count].sy1=chuhao;
*'
buf[count].sy1=times;
^'
buf[count].sy1=chengfang;
buf[count].sy1=becomes;
buf[count].sy1=rop;
buf[count].pos=5;
buf[count].sy1=semicolon;
buf[count].sy1=-1;
/********************displ************************/
voiddisp1()
inttemp1=0;
printf("
\n***************词法分析结果*************\n"
);
for(temp1=0;
temp1<
count;
temp1++)
cout<
buf[temp1].sy1<
"
buf[temp1].pos<
endl;
intreadnu()/*从二元式读一个字符*/
if(pbuf->
sy1>
=0)
n.sy1=pbuf->
sy1;
n.pos=pbuf->
pos;
pbuf++;
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分析移进规约等
出错"
exit(0);
if((lr<
19)&
(lr>
=0))
sp++;
stack[sp].pos=lr;
stack[sp].sy1=n1.sy1;
(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文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 词法 语法分析 中间 代码 生成
![提示](https://static.bdocx.com/images/bang_tan.gif)