词法分析器的设计实验.docx

上传人:聆听****声音 文档编号:768086 上传时间:2023-04-30 格式:DOCX 页数:14 大小:106.87KB
下载 相关 举报
词法分析器的设计实验.docx_第1页
第1页 / 共14页
词法分析器的设计实验.docx_第2页
第2页 / 共14页
词法分析器的设计实验.docx_第3页
第3页 / 共14页
词法分析器的设计实验.docx_第4页
第4页 / 共14页
词法分析器的设计实验.docx_第5页
第5页 / 共14页
词法分析器的设计实验.docx_第6页
第6页 / 共14页
词法分析器的设计实验.docx_第7页
第7页 / 共14页
词法分析器的设计实验.docx_第8页
第8页 / 共14页
词法分析器的设计实验.docx_第9页
第9页 / 共14页
词法分析器的设计实验.docx_第10页
第10页 / 共14页
词法分析器的设计实验.docx_第11页
第11页 / 共14页
词法分析器的设计实验.docx_第12页
第12页 / 共14页
词法分析器的设计实验.docx_第13页
第13页 / 共14页
词法分析器的设计实验.docx_第14页
第14页 / 共14页
亲,该文档总共14页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

词法分析器的设计实验.docx

《词法分析器的设计实验.docx》由会员分享,可在线阅读,更多相关《词法分析器的设计实验.docx(14页珍藏版)》请在冰点文库上搜索。

词法分析器的设计实验.docx

一、实验目的和要求

加深对状态转换图的实现及词法分析器的理解。

熟悉词法分析器的主要算法及实现过程。

要求学生掌握词法分析器的设计过程,并实现词法分析。

二、实验基本内容

1、格式

输入:

打开一个C语言程序的源代码文件,将其读入程序输入框。

处理:

对输入框中的代码进行词法分析,分离出关键字、标识符、数值、运算符和界符。

输出:

在词法分析结果表中输出每个单词对应的编码和值。

其中,编码是自定义的,一种类型对应一组编码。

2、编译对象

变量声明和其它标记赋值语句

分支结构语句循环语句

3、实现过程

在词法分析程序设计中,先以只读方式读取一个文件,自文件头开始扫描文本,滤去开头的空格、回车符、换行符等!

读取的字符送入缓冲区。

扫描第一个字符,看匹配的类型,并进行相应的类型分析,满足判断类型时,输出其种别码和值。

判断时要注意保留字和识别符之间的不同,单目运算符和双目运算符之间的不同。

因此可用指针进行处理。

还必须熟悉字符串函数的使用。

并要对非法字符作出错误提示。

文本扫描结束要判断词法分析是否成功。

最后是关闭文件,释放指针。

给出一个简单语言的词法规则,画出状态转换图,并依据状态转换图编制出词法分析程序,能从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。

并依次输出各个单词的内部编码及单词符号自身值(遇到错误时可显示“Error”,然后跳过错误部分继续显示)

词法规则如下:

单词符号

种别码

内码

单词符号

种别码

内码

auto

101

long

121

break

102

new

122

case

103

operator

123

char

104

private

124

class

105

protected

125

const

106

public

126

continue

107

register

127

default

108

return

128

delete

109

short

129

do

110

sizeof

130

double

111

static

131

else

112

struct

132

enum

113

switch

133

extern

114

template

134

float

115

this

135

for

116

typedef

136

friend

117

union

137

if

118

virtual

138

inline

119

void

139

int

120

while

140

单词符号

种别码

内码

单词符号

种别码

内码

201

234

202

->

235

*

203

·

236

/

204

[

237

%

205

]

238

++

206

239

--

207

240

208

241

>=

209

{

242

210

}

243

<=

211

#

244

==

212

245

213

标识符

300

&&

214

常数

400

二进制形式

||

215

!

216

<<

217

>>

218

~

219

|

220

^

221

&

222

223

+=

224

-=

225

*=

226

/=

227

%=

228

>>=

229

<<=

230

&=

231

^=

232

|=

233

三、实验步骤

1.基本思想

从源程序中依次读入字符并解析,与关键字、运算符、结束符进行比较,得出其中的关键字,并将它存入到数组中去。

2.程序流程图

3.实验的输入源文件(input.txt)

inta=3;doubleb=4;intc;doubled=5;if(a>b)c=a;

elsec=b;if(c

4.实验输出截图

为了便于语法分析程序使用此法分析程序的结果,将此法分析程序的结果输出到output.txt

文件中,其内容如下所示:

5.实验源代码:

#include#include#include#defineMaxSize1 17

#defineMaxSize2 20

#defineMaxSize3 4structTNode

{

charvalue[20];intnumber;

chardescription[20];

}KeyWords[MaxSize1],Operation[MaxSize2],EndOperation[MaxSize3];

char

*WordsBuff[MaxSize1]={"const","long","float","double","void","main","if","else","

then","break","int","char","include","for","while","printf","scanf"};

char *OperationBuff[MaxSize2]={"+","-","*","/","+=","-=","*=","++","--

","<","<=",">",">=","<>","=","(",")","#","{","}"};

charEndOperationBuff[MaxSize3]={'',';','\n','\t'};TNodeTable1[500];

TNodeVariable[100];

TNodeConst[100];

voidinputKeyWords(char*buff[],intsize)

{

for(inti=0;i

{

strcpy(KeyWords[i].value,buff[i]);KeyWords[i].number=i+1;

strcpy(KeyWords[i].description,"关键字");

}

}

voidinputOperation(char*buff[],intsize)

{

for(inti=0;i

{

strcpy(Operation[i].value,buff[i]);Operation[i].number=i+50;

strcpy(Operation[i].description,"运算符");

}

}

voidinputEndOperation(charbuff[],intsize)

{

for(inti=0;i

{

EndOperation[i].value[0]=buff[i];EndOperation[i].value[1]='\0';EndOperation[i].number=i+100;

strcpy(EndOperation[i].description,"结束符");

}

}

voidoutputInfo(TNodea[],intsize)

{

for(inti=0;i

{

printf("(%d",a[i].number);printf("\t");printf("%s)",a[i].value);printf("\t");printf(a[i].description);printf("\n");

}

}

voidoutInfoToFile(TNodea[],intsize,FILE*out)

{

for(inti=0;i

{

fprintf(out,"(%d",a[i].number);fprintf(out,"\t");fprintf(out,"%s)",a[i].value);fprintf(out,"\t");fprintf(out,a[i].description);fprintf(out,"\n");

}

}

chargetChar(FILE*fp)

{

charch=fgetc(fp);returnch;

}

intisOperation(chara[])

{

intresult;

for(inti=0;i

{

result=strcmp(a,Operation[i].value);if(result==0)

{

returni;break;

}

}

return-1;

}

intisKeyWords(chara[])

{

intresult;

for(inti=0;i

{

result=strcmp(a,KeyWords[i].value);if(result==0)

{

returni;break;

}

}

return-1;

}

intisEndOperation(chara)

{

for(inti=0;i

{

if(a==EndOperation[i].value[0])

{

returni;break;

}

}

return-1;

}

intisChar(chara)

{

if(a>='a'&&a<='z')return1;

elseif(a>'A'&&a<='Z')return1;

else

return0;

}

intisDigit(chara)

{

if(a>='0'&&a<='9')return1;

else

return0;

}

intcount=0;intcount1=0;intcount2=0;

intstart1(FILE*in)

{

charbuff[20];

charnextchar[2];chartemp[20];inti=0;

inta;

charop[3];op[2]='\0';

nextchar[0]=fgetc(in);nextchar[1]='\0';while(nextchar[0]!

=EOF)

{

if(isChar(nextchar[0]))

{

buff[i]=nextchar[0];i++;nextchar[0]=fgetc(in);

}

elseif(isDigit(nextchar[0]))

{

buff[i]=nextchar[0];i++;nextchar[0]=fgetc(in);

}

elseif(nextchar[0]=='\r'||nextchar[0]=='\n')

{

buff[i]='\0';a=isKeyWords(buff);if(a!

=-1&&i>0)

{

strcpy(Table1[count].value,KeyWords[a].value);Table1[count].number=KeyWords[a].number;

}

elseif(i>0)

{

strcpy(Table1[count].description,KeyWords[a].description);count++;

i=0;

if(isChar(buff[0]))

{

strcpy(Variable[count1].value,buff);Variable[count1].number=count1;

strcpy(Variable[count1].description,"标识符");

count1++;i=0;

}

elseif(isDigit(buff[0]))

{

strcpy(Const[count2].value,buff);Const[count2].number=count2;

strcpy(Const[count2].description,"常量");

count2++;i=0;

}

}

else

{

}

nextchar[0]=fgetc(in);

}

elseif(isEndOperation(nextchar[0])!

=-1)

{

buff[i]='\0';a=isKeyWords(buff);if(a!

=-1&&i>0)

{

strcpy(Table1[count].value,KeyWords[a].value);Table1[count].number=KeyWords[a].number;strcpy(Table1[count].description,KeyWords[a].description);strcpy(temp,KeyWords[a].value);

count++;i=0;

}

elseif(i>0)

{

if(isChar(buff[0]))

{

strcpy(Variable[count1].value,buff);Variable[count1].number=count1;

strcpy(Variable[count1].description,"标识符");

count1++;i=0;

}

elseif(isDigit(buff[0]))

{

strcpy(Const[count2].value,buff);Const[count2].number=count2;

strcpy(Const[count2].description,"常量");

count2++;i=0;

}

}

else

{

}

nextchar[0]=fgetc(in);

}

elseif((a=isOperation(nextchar))!

=-1)

{

buff[i]='\0';a=isKeyWords(buff);if(a!

=-1&&i>0)

{

strcpy(Table1[count].value,KeyWords[a].value);Table1[count].number=KeyWords[a].number;strcpy(Table1[count].description,KeyWords[a].description);count++;

i=0;

}

elseif(i>0)

{

if(isChar(buff[0]))

{

strcpy(Variable[count1].value,buff);

Variable[count1].number=count1;

strcpy(Variable[count1].description,"标识符");count1++;

i=0;

}

elseif(isDigit(buff[0]))

{

strcpy(Const[count2].value,buff);Const[count2].number=count2;

strcpy(Const[count2].description,"常量");

count2++;i=0;

}

}

else

{

}

op[0]=nextchar[0];nextchar[0]=fgetc(in);if(nextchar[0]!

='@')

{

if(isOperation(nextchar)!

=-1)

{

op[1]=nextchar[0];if((a=isOperation(op))!

=-1)

{

strcpy(Table1[count].value,Operation[a].value);Table1[count].number=Operation[a].number;

strcpy(Table1[count].description,Operation[a].description);

count++;nextchar[0]=fgetc(in);

}

else

{

strcpy(Table1[count].value,op);Table1[count].number=-1;

strcpy(Table1[count].description,"未定义的运算符");

count++;nextchar[0]=fgetc(in);

}

}

else

{

op[1]='\0';



a=isOperation(op);strcpy(Table1[count].value,Operation[a].value);Table1[count].number=Operation[a].number;strcpy(Table1[count].description,Operation[a].description);

count++;}}}}

returncount;

}

voidmain()

{

inputKeyWords(WordsBuff,MaxSize1);inputOperation(OperationBuff,MaxSize2);inputEndOperation(EndOperationBuff,MaxSize3);FILE*in,*out;

boolFlag=true;while(Flag)

{

printf("源文件的位置:

D:

\\input.txt\n");if((in=fopen("D:

\\input.txt","r"))==NULL)

{

printf("读取源文件失败!

\n");

exit(0);

}

if((out=fopen("D:

\\output.txt","w"))==NULL)

{

printf("打开文件失败!

\n");exit(0);

}

intMaxSize=start1(in);

printf("关键字及运算符\n");

fprintf(out,"关键字及运算符\n");outputInfo(Table1,MaxSize);outInfoToFile(Table1,MaxSize,out);

printf("标识符表:

\n");

fprintf(out,"标识符表:

\n");outputInfo(Variable,count1);outInfoToFile(Variable,count1,out);

printf("常量表:

\n");

fprintf(out,"常量表:

\n");outputInfo(Const,count2);outInfoToFile(Const,count2,out);Flag=false;

fclose(in);

fclose(out);

}

}

四、实验中发现的问题和遇到的困难:

4.1分析出的关键字、运算符、标识符等的保存问题

4.2文本文件中的转义字符问题

五、问题及困难的解决:

5.1:

对于保存的问题,我们设计了一种数据结构如下所示:

structTNode

{

charvalue[20];//存放标识符的值intnumber; //存放标识符的种别码chardescription[20];//描述

}

软后申明这种类型的数组来保存关键字、运算符、标识符和常量等。

5.2:

转义字符是C语言中表示字符的一种特殊形式。

通常使用转义字符表示ASCII码字符集中不可打印的控制字符和特定功能的字符,如用于表示字符常量的单撇号( '),用于表示字符串常量的双撇号( ")和反斜杠( \)等。

转义字符用反斜杠\后面跟一个字符或一个八进制或十六进制数表示,文本文件中的打一下回车键对应的字符是’\r’’\n’,是两个字符

六、总结

第一个编译原理课程实验已经结束了,在这一个星期里的时间里,通过实验,让我感受到许多不足。

历本次实训,从中学到很多东西,这次实训的宝贵经验也肯定将会成为我在以后成长道路上的一笔丰富财富!

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

当前位置:首页 > IT计算机 > 电脑基础知识

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

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