编译原理课程设计小型程序设计语言编译器的设计与实现文档格式.docx
《编译原理课程设计小型程序设计语言编译器的设计与实现文档格式.docx》由会员分享,可在线阅读,更多相关《编译原理课程设计小型程序设计语言编译器的设计与实现文档格式.docx(20页珍藏版)》请在冰豆网上搜索。
所以就选择参照书上的内容自己动手,词法分析的思路基本上和书上的一样对每个词进行分析编号。
但是由于书上内容复杂,所以我只做了赋值语句的顺序处理部分。
而且和书上的赋值语句相比我有加了减法和除法的功能。
并且在读取阶段,书上是按行读取(读到”\n”为一个readline),而我选择了按语句进行读取(读到”;
”为一个readline)。
因为有时候一行之间会有好几个语句。
我可以把一行上的多个语句分开来,当然书上也可以只不过这一步她是在程序语句处理里面完成的。
而我只有赋值语句。
并且还要实现顺序结构所以就按照自己的思路做下去了。
然后是语法分析,由于词法分析和书上的有出路。
所以一开始我就没打算用书上的思路去做。
就按照自己的思路来解决,首先是对词法分析里的存储单词的数组进行拷贝和修改(添加了#号使其能区分出赋值语句)、然后正式的语法分析时,我是直接对拷贝后的数组进行分析的,中间出了不少错误,更关键的是语法分析时在顺序上出现了错误,这一点我无法用语言说清楚,解决顺序上的错误时我加入了add1()这个函数,同时这个函数也实现了将终结符改为非终结符的功能(也就是所谓的临时变量)。
然后就是一个语句分析完后进行下一个语句的分析。
这个就是个衔接问题,改动数组的坐标就能完成,大概的思路就是这样,中间调试时错误百出,对语法分析程序做了不少的小动作。
然后就是将语法分析结果显示出来,为了和课本的相似,用了几个条件语句做约定。
这个是第二天上午解决的,思考了一会。
当然最关键的核心技术,还是和书上的一样。
符号
种别编码
说明
Pound_sign
7
“#”
add
34
“+”
sub
35
“-”
mul
36
“*“
div
37
“/”
equal
38
“=”
lbrackets
48
“(“
rbrackets
49
“)”
tempsy
55
临时变量
ident
56
变量
intconst
57
整常数
单词符号的内部定
状
态
ACTION
GOTO
i
+
-
*
/
(
)
#
E
S3
S2
S4
S5
S6
S7
8
R6
9
10
11
12
S13
R1
R2
R3
R4
13
R5
算符运算SLR
(1)分析表
七.源程序及运行结果
#include<
iostream>
fstream>
string.h>
usingnamespacestd;
#definetxtname"
C:
\\bianyiqi.txt"
#defineACC-2
//---------------------字符定义------------------------
#definepound_sign7//“#”
#defineadd34//“+”
#definesub35//“-”
#definemul36//“*“
#definediv37//“/”
#defineequal38//“=”
#definelbrackets48//“(“
#definerbrackets49//“)”
#definetempsy55//临时变量
#defineident56//变量
#defineintconst57//整常数
//--------------------变量申明-------------------------
charch='
\0'
;
//读取字符
intcount=0;
//计buf里的单词个数
staticcharspelling[10]={"
"
};
//读取一个变量
staticcharline[255]={"
//单词字符数组
char*pline;
//单词指针
intlnum=0;
//行数
intnlength=0;
//所产生的变量编号
staticcharntab1[100][10];
//存放新的变量并进行比较
structaa
{
intsy1;
intpos;
}buf[1000],n,n1,E,sstack[100],ibuf[100];
inttt1=0;
intstack[1000];
//栈
intsp=0;
//栈的位置数
intii=2;
//ibuf数组的位置数
intlr;
//状态序列
intj=0;
//ibuf总个数
inth=1;
//控制”#结束#”的个数函数
ifstreaminfile;
//-----------------语法分析表---------------------------------
intaction[14][9]={{3,-1,-1,-1,-1,2,-1,-1,1},
{-1,4,5,6,7,-1,-1,ACC,-1},
{3,-1,-1,-1,-1,2,-1,-1,8},
{-1,106,106,106,106,-1,106,106,-1},
{3,-1,-1,-1,-1,2,-1,-1,9},
{3,-1,-1,-1,-1,2,-1,-1,10},
{3,-1,-1,-1,-1,2,-1,-1,11},
{3,-1,-1,-1,-1,2,-1,-1,12},
{-1,4,5,6,7,-1,13,-1,-1},
{-1,101,101,6,7,-1,101,101,-1},
{-1,102,102,6,7,-1,102,102,-1},
{-1,103,103,103,103,-1,103,103,-1},
{-1,104,104,104,104,-1,104,104,-1},
{-1,105,105,105,105,-1,105,105,-1}};
//------------------字符读取---------------------------
voidreadline()
{
charch1;
pline=line;
infile.get(ch1);
while(ch1!
='
'
{
*pline=ch1;
pline++;
infile.get(ch1);
}
*pline=NULL;
}
voidreadch()
if(ch==NULL)
readline();
lnum++;
ch=*pline;
pline++;
//-----------------变量识别-----------------------
intfind(charspel[])
intss1=0;
intii=0;
while((ss1==0)&
&
(ii<
nlength))
if(!
strcmp(spel,ntab1[ii]))
ss1=1;
ii++;
if(ss1==1)
returnii-1;
else
return-1;
voididentifier()
intiii=0,j,k=0;
do
spelling[k]=ch;
k++;
readch();
}while(((ch>
a'
)&
(ch<
z'
))||((ch>
0'
9'
)));
pline--;
spelling[k]='
buf[count].sy1=ident;
j=find(spelling);
if(j==-1)
buf[count].pos=tt1;
strcpy(ntab1[tt1],spelling);
tt1++;
nlength++;
buf[count].pos=j;
count++;
for(k=0;
k<
10;
k++)
spelling[k]=NULL;
//----------------数字识别------------------------
voidnumber()
intivalue=0;
intdigit;
digit=ch-'
ivalue=ivalue*10+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'
identifier();
break;
1'
2'
3'
4'
5'
6'
7'
8'
number();
+'
buf[count].sy1=add;
count++;
-'
buf[count].sy1=sub;
*'
buf[count].sy1=mul;
/'
buf[count].sy1=div;
buf[count].sy1=equal;
('
buf[count].sy1=lbrackets;
)'
buf[count].sy1=rbrackets;
}
buf[count].sy1=-1;
//全部读完最后一个赋值为-1
//-------------------------------------------
voiddisp2(aak)
switch(k.sy1)
case34:
cout<
<
+"
endl;
case35:
-"
case36:
*"
case37:
/"
case38:
="
case48:
("
case49:
)"
case55:
临时变量"
case56:
变量"
\t'
ntab1[k.pos]<
case57:
整常数"
voiddisp1()
inti;
cout<
endl<
----------------------词法分析结果------------------------"
for(i=0;
i<
count;
i++)
cout<
buf[i].sy1<
buf[i].pos<
disp2(buf[i]);
程序总共"
lnum<
行,产生了"
count<
个二元式"
----------------------变量名表------------------------"
tt1;
ntab1[i]<
voiddisp3()
状态:
for(inti=0;
=sp;
stack[i]<
"
//----------------与分析表匹配---------------------------
intchange(intn)
switch(n)
caseident:
caseintconst:
return0;
caseadd:
return1;
casesub:
return2;
casemul:
return3;
casediv:
return4;
caselbrackets:
return5;
caserbrackets:
return6;
casepound_sign:
return7;
casetempsy:
return8;
//---词法分析数组转化为语法分析数组-----------
voidexchange()
if(buf[i-1].sy1==ident&
buf[i].sy1==ident)
ibuf[j].sy1=pound_sign;
j++;
ibuf[j].sy1=buf[i].sy1;
if(buf[i].sy1==ident)
ibuf[j].pos=buf[i].pos;
j++;
ibuf[j].sy1=pound_sign;
j++;
ibuf[j].sy1=-1;
=j;
ibuf[i].sy1<
//------------------增加临时变量------------------------
voidadd1(inti)
intk=j,n;
for(n=k;
n>
=i;
n--)
ibuf[n+1].sy1=ibuf[n].sy1;
ibuf[n+1].sy1=tempsy;
//------------------语法分析-------------------
voidlrparse()
lr=action[stack[sp]][change(ibuf[ii].sy1)];
//cout<
stack[sp]<
change(ibuf[ii].sy1)<
if(ibuf[ii].sy1!
=tempsy)
disp3();
if(lr<
14&
lr>
=0)
sp++;
stack[sp]=lr;
if(ibuf[ii].sy1!
=tempsy&
lr!
=ACC)
cout<
移进"
//cout<
#'
ibuf[ii].sy1<
//disp3();
lrparse();
if(lr>
100&
lr<
107)
switch(lr)
case101:
sp=sp-3;
add1(ii);
ibuf[ii].sy1=tempsy;
归约E→E+E"
break;
case102:
归约E→E-E"
case103:
归约E→E*E"
case104:
归约E→E/E"
case105:
归约E→(E)"
case106:
sp=sp-1;
归约E→i"
if(lr==ACC)
sp=sp-1;
if(h==1)
//disp3();
#"
结束"
h=2;
if(ibuf[ii+1].sy1!
=-1)
stack[sp+1]=0;
ii=ii+3;
h=1;
lrparse();
else
return;
//--------------------------------
intmain()
infile.open(txtname,ios:
in);
readch();
scan();
disp1();
exchange();
stack[sp]=0;
------------------语法分析-------------------"
lrparse();
infile.close();
return0;
运行结果:
1.使用的语句是d=(a+b)/c~;
这里的~号是用来结束用的实际分析的