编译实验报告.docx

上传人:b****3 文档编号:12882810 上传时间:2023-04-22 格式:DOCX 页数:77 大小:89.50KB
下载 相关 举报
编译实验报告.docx_第1页
第1页 / 共77页
编译实验报告.docx_第2页
第2页 / 共77页
编译实验报告.docx_第3页
第3页 / 共77页
编译实验报告.docx_第4页
第4页 / 共77页
编译实验报告.docx_第5页
第5页 / 共77页
点击查看更多>>
下载资源
资源描述

编译实验报告.docx

《编译实验报告.docx》由会员分享,可在线阅读,更多相关《编译实验报告.docx(77页珍藏版)》请在冰豆网上搜索。

编译实验报告.docx

编译实验报告

二、课程设计正文

1.编写一个L-语言的词法分析器,从左到右逐个字符地对L-语言的源程序进行扫描,产生一个个单词符号的机内表示。

程序结构如图L-1所示:

scanner

IsAlpha

IsNumber

IsChar

Isother

OutPut

Error

图L-1

1.1Sanner()

1.功能:

完成初始化,并循环调用子模块,完成单词的识别。

2.算法描述如下

VoidScanner()

{调用ScannerInit()进行初始化;

读入源程序的第一个字符;

while(字符!

=EOF)

{if(字符==字母)IsAlPha();

elseif(字符==数字)IsNumber();

elseif(字符==‘’’)IsChar();

elseIsOther();

}

打印结束信息;

结束操作;

}

1.2IsAlPha()

1.功能:

识别保留字和标识符。

2.算法描述如下:

VoidIsAlPha()

{while(字符为字母或数字或’_’)

{记录当前字符;

读取下一字符;

}

判断当前字符串是否为保留字,并设置标志位h;

调用OutPut()函数输出保留字或标识符;

}

1.3IsNumber()

1.功能:

识别整数和实数。

2.算法描述如下:

voidIsNumber()

{

intflag=0;

while(字符为数字)

{记录当前字符;

读取下一字符;

If(字符为’.’号)

{记录当前字符;

flag=1;

读下一字符;

跳出循环;

}

}

记单词编码为整数的编码(当前Token为整数);

If(flag=1)

{if(当前字符为数字)

{记录当前数字;

while(当前字符为数字)

{记录字符;

读取下一字符;

}

记单词编码为实数的编码(当前Token为实数);

}

elseError

(2);

if(当前字符为’.’)删除余下数字;

}

if(当前字符为字母)舍去后面的部分;

OutPut();

}

1.4IsChar()

1.功能:

识别字符串。

2.算法描述:

voidIsChar()

{for(;;;)

{读取下一字符;

现行Token为字符串;

If(当前字符不是‘.’号)

记录字符;

Elsebreak;

}

OutPut();

读下一字符;

}

1.5IsOther()

1.功能:

识别其他单词。

2.算法描述如下:

voidIsOther()

{switch(当前字符)

{对于不同字符做出不同处理,主要有:

1、符号内容的记取;

2、查出机内码;

3、调用OutPut()输出至Token()文件;

4、读取下一字符;

5、对于错误符号将其删除,并报错;}

}

1.6ScannerInit()

1.功能:

进行初始化,主要包括:

1、建立单词编码表、token表、符号表,并将它们清空。

2、打开单词编码文件,并将单词编码读到编码表中。

1.7OutPut()

1.功能:

输出识别出的单词,包括:

2.若单词为标识符或常数再查,填符号表。

1.8Error()

1.功能:

判断错误原因。

2.在由词法分析程序对L语言源程序分析产生的token,符号表文件的基础上,从完成语法语义分析,并产生相应的中间代码-四元式序列。

2.1paser()

1.功能:

主模块,完成初始化,并调用复合语句分析模块和说明语句分析模块,完成分析任务。

2.算法描述如下:

voidpaser()

{初始化;

从Token文件读取第一个单词;

if(单词==program)

{读取下一单词;

if(单词==标识符)

{读取下一单词;

if(单词为‘;’)

{行数加一;

读取下一单词;

if(单词为var)

declear();

if(单词为begin)

{S_Begin();

if(code不是等于号)Error(49);

}

else出错处理;

}

else出错处理;

}

else出错处理;

}

else出错处理;

2.2S_Begin()

1.功能:

完成复合语句的分析。

2.算法描述

S_Begin()

{if(当前字符为begin)

{读取下一字符;

调用L_Analize();

if(当前字符为end)结束;

else非正常结束,返回0;

}

读取下一字符;

返回;

}

2.3L_Analize()

1.功能:

完成语句序列分析。

2.算法描述

L_Analize()

{intrtn;

switch(当前字符)

{caseIF:

调用S_IF()函数;break;

caseBEGIN:

调用S_Begin()函数;braek;

case标识符:

调用S_Let()函数;break;

caseWHILE:

调用S_While();break;

}

if(当前字符为‘:

’)

{行数加一;

读取下一字符;

递归调用L_Analize()

}

elsereturnrtn;

}

2.4S_Let()

1.功能:

完成赋值语句的分析。

2.算法分析

S_Let(inta)

{if(当前字符为标识符)

{if(需要记录变量的地址)记录赋值变量的地址;

读取下一个单词;

if(当前单词为赋值号)

{调用表达式分析函数L_Analize();

if(表达式正确)生成赋值句四元式;

}

}

else赋值句出错;

return四元式序号;

}

2.5S_IF()

1.功能:

完成条件语句的分析。

2.算法描述:

IntS_IF()

{inta;

intrtn=0;

定义一个真出口True_address和一个假出口Flase_address;

if(当前单词为if)

{布尔表达式初始化;

调用布尔表达式分析函数B_Analize();

rtn=布尔表达式的四元式首址;

产生无条件跳转四元式;

if(当前单词为then)

{读取下一单词;

switch(当前单词)

{caseIF:

调用S_IF()函数;break;

caseBEGIN:

调用S_Begin()函数;braek;

case标识符:

调用S_Let()函数;break;

caseWHILE:

调用S_While();break;

}

BackPatch();

if(当前单词为else)

{读取下一单词;

switch(当前单词)

{caseIF:

调用S_IF()函数;break;

caseBEGIN:

调用S_Begin()函数;braek;

case标识符:

调用S_Let()函数;break;

caseWHILE:

调用S_While();break;

}

BackPatch();

}

elsertn;

}

else报错;(缺少then)

}

rtn;

}

2.6S_While()

1.功能:

完成while循环语句的分析。

2.算法描述;

intS_While()

{intrtn=0;boor_value,True_address,False_address;

if(当前单词为while)

{rtn=布尔表达式分析函数B_Analize();

boor_value=布尔表达式值地址;

产生跳转四元式;

if(当前单词为do)

{读取下一单词;

switch(当前单词)

{caseIF:

调用S_IF()函数;break;

caseBEGIN:

调用S_Begin()函数;braek;

case标识符:

调用S_Let()函数;break;

caseWHILE:

调用S_While();break;

}

BackPatch();

BackPatch();

}

else出错,缺少do;

}

returnrtn;

}

2.7gen()

该函数形成一个四元式,并将其输出至四元式文件。

2.8E_Analize()

1.该函数是算术分析表达式的主模块,它调用算术表达式的子模块,采用递归下降分析法完成算术表达式的分析。

2.算术表达式的各个子模块:

a.E_Init()将算术表达式读入分析栈;

b.intE_AddSub()完成E->TE1|T的分析;

c.intE1_AddSub(inta)完成E1->+TE1|-TE1|^

d.T_MulDiv()完成T->FT1|F的分析;

e.T1_MulDiv(inta)完成T1->*FT1|/FT1|^;

f.F_Number()完成F->i|(E)的分析;

2.9B_Analize()

1.布尔表达式分析的主模块,调用其他布尔表达式的子模块,采用递归下降分析法完成布尔表达式的分析。

并返回该布尔表达式的首个四元式地址。

a.B_OR()完成B->LB|L的分析;

b.B1_OR(inta)完成B1->orLB1|^的分析;

c.L_AND()完成L->ML1|M的分析;

d.L1_AND()完成L1->andM1|^的分析;

e.M_NOT()完成M->notM|K的分析;

f.K_END()完成K->i|false|true|(B)的分析;

g.K_CMP()完成K->iSi,S-><>|=|<=|>=|>|<的分析。

三、课程设计总结

1、实验中遇到的问题

词法分析器程序中要读入一个单词编码文件,但是文件的格式在编写的时候和程序有点差异,因而导致输出结果再三的错误。

语法/语义分析器中,在修改符号表时,出现错误,最终没有的到正确结果。

2、对实验原理有更深的理解

通过该课程设计,掌握了什么是编译程序,编译程序工作的基本过程及其各阶段的基本任务,熟悉了编译程序总流程框图,了解了编译程序的生成过程,构造工具及其相关的技术对课本上的知识有了更深的理解,课本上的知识师机械的,表面的.通过把该算法的内容,算法的执行顺序在计算机上实现,把原来以为很深奥的书本知识变的更为简单,对实验原理有更深的理解。

3、对该理论在实践中的应用有深刻的理解

通过把该算法的内容,算法的执行顺序在计算机上实现,知道和理解了该理论在计算机中是怎样执行的,对该理论在实践中的应用有深刻的理解。

四、参考文献

[1]贺讯.编译方法学习指导与实践.北京:

机械工业出版社,第一版.2004年8月。

五、附录

1.单词编码文件ni.txt

and1

or11

begin2

program12

bool3

real13

+23

<=33

do4

then14

-24

<34

else5

true15

*25

<>35

end6

var16

/26

>36

false7

while17

.27

>=37

if8

标识符18

,28

integer9

整数19

:

29

not10

实数20

;30

(21

:

=31

)22

=32

char38

2.测试代码文件11.txt

programabc;

vara:

real;

begin

ifa<22.2thenx:

=c+d;

end

3.词法分析完整源代码

#include

#include

#include

#defineLENGTH61

#defineN100

/*********************************************************************/

typedefstructtoken

{

intlabel;

charname[30];

intcode;

intaddr;

}token;

typedefstructKeyWord

{

charname[30];

intcode;

}KeyWord;

typedefstructsymble

{

intnumber;

inttype;

charname[30];

}symble;

/*********************************************************************/

charch;

intvar_count;

interror_count;

intlabel_count;

intcode_count;

intaddr_count;

intLineOfPro;

charfilename[30];

FILE*KeyFin;

FILE*SourceFin;

FILE*TokenFout;

FILE*SymbleFout;

KeyWordkey[LENGTH];

tokenCurrentToken;

symbleCurrentSimble;

symbleSymbleList[N];

/*********************************************************************/

voidScanner();

voidScannerInit();

voidIsAlpha();

voidIsNumber();

voidIsAnotation();

voidIsChar();

voidIsOther();

voidOutPut();

voidError(inta);

intWordHave();

intstrcmp(char*s,char*t)

{

for(;*s==*t;s++,t++)

if(*s==0)return0;

return1;

}

/*********************************************************************/

intmain()

{

inti=0,j=0;

code_count=0;

LineOfPro=0;

var_count=0;

addr_count=1;

label_count=1;

for(i=0;i

{

SymbleList[i].number=0;

SymbleList[i].type=0;

for(j=0;j<30;j++)SymbleList[i].name[j]='\0';

}

Scanner();

system("pause");

return0;

}

/************************主程序***************************************/

voidScanner()

{

inti=0;error_count=0;

ScannerInit();

printf("***************************************");

printf("*L语言词法分析器);

printf("***************************************");

printf("输入原文件名:

");

for(;;)

{

scanf("%c",&filename[i]);

if(filename[i]==10)

break;

i++;

}

filename[i]='\0';

if((SourceFin=fopen(filename,"rt"))==NULL)

{

printf("无法打开文件%s.\n",filename);

exit

(1);

}

if((TokenFout=fopen("token.txt","wt+"))==NULL)

{

printf("无法打开文件symble.txt\n");

exit

(1);

}

if((SymbleFout=fopen("symble.txt","wt+"))==NULL)

{

printf("无法打开文件symble.txt\n");

exit

(1);

}

ch=fgetc(SourceFin);

while(ch!

=EOF)

{

for(i=0;i<30;i++)CurrentToken.name[i]='\0';

if((ch>47)&&(ch<58))IsNumber();

else

{

if(((ch>64)&&(ch<90))||((ch>96)&&(ch<123))||(ch=='_'))IsAlpha();

else{if(ch=='\'')IsChar();

elseIsOther();

}

}

}

fclose(SourceFin);

fclose(TokenFout);

fclose(SymbleFout);

printf("分析完毕/\n");

}

/********************************初始化*******************************/

voidScannerInit()

{

inti=1;

intk=0;

if((KeyFin=fopen("ni.txt","rt"))==NULL)

{

printf("cannotopenni.txt\n");

exit

(1);

}

for(i=0;i<60;i++)

for(k=0;k<30;k++)key[i].name[k]='\0';

for(i=0;i<60;i++)

{

/*读入编码表*/

fscanf(KeyFin,"%s%d",key[i].name,&key[i].code);

}

fclose(KeyFin);

}

/*****************************数字处理********************************/

voidIsNumber()

{

intk=0;

intflag=0;

charch1;

while(((ch>47)&&(ch<58)))

{

CurrentToken.name[k++]=ch;

ch=fgetc(SourceFin);

if(ch=='.')

{

flag=1;

break;

}

}

CurrentToken.code=19;

CurrentToken.addr=addr_count++;

CurrentToken.label=label_count++;

if(flag)

{

ch1=fgetc(SourceFin);

if((ch1>47)&&(ch<58))CurrentToken.name[k++]=ch;

elseError

(2);

ch=ch1;

while((ch>47)&&(ch<58))

{

CurrentToken.name[k++]=ch;

ch=fgetc(SourceFin);

}

CurrentToken.code=20;

if(ch=='.')

{

Error

(2);

ch=fgetc(SourceFin);

while((ch>47)&&(ch<58))ch=fgetc(SourceFin);

}

}

if(((ch>64)&&(ch<90))||((ch>96)&&(ch<123)))

{

Error

(2);

while(((ch>64)&&(ch<90))||((ch>96)&&(ch<123)))

{

ch=fgetc(SourceFin);

while((ch>47)&&(ch<58))ch=fgetc(SourceFin);

}

}

OutPut();

}

/*************************字母处理************************************/

voidIsAlpha()

{

inti,h;

h=0;

i=0;

while(((ch>64)&&(ch<90))||((ch>96)&&(ch<123))||(ch=='_'))

{

CurrentToken.name[i++]=ch;

ch=fgetc(SourceFin);

}

for(i=1;i

{

h=strcmp(CurrentToken.name,key[i].name);

if(!

h)

break;

}

if(!

h)

{

CurrentToken.code=key[i].code;

CurrentToken.addr=-1;

}

else

{

CurrentToken.code=18;

CurrentToken.addr=addr_count++;

}

CurrentToken.label=label_count++;

OutPut();

}

/****************************字符串处理*******************************/

voidIsChar()

{

inti=0;

for(;;)

{

ch=fgetc(SourceFin);

CurrentToken.code=20;

if(ch!

='\'')CurrentToken.name[i++]=ch;

elsebreak;

}

CurrentToken.addr=addr_count++;

CurrentToken.label=label_count++;

OutPut();

ch=fgetc(SourceFin);

}

/*****************************

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 自然科学 > 生物学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1