编译原理实验报告.docx
- 文档编号:29895462
- 上传时间:2023-08-03
- 格式:DOCX
- 页数:31
- 大小:172.55KB
编译原理实验报告.docx
《编译原理实验报告.docx》由会员分享,可在线阅读,更多相关《编译原理实验报告.docx(31页珍藏版)》请在冰豆网上搜索。
编译原理实验报告
编译原理实验报告
学院:
国际教育学院
专业:
中法计算机合作专业
班级:
中法计082
姓名:
王倩男
学号:
082500
指导老师:
吴清
实验成绩:
良好
完成时间:
2011年6月13日
目录
实验一词法分析程序实现3
实验设计:
3
实验步骤3
基本思路:
6
流程图6
程序代码:
7
实验结果分析:
12
实验心得12
实验二语法分析程序实现13
实验设计:
13
实验步骤13
基本思路13
流程图:
14
程序代码15
wordscan.h15
Test.cpp17
实验结果分析19
实验心得21
实验一词法分析程序实现
实验设计:
实验目的与要求
通过编写和调试一个词法分析程序,掌握在对程序设计语言的源程序进行扫描的过程中,将字符流形式的源程序转化为一个由各类单词符号组成的流的词法分析方法。
基本实验题目
题目:
试用手工编码方式构造识别以下给定单词的某一语言的词法分析程序。
语言中具有的单词包括五个关键字begin、end、if、then、else;标识符;无符号常数;六种关系运算符;一个赋值符和四个算术运算符。
实验步骤
单词的分类:
构造上述语言中的各类单词符号及其分类码表。
单词符号
类别编码
类别码的助记符
单词值
begin
1
BEGIN
end
2
END
if
3
IF
then
4
THEN
else
5
ELSE
标识符
6
ID
字母打头的字母数字串
无符号常数
7
UCON
机内二进制表示
<
8
LT
<=
9
LE
=
10
EQ
<>
11
NE
>
12
GT
>=
13
GE
:
=
14
IS
+
15
PL
-
16
MI
*
17
MU
/
18
DI
表I语言中的各类单词符号及其分类码表
图I识别表I所列语言中的部分单词的DFA及相关的语义过程
图I中所出现的语义变量及语义函数的含义和功能说明如下:
Ø函数GETCHAR:
每调用一次,就把扫描指示器当前所指示的源程序字符送入字符变量ch,然后把扫描指示器前推一个字符位置。
Ø字符数组TOKEN:
用来依次存放一个单词词文中的各个字符。
Ø函数CAT:
每调用一次,就把当前ch中的字符拼接于TOKEN中所存字符串的右边。
Ø函数LOOKUP:
每调用一次,就以TOKEN中的字符串查保留字表,若查到,就将相应关键字的类别码赋给整型变量c;否则将c置为零。
函数RETRACT:
每调用一次,就把扫描指示器回退一个字符位置(即退回多读的那个字符)。
Ø函数OUT:
一般仅在进入终态时调用此函数,调用的形式为OUT(c,VAL)。
其中,实参c为相应单词的类别码或其助记符;实参VAL为TOKEN(即词文)或为空串。
函数OUT的功能是,在送出一个单词的内部表示之后,返回到调用该词法分析程序的那个程序。
需要将程序一中的整常数扩展为无符号常数,以满足题目的要求。
描述无符号数的右线性文法G1[<无符号数>]如下:
〈无符号数〉→d〈余留无符号数〉
〈无符号数〉→·〈小数部分〉
〈无符号数〉→d
〈余留无符号数〉→d〈余留无符号数〉
〈余留无符号数〉→·〈十进小数〉
〈余留无符号数〉→E〈指数部分〉
〈余留无符号数〉→d
〈余留无符号数〉→·
〈十进小数〉→E〈指数部分〉
〈十进小数〉→d〈十进小数〉
〈十进小数〉→d
〈小数部分〉→d〈十进小数〉
〈小数部分〉→d
〈指数部分〉→d〈余留整指数〉
〈指数部分〉→+〈整指数〉
〈指数部分〉→-〈整指数〉
〈指数部分〉→d
〈整指数〉→d〈余留整指数〉
〈整指数〉→d
〈余留整指数〉→d〈余留整指数〉
〈余留整指数〉→d
图II所示为上述文法的状态转换图,其中编号0、1、2、…、6分别代表非终结符号<无符号数>、<余留无符号数>、<十进小数>、<小数部分>、<指数部分>、<整指数>及<余留整指数>。
图II文法G1[<无符号数>]的状态转换图
无符号数识别中的语义处理方法详见教材P56。
表II即为嵌入了语义动作的状态矩阵,其功能是在扫描源程序字符串的过程中,把识别出的字符串形式的无符号数的值,逐步转换为相应的二进制整数(ICON)或二进制浮点数(FCON)的内部形式。
(注:
考虑能否采用C语言的库函数实现此语义处理工作;是否可将无符号常数这一类单词进一步细分成整型常数和浮点型常数两类单词。
)
表II包含语义处理过程的识别无符号数的状态矩阵
基本思路:
Ø关键字作为一类特殊的标示符:
识别出关键字,执行lookup()函数查询关键字表,并给出其识别码。
Ø识别无符号整数是将数字串转化为浮点型FCON并输出。
Ø主程序入口:
t_main();打开文件file.txt,调用scanner函数对file.txt中的程序段进行扫描,并使用out()函数控制输出。
否
流程图
Ø主程序流程图:
Ø
输出
扫描子程序流程图:
程序代码:
程序一根据图1编写的扫描器
#include"stdafx.h"
#include
#include
#include
#include
#defineDIGIT1
#definePOINT2
#defineOTHER3
#definePOWER4
#definePLUS5
#defineMINUS6
#defineID6
#defineINT7
#defineLT8
#defineLE9
#defineEQ10
#defineNE11
#defineGT12
#defineGE13
#defineClassOther200
#defineEndState-1
intw,n,p,e,d;
intClass;//Usedtoindicateclassoftheword
intICON;
floatFCON;
staticintCurrentState;//Usedtopresentcurrentstate,theinitialvalue:
0
intGetChar(void);
intEXCUTE(int,int);
intLEX(void);
charTOKEN[20];
intHandleOtherWord(void)
{returnClassOther;}
intHandleError(void)
{printf("Error!
\n");return0;}
intGetChar(inti)
{
intc;
c=(int)TOKEN[i];
if(isdigit(c)){d=c-'0';returnDIGIT;}
if(c=='.')returnPOINT;
if(c=='E'||c=='e')returnPOWER;
if(c=='+')returnPLUS;
if(c=='-')returnMINUS;
returnOTHER;
}
intEXCUTE(intstate,intsymbol)
{
switch(state)
{
case0:
switch(symbol)
{
caseDIGIT:
n=0;p=0;e=1;w=d;CurrentState=1;Class=INT;break;
casePOINT:
w=0;n=0;p=0;e=1;CurrentState=3;Class=INT;break;
default:
HandleOtherWord();Class=ClassOther;CurrentState=EndState;
}
break;
case1:
switch(symbol)
{
caseDIGIT:
w=w*10+d;break;//CurrentState=1;
casePOINT:
CurrentState=2;break;
casePOWER:
CurrentState=4;break;
default:
ICON=w;CurrentState=EndState;FCON=(float)ICON;
}
break;
case2:
switch(symbol)
{
caseDIGIT:
n++;w=w*10+d;break;
casePOWER:
CurrentState=4;break;
default:
FCON=(float)w*pow((float)10,e*p-n);CurrentState=EndState;
}
break;
case3:
switch(symbol)
{
caseDIGIT:
n++;w=w*10+d;CurrentState=2;break;
default:
HandleError();CurrentState=EndState;
}
break;
case4:
switch(symbol)
{
caseDIGIT:
p=p*10+d;CurrentState=6;break;
caseMINUS:
e=-1;CurrentState=5;break;
casePLUS:
CurrentState=5;break;
default:
HandleError();CurrentState=EndState;
}
break;
case5:
switch(symbol)
{
caseDIGIT:
p=p*10+d;CurrentState=6;break;
default:
HandleError();CurrentState=EndState;
}
break;
case6:
switch(symbol)
{
caseDIGIT:
p=p*10+d;break;
default:
FCON=(float)w*pow((float)10,e*p-n);
CurrentState=EndState;
}
break;
}
returnCurrentState;
}
intLEX(void)
{
intch;
inta=0;
CurrentState=0;
while(CurrentState!
=EndState)
{
ch=GetChar(a);
EXCUTE(CurrentState,ch);
a++;
}
returnClass;
}
externintlookup(char*TOKEN)
{
intz;
if(strcmp(TOKEN,"begin")==0)
{z=1;
returnz;}
if(strcmp(TOKEN,"end")==0)
{z=2;
returnz;}
if(strcmp(TOKEN,"if")==0)
{z=3;
returnz;}
if(strcmp(TOKEN,"then")==0)
{z=4;
returnz;}
if(strcmp(TOKEN,"else")==0)
{z=5;
returnz;}
else
{z=0;
returnz;}
}
externvoidout(intc,char*TOKEN)
{
if(c==6)
{
printf("(ID,%s)对应'%s'",TOKEN,TOKEN);
}
elseif(c==7)
{
if((int)FCON!
=FCON)
printf("(UCON,%f)对?
应®|'%s'",FCON,TOKEN);
else
printf("(UCON,%i)对?
应®|'%s'",ICON,TOKEN);
}
elseif(c==8)
printf("(LT,%s)对应'<'",TOKEN);
elseif(c==9)
printf("(LE,%s)对应'<='",TOKEN);
elseif(c==10)
printf("(EQ,%s)对应'='",TOKEN);
elseif(c==11)
printf("(NE,%s)对应'<>'",TOKEN);
elseif(c==12)
printf("(GT,%s)对应'>'",TOKEN);
elseif(c==13)
printf("(GE,%s)对应'>='",TOKEN);
elseif(c==14)
printf("(IS,%s)对应':
='",TOKEN);
elseif(c==15)
printf("(PL,%s)对应'+'",TOKEN);
elseif(c==16)
printf("(MI,%s)对应'-'",TOKEN);
elseif(c==17)
printf("(MU,%s)对应'*'",TOKEN);
elseif(c==18)
printf("(DI,%s)对应'/'",TOKEN);
elseif(c==1)
printf("(BEGIN,)对应'begin'");
elseif(c==2)
printf("(END,)对应'end'");
elseif(c==3)
printf("(IF,)对应'if'");
elseif(c==4)
printf("(THEN,)对应'then'");
elseif(c==5)
printf("(ELSE,)对应'else'");
printf("\n");
}
externvoidreport_error(void)
{printf("error");}
voidscanner(FILE*fp)
{
charch;inti,c;
ch=fgetc(fp);
while(ch!
=EOF)
{
if(isalpha(ch))
{
TOKEN[0]=ch;ch=fgetc(fp);i=1;
while(isalnum(ch))
{
TOKEN[i]=ch;i++;
ch=fgetc(fp);
}
TOKEN[i]='\0';
fseek(fp,-1,1);
c=lookup(TOKEN);
if(c==0)out(ID,TOKEN);
elseout(c,"");
}
else
if(isdigit(ch))
{
TOKEN[0]=ch;ch=fgetc(fp);i=1;
while(isdigit(ch)||ch=='.'||ch=='E'||ch=='e'||ch=='-')
{
TOKEN[i]=ch;i++;
ch=fgetc(fp);
}
TOKEN[i]='\0';
fseek(fp,-1,1);
LEX();
out(INT,TOKEN);
}
else
switch(ch)
{
case'<':
ch=fgetc(fp);
if(ch=='=')out(LE,"");
elseif(ch=='>')out(NE,"");
else
{
fseek(fp,-1,1);
out(LT,"");
}break;
case'=':
out(EQ,"");break;
case'>':
ch=fgetc(fp);
if(ch=='=')out(GE,"");
else
{
fseek(fp,-1,1);
out(GT,"");
}break;
case':
':
ch=fgetc(fp);
if(ch=='=')out(14,"");break;
default:
report_error();break;
case'':
break;
case'\n':
break;
case'\t':
break;
case'+':
out(15,"");break;
case'-':
out(16,"");break;
case'*':
out(17,"");break;
case'/':
out(18,"");break;
}
ch=fgetc(fp);
}
}
int_tmain(intargc,_TCHAR*argv[])
{
FILE*fp;
fp=fopen("file.txt","r");
scanner(fp);
getchar();
return0;
}
实验结果分析:
建立一个名为file.txt的文件,键入“ifmyid>=1.5E-2+100thenx:
=y”并保存,运行得到如下结果:
实验心得
词法分析的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。
通过本试验的完成,更加加深了对词法分析原理的理解。
最初是按照老师课堂上的C语言实现这个思路进行的,但是后来老师要求将识别数字拓展到浮点数(即实数)。
由于本人C语言功底不够扎实,最后只得再回过头去看了一下C语言的语法,不过最后还是通过自己的力量把东西给做出来了。
很有成就感!
实验二语法分析程序实现
实验设计:
实验目的与要求
通过设计、编制、调试一个典型的语法分析程序(任选一种有代表性的语法分析方法,如算符优先法、递归下降法、LL
(1)、SLR
(1)、LR
(1)等,作为编制语法分析程序的依据),对扫描器所提供的单词序列进行语法检查和结构分析,实现并进一步掌握常用的语法分析方法。
实验内容
选择对各种常见高级程序设计语言都较为通用的语法结构作为分析对象,给出其文法描述(注意应与所采用的语法分析方法比较贴近),设计并实现一个完整的语法分析程序(分析过程可暂不嵌入任何语义动作)。
题目:
对算术表达式的一个简化子集,根据如下其语法结构的BNF定义G2[<算术表达式>],任选学过的一种语法分析方法,针对运算对象为无符号数(和变量)的四则运算,编制一个语法分析程序。
G2[<算术表达式>]:
<算术表达式>→<项>|<算术表达式>+<项>|<算术表达式>-<项>
<项>→<因式>|<项>*<因式>|<项>/<因式>
<因式>→<运算对象>|(<算术表达式>)
若将语法范畴<算术表达式>、<项>、<因式>和<运算对象>分别用E、T、F和i代表,则G2可写成:
E→T|E+T|E-TT→F|T*F|T/FF→i|(E)
实验步骤
基本思路
设定待分析的简单语言的语法用扩充的BNF表示如下:
⑴<程序>:
:
=begin<语句串>end
⑵<语句串>:
:
=<语句>{;<语句>}
⑶<语句>:
:
=<赋值语句>
⑷<赋值语句>:
:
=ID:
=<表达式>
⑸<表达式>:
:
=<项>{+<项>|-<项>}
⑹<项>:
:
=<因子>{*<因子>|/<因子>
⑺<因子>:
:
=ID|NUM|(<表达式>)
结合实验一的词法分析器,经修改简化后得到wordscan.h,利用C语言编制递归下降分析的语法分析程序。
流程图:
Ø主程序流程图:
结束
Ø递归下降分析程序流程图
提示错误:
语句错误
Ø
是
语句串分析程序流程图
Ø语句分析程序流程图
是否为’:
=’
是否为’+’||’-’
是否为’*’||’/’
程序代码
wordscan.h
#include"stdio.h"
#include"string.h"
charprog[80],token[8];
intc,p,m,n,sum=0;
charch;
char*rwtab[5]={"begin","end","if","then","else"};
voidscanner()
{
m=0;
for(n=0;n<8;n++)token[n]=NULL;
ch=prog[p++];
while(ch=='')ch=prog[p++];
if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))
{
while((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')||(ch>='0'&&ch<='9'))
{
token[m++]=ch;
ch=prog[p++];
}
token[m++]='\0';
c=6;
p=p-1;//回退一个字符
for(n=0;n<5;n++)
{
if(strcmp(token,rwtab[n])==0)
{
c=n+1;
break;
}
}
}
elseif(ch>='0'&&ch<='9')
{
sum=0;
while(ch>='0'&&ch<='9')
{
sum=sum*10+ch-'0';
ch=prog[p++];
}
p=p-1;c=7;
}
else
{
switch(ch)
{
case'<':
m=0;
token[m++]=ch;
ch=prog[p];
if(ch=='>')
{
c=11;
token[m++]=ch;
}
elseif(ch=='=')
{
c=9;
token[m++]=ch;
}
else
{
c=8;
p=p-1;
}
p=p+1;
token[m]='\0';
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理 实验 报告