词法分析程序设计 编译原理 C++ C#.docx

上传人:b****1 文档编号:14237716 上传时间:2023-06-21 格式:DOCX 页数:17 大小:19.43KB
下载 相关 举报
词法分析程序设计 编译原理 C++ C#.docx_第1页
第1页 / 共17页
词法分析程序设计 编译原理 C++ C#.docx_第2页
第2页 / 共17页
词法分析程序设计 编译原理 C++ C#.docx_第3页
第3页 / 共17页
词法分析程序设计 编译原理 C++ C#.docx_第4页
第4页 / 共17页
词法分析程序设计 编译原理 C++ C#.docx_第5页
第5页 / 共17页
词法分析程序设计 编译原理 C++ C#.docx_第6页
第6页 / 共17页
词法分析程序设计 编译原理 C++ C#.docx_第7页
第7页 / 共17页
词法分析程序设计 编译原理 C++ C#.docx_第8页
第8页 / 共17页
词法分析程序设计 编译原理 C++ C#.docx_第9页
第9页 / 共17页
词法分析程序设计 编译原理 C++ C#.docx_第10页
第10页 / 共17页
词法分析程序设计 编译原理 C++ C#.docx_第11页
第11页 / 共17页
词法分析程序设计 编译原理 C++ C#.docx_第12页
第12页 / 共17页
词法分析程序设计 编译原理 C++ C#.docx_第13页
第13页 / 共17页
词法分析程序设计 编译原理 C++ C#.docx_第14页
第14页 / 共17页
词法分析程序设计 编译原理 C++ C#.docx_第15页
第15页 / 共17页
词法分析程序设计 编译原理 C++ C#.docx_第16页
第16页 / 共17页
词法分析程序设计 编译原理 C++ C#.docx_第17页
第17页 / 共17页
亲,该文档总共17页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

词法分析程序设计 编译原理 C++ C#.docx

《词法分析程序设计 编译原理 C++ C#.docx》由会员分享,可在线阅读,更多相关《词法分析程序设计 编译原理 C++ C#.docx(17页珍藏版)》请在冰点文库上搜索。

词法分析程序设计 编译原理 C++ C#.docx

词法分析程序设计编译原理C++C#

Xxx大学

 

词法分析程序设计

 

实验课程:

编译原理

年级:

2014级

专业:

计算机科学与技术

班级:

2班

学号:

姓名:

指导教师:

目录

一.实验描述2

二.实验目的3

三.实验任务3

四.实验原理3

五.代码实现4

六.总结14

七.致谢词15

一.实验描述

运行环境:

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

19

;

20

=

21

<

22

>

23

*

24

**

25

>=

26

<=

27

!

=

28

2.状态转换图

3.程序流程

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

二.实验目的

三.实验任务

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

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

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

四.实验原理

charset[1000],str[500],strtaken[20];//set[]存储代码,strtaken[]存储当前字符

charsign[50][10],constant[50][10];//存储标识符和常量

定义了一个Analyzer类

classAnalyzer{

public:

Analyzer();//构造函数~Analyzer();//析构函数

intIsLetter(charch);//判断是否是字母,是则返回1,否则返回0。

intIsDigit(charch);//判断是否为数字,是则返回1,否则返回0。

voidGetChar(char*ch);//将下一个输入字符读到ch中。

voidGetBC(char*ch);//检查ch中的字符是否为空白,

若是,则调用GetChar直至ch进入一个非空白字符。

voidConcat(char*strTaken,char*ch);//将ch中的字符连接到strToken之后。

intReserve(char*strTaken);//对strTaken中的字符串查找保留字表,若是一个保留字返回它的数码,否则返回0。

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

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

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

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

五.代码实现

#include"stdafx.h"

#include"stdio.h"

#include"string.h"

#include"iostream"

usingnamespacestd;

charset[1000],str[500],strtaken[20];//set[]存储代码,strtaken[]存储当前字符

charsign[50][10],constant[50][10];//存储标识符和常量

//intWords[500][10];

charch;//当前读入字符

intsr,to=0;//数组str,strtaken的指针

intst=0,dcount=0;

intid=0;

staticintline=1;

inth,l;

typedefstructWords/*放置二元组*/

{

intnum;

charletters[20];

}DS;

DSWords[500];

typedefstructwords

{

charword[20];

inttype;

}WORDS;

WORDSwords[]={

{"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},{"+",15},

{"-",16},{"(",17},

{")",18},{",",19},

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

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

{"*",24},{"**",25},

{">=",26},{"<=",27},

{"!

=",28}};

typedefstructkeytable/*放置关键字*/

{

charname[20];

intkind;

}KEYTABLE;

KEYTABLEkeyword[]={/*设置关键字*/

{"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},};

voidopenfile()/*打开文件*/

{cout<<"____________________________________________________"<

cout<<"____________________________________________________"<

FILE*fp;

chara,filename[10];

intn=0;

gets(filename);

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

{printf("cannotopenfile.\n");

//exit(0);}

else

while(!

feof(fp))/*文件不结束,则循环*/

{a=getc(fp);/*getc函数带回一个字符,赋给a*/

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

n++;}

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');}

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

{

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++;}}while(set[j]!

='\0');

str[sr]='\0';

}

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())//标识符和关键字判定

{while(IsLetter()||IsDigit())/*若第一个是字符,继续读取,直到出现空格*/

{Concat();

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

}

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

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

if(value==-1)/*如果返回值是-,那就是标识符,把它输出*/

{InsertId();/*插入标识符*/

}reflesh();

}

elseif(IsDigit())

{while(IsDigit())/*否则,若第一个是数字,继续读取,直到出现空格*/

{Concat();/*把ch中的字符放入strtaken[]*/

GetChar();

}

Retract();/*指示器sr回调一个字符位置,把ch置为空*/InsertConst();/*插入常数,返回类型为int*/

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

//getchar();

reflesh();

}

else

switch(ch)/*否则,若是下面的符号*/

{

case'+':

case'-':

case'(':

case')':

case',':

case';':

case'=':

case'<':

case'>':

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<

cout<<"输出标识符:

"<

for(intsign_i=0;sign_i

cout<

cout<

cout<<"输出常量:

"<

for(intconst_i=0;const_i

cout<

cout<

}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;//thereisacomment

n:

=j+m;

Ifn>=3andn<5

thenj:

=j-1;

end.

结果截图:

六.总结

我在这次词法分析器的设计过程中学到了很多东西,其中最大的收获是对于编译原理中的词法分析这一过程理解的更加清楚明了。

其次,是在使用c++编程的能力有所提高。

当然,在该词法分析器设计中也有一些不足的地方,比如能识别的关键字有限,并不能识别所有的关键字,识别不出字符常量等。

分析结果输出方式为:

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

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

七.致谢词

感谢XXX老师对我们的悉心教导以及提供我们这样一个学以致用的机会。

通过这一阶段对编译原理课程的学习,特别是通过这次对于词法分析器的编程实践,我对于编译原理中的词法分析这一过程理解的更加清楚明了,收获很大。

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

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2