编译原理实验报告词法分析器内含源代码.docx

上传人:b****5 文档编号:5971477 上传时间:2023-01-02 格式:DOCX 页数:16 大小:150.93KB
下载 相关 举报
编译原理实验报告词法分析器内含源代码.docx_第1页
第1页 / 共16页
编译原理实验报告词法分析器内含源代码.docx_第2页
第2页 / 共16页
编译原理实验报告词法分析器内含源代码.docx_第3页
第3页 / 共16页
编译原理实验报告词法分析器内含源代码.docx_第4页
第4页 / 共16页
编译原理实验报告词法分析器内含源代码.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

编译原理实验报告词法分析器内含源代码.docx

《编译原理实验报告词法分析器内含源代码.docx》由会员分享,可在线阅读,更多相关《编译原理实验报告词法分析器内含源代码.docx(16页珍藏版)》请在冰豆网上搜索。

编译原理实验报告词法分析器内含源代码.docx

编译原理实验报告词法分析器内含源代码

编译原理实验

(一)

——词法分析器

实验描述

运行环境:

VC++2008

对某特定语言A,构造其词法规则。

该语言的单词符号包括:

1该程序能识别的单词符号及类别说明表

单词

类别

PROGRAM

0

NOT

1

BEGIN

2

IF

3

END

4

THEN

5

VAR

6

ELSE

7

INT

8

WHILE

9

AND

10

DO

11

OR

12

标识符

13

常数

14

+

15

-

16

17

18

5

19

20

=

21

<

22

>

23

*

24

**

25

>=

26

<=

27

!

=

28

2状态转换图

數宇

其它

3程序流程:

 

词法分析作成一个子程序,由另一个主程序调用,每次调用返回一个单词对应的二元组,输出标识符表、常数表由主程序来完成。

2.实验目的

通过动手实践,使学生对构造编译系统的基本理论、编译程序的基本结构有更为深入的理解和掌握;使学生掌握编译程序设计的基本方法和步骤;能够设计实现编译系统的重要环节。

同时增强编写和调试程序的能力。

3.实验任务

编制程序实现要求的功能,并能完成对测试样例程序的分析。

四.实验原理

 

intReserve(char*strTaken);//对strTaken中的字符串查找保留字表,若是一个保留

字返回它的数码,否则返回0。

voidRetract(char*ch);//将搜索指针器回调一个字符位置,将ch置为空白字符。

voidinput();//向存放输入结果的字符数组输入一句语句。

voiddisplay();//输出一些程序结束字符显示样式

intanalyzerSubFun();//词法分析器子程序,为了实现词法分析的主要功能。

五.代码实现

//cifa.cpp:

定义控制台应用程序的入口点

//#include"stdafx.h"

#include"stdio.h"

#include"string.h"

#include"iostream"

//set[]存储代码,strtaken[]存储当前字符

//存储标识符和常量

的指针

usingnamespacestd;

charset[1000],str[500],strtaken[20];charsign[50][10],constant[50][10];

//intWords[500][10];charch;//当前读入字符intsr,to=0;//数组str,strtakenintst=0,dcount=0;

intid=0;

staticintline=1;inth,l;

typedefstructWords/*放置二元组*/{

intnum;charletters[20];

"program",0},"not",1},"begin",2},"end",3},"if",4},"then",5},"var",6},"else",7},"int",8},"while",9},"and",10},"do",11},"or",12},

}DS;

DSWords[500];

typedefstructwords{

charword[20];

inttype;

}WORDS;

WORDSwords[]={

{

{

{

{{{{{{{{{{

{"+",15},{"-",16},{"(",17},{")",18},

{",",19},

{";",20},{"=",21},

{"<",22},{">",23},

25},

};

typedefstructkeytable{

charname[20];intkind;

/*设置关键字*/"program",0},"not",1},"begin",2},"end",3},"if",4},"then",5},"var",6},"else",7},"int",8},"while",9},"and",10},"do",11},"or",12},

}KEYTABLE;

KEYTABLEkeyword[]={

{

{

{

{

{

{

{

{

{

{

{

{

{

};

voidopenfile()/*打开文件*/

{

cout<<""<

cout<<"词法分析器"<

cout<<""<

cout<<"请在本程序根目录下寻找以.txt”为结尾的文件作为词法分析对象,输入文件名"<

chara,filename[10];

intn=0;

gets(filename);

if((fp=fopen(filename,"r"))==NULL)

{

//exit(0);

}

else

while(!

feof(fp))

{

a=getc(fp);

set[n]=a;

n++;

}

printf("cannotopenfile.\n");

/*文件不结束,则循环*/

/*getc函数带回一个字符,赋给a*/

/*文件的每一个字符都放入set[]数组中*/

fclose(fp);set[n-1]='\0'

voidreflesh()/*清空strtaken数组*/

{

to=0;/*全局变量to是strtaken的指示器*/

strcpy(strtaken,"");

}

voidpre1()/*预处理程序*/

{

inti,a,b,n=0;

do

{

if(set[n]=='/'&&set[n+1]=='*')

{

a=n;/*记录第一个注释符的位置*/while(!

(set[n]=='*'&&set[n+1]=='/'))

{

if(set[n]=='\n')

line++;

n++;

}

b=n+1;/*记录第二个注释符的位置*/

for(i=a;i<=b;i++)/**/

set[i]='';/*把注释的内容换成空格,等待第二步预处理*/}

elseif(set[n]=='/'&&set[n+1]=='/')

{

a=n;/*记录第一个注释符的位置*/while(!

set[n]=='\n')

n++;

b=n+1;/*记录第二个注释符的位置*/for(i=a;i<=b;i++)/**/

set[i]='';/*把注释的内容换成空格,等待第二步预处理*/}

n++;

}while(set[n]!

='\0');

}

intj=0;

sr=0;

/*全局变量sr是str[]的指示器*/

do

if

(set[j]==''||set[j]==

'\n')

while(set[j]==

||set[j]=='\n')/*扫描到有连续的空格或换行符

*/

{if(set[j]==

'\n')line++;

j++;

 

str[sr]=

/*用一个空格代替扫描到的连续空格和换行符放入str[]*/

sr++;

else

 

str[sr]=set[j];

/*若当前字符不为空格或换行符就直接放入str[]*/

sr++;

j++;

 

charGetChar()/*把字符读入全局变量ch中,指示器sr前移*/{

ch=str[sr];

sr++;

return(str[sr-1]);}

voidGetBC()/*开始读入符号,直至第一个不为空格*/{

while(ch=='')

{ch=GetChar();

}

}

voidConcat()/*把ch中的字符放入strtaken[]*/

{

strtaken[to]=ch;

to++;/*全局变量to是strtaken的指示器*/

strtaken[to]=

'\0'

 

}

intIsLetter()/*判断是否为字母*/

{

if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))return

(1);

elsereturn(0);

}

intIsDigit()/*判断是否为数字*/

{

if(ch>='0'&&ch<='9')

return

(1);

elsereturn(0);

}

intReserve()/*对strtaken中的字符串查找保留字表,若是则返回它的编码,否则返回-*/{

inti,k=0;

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

{

if(stricmp(strtaken,keyword[i].name)==0)

{k=1;

Words[dcount].num=keyword[i].kind;strcpy(Words[dcount].letters,"-");

dcount++;

return(keyword[i].kind);

}

}

if(k!

=1)

return(-1);}

voidRetract()/*指示器sr回调一个字符位置,把ch置为空*/

{

sr--;

ch='';}

intInsertId()

{

inti,k;

for(i=0;i

{k=strcmp(strtaken,sign[i]);

if(k==0)return(i);

}

strcpy(sign[id],strtaken);/*插入标识符*/Words[dcount].num=13;

strcpy(Words[dcount].letters,strtaken);id++;dcount++;

return(id-1);

}

intInsertConst()

{

inti,k;

for(i=0;i

{

k=strcmp(strtaken,constant[i]);

if(k==0)

return(i);

}

strcpy(constant[st],strtaken);/*插入常数*/Words[dcount].num=14;strcpy(Words[dcount].letters,strtaken);

st++;dcount++;

return(st-1);}

voidanalysis()

{

intvalue;

reflesh();/*清空strtaken数组*/

pre1();/*预处理,使注释内容换成单个空格,放回set[]中*/

pre2();/*预处理,使set[]中连续的空格置换成单个空格,并把set[]的内容放到str[]中*/

sr=0;

GetChar();

/*把字符读入全局变量ch中,指示器sr前移*/

GetBC();

/*读取第一个字符*/

while(ch!

='\0')

/*当不等于结束符,继续执行*/

if(IsLetter())//标识符和关键字判定

}

reflesh();

}

Concat();

for(intc0=15;c0<=23;c0++)

{

if(stricmp(strtaken,words[c0].word)==0)

{

Words[dcount].num=words[c0].type;

dcount++;

}

}reflesh();

break;default:

if(ch=='*')/*如果是"*"符号,继续读取下一个*/{

Concat();/*判断是否为"**"的情况*/

GetChar();

if(ch==strtaken[0])

Concat();

else

Retract();

for(intc1=24;c1<=25;c1++)

{

if(stricmp(strtaken,words[c1].word)==0)

{Words[dcount].num=words[c1].type;

dcount++;

}

}

//printf("%s",strtaken);

//getchar();

reflesh();

break;

}

elseif(ch=='<'||ch=='>'||ch=='!

')

{

Concat();/*判断是否为<=,>=,!

=的情况*/

GetChar();

if(ch=='=')

Concat();

else

Retract();

for(intc2=26;c2<=28;c2++)

if(stricmp(strtaken,words[c2].word)==0)

Words[dcount].num=words[c2].type;dcount++;

}

}

reflesh();

break;

}

else

{h=ch/line;

l=ch%line;

cout<<"Errorin"<

//getchar();

break;

}

}

GetChar();

GetBC();

}

cout<<"输出二元组:

"<

for(intd_i=0;d_i

cout<

cout<<"输出标识符:

"<

for(intsign_i=0;sign_i

cout<<"输出常量:

"<

for(intconst_i=0;const_i

}

int_tmain(intargc,_TCHAR*argv[])

{

openfile();analysis();

printf("Analysisisfinished!

");

getchar();

return0;

测试结果

测试语句为:

Programexample;

varintj,m,n;

Begin/*thereis*a

/comment*/i:

=2;j:

=6;

m:

=3;//thereisacommentn:

=j+m;

Ifn>=3andn<5

thenj:

=j-1;

end.

结果截图:

m

ithere

>is

>A.

Iconsent

脑出常量’

12

六.总结

我在这次词法分析器的设计过程中学到了很多东西,其中最大的收获是对

于编译原理中的词法分析这一过程理解的更加清楚明了。

其次,是在使用C++编

程的能力有所提高。

当然,在该词法分析器设计中也有一些不足的地方,比如能

识别的关键字有限,并不能识别所有的关键字,识别不出字符常量等。

分析结果输出方式为:

用一个存放结果的字符串数组,并用指针指向它,输出结果正确,但是输出结果比较乱。

不过总的来说,这次实验达到了其初衷,实现了规定的功

八.致谢词:

感谢XXX老师对我们的悉心教导以及提供我们这样一个学以致用的机会通过这一阶段对编译原理课程的学习,特别是通过这次对于词法分析器的编程实践,我对于编译原理中的词法分析这一过程理解的更加清楚明了,收获很大。

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

当前位置:首页 > 求职职场 > 简历

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

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