实验《编译原理》词法分析程序设计方案.docx

上传人:b****1 文档编号:2627978 上传时间:2023-05-04 格式:DOCX 页数:21 大小:52.61KB
下载 相关 举报
实验《编译原理》词法分析程序设计方案.docx_第1页
第1页 / 共21页
实验《编译原理》词法分析程序设计方案.docx_第2页
第2页 / 共21页
实验《编译原理》词法分析程序设计方案.docx_第3页
第3页 / 共21页
实验《编译原理》词法分析程序设计方案.docx_第4页
第4页 / 共21页
实验《编译原理》词法分析程序设计方案.docx_第5页
第5页 / 共21页
实验《编译原理》词法分析程序设计方案.docx_第6页
第6页 / 共21页
实验《编译原理》词法分析程序设计方案.docx_第7页
第7页 / 共21页
实验《编译原理》词法分析程序设计方案.docx_第8页
第8页 / 共21页
实验《编译原理》词法分析程序设计方案.docx_第9页
第9页 / 共21页
实验《编译原理》词法分析程序设计方案.docx_第10页
第10页 / 共21页
实验《编译原理》词法分析程序设计方案.docx_第11页
第11页 / 共21页
实验《编译原理》词法分析程序设计方案.docx_第12页
第12页 / 共21页
实验《编译原理》词法分析程序设计方案.docx_第13页
第13页 / 共21页
实验《编译原理》词法分析程序设计方案.docx_第14页
第14页 / 共21页
实验《编译原理》词法分析程序设计方案.docx_第15页
第15页 / 共21页
实验《编译原理》词法分析程序设计方案.docx_第16页
第16页 / 共21页
实验《编译原理》词法分析程序设计方案.docx_第17页
第17页 / 共21页
实验《编译原理》词法分析程序设计方案.docx_第18页
第18页 / 共21页
实验《编译原理》词法分析程序设计方案.docx_第19页
第19页 / 共21页
实验《编译原理》词法分析程序设计方案.docx_第20页
第20页 / 共21页
亲,该文档总共21页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

实验《编译原理》词法分析程序设计方案.docx

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

实验《编译原理》词法分析程序设计方案.docx

实验《编译原理》词法分析程序设计方案

实验1-3《编译原理》S语言词法分析程序设计方案

一、实验目的

了解词法分析程序的两种设计方法之一:

根据状态转换图直接编程的方式;

二、实验内容

1.根据状态转换图直接编程

编写一个词法分析程序,它从左到右逐个字符的对源程序进行扫描,产生一个个的单词的二元式,形成二元式(记号)流文件输出。

在此,词法分析程序作为单独的一遍,如下图所示。

具体任务有:

(1)组织源程序的输入

(2)拼出单词并查找其类别编号,形成二元式输出,得到单词流文件

(3)删除注释、空格和无用符号

(4)发现并定位词法错误,需要输出错误的位置在源程序中的第几行。

将错误信息输出到屏幕上。

(5)对于普通标识符和常量,分别建立标识符表和常量表(使用线性表存储),当遇到一个标识符或常量时,查找标识符表或常量表,若存在,则返回位置,否则返回0并且填写符号表或常量表。

标识符表结构:

变量名,类型(整型、实型、字符型),分配的数据区地址

注:

词法分析阶段只填写变量名,其它部分在语法分析、语义分析、代码生成等阶段逐步填入。

常量表结构:

常量名,常量值

三、实验要求

1.能对任何S语言源程序进行分析

在运行词法分析程序时,应该用问答形式输入要被分析的S源语言程序的文件名,然后对该程序完成词法分析任务。

2.能检查并处理某些词法分析错误

词法分析程序能给出的错误信息包括:

总的出错个数,每个错误所在的行号,错误的编号及错误信息。

本实验要求处理以下两种错误(编号分别为1,2):

1:

非法字符:

单词表中不存在的字符处理为非法字符,处理方式是删除该字符,给出错误信息,“某某字符非法”。

2:

源程序文件结束而注释未结束。

注释格式为:

/*……*/

四、保留字和特殊符号表

单词代码

1

2

3

4

5

6

7

8

9

单词

int

char

float

void

const

for

if

else

then

单词助记符

int

char

float

void

const

for

if

else

then

内码值

-

-

-

-

-

-

-

-

-

单词代码

10

11

12

13

14

15

16

17

18

单词

while

switch

break

begin

end

标识符

数字(包括整数和实数)

单词助记符

while

switch

break

begin

end

id

num

内码值

-

-

-

-

-

在符号表中的位置

在常数表中的位置

单词代码

19

20

21

22

23

24

25

26

27

单词

+

-

*

/

%

[

]

单词助记符

+

-

*

/

%

[

]

内码值

-

-

-

-

-

-

-

-

-

单词代码

28

28

29

30

单词

!

=

<

>

<=

>=

==

{

}

单词助记符

rlop

{

}

内码值

!

=

<

>

<=

>=

==

-

-

单词代码

37

38

39

40

41

42

43

44

45

单词

/=

+=

-=

*=

%=

||

&&

!

=

单词助记符

/=

+=

-=

*=

%=

or

and

not

=

内码值

-

-

-

-

-

-

-

-

-

单词的构词规则:

字母=[A-Za-z]

数字=[0-9]

标识符=(字母|_)(字母|数字)*

数字=数字(数字)*(.数字+|ε)

四、S语言表达式和语句说明

1.算术表达式:

+、-、*、/、%

2.关系运算符:

>、>=、<、<=、==、!

=

3.赋值运算符:

=,+=、-=、*=、/=、%=

4.变量说明:

类型标识符变量名表;

5.类型标识符:

intcharfloat

6.If语句:

if表达式then语句[else语句]

7.For语句:

for(表达式1;表达式2;表达式3)语句

8.While语句:

while表达式do语句

9.S语言程序:

由函数构成,函数不能嵌套定义。

函数格式为:

返回值函数名(参数)

{

数据说明

语句

}

五、程序参考结构说明

1.Initscanner函数:

程序初始化:

输入并打开源程序文件和目标程序文件,初始化保留字表

2.Scanner函数:

若文件未结束,反复调用lexscan函数识别单词。

3.Lexscan函数:

根据读入的单词的第一个字符确定调用不同的单词识别函数

4.Isalpha函数:

识别保留字和标识符

5.Isnumber函数:

识别整数,如有精力,可加入识别实数部分工功能

6.Isanotation函数:

处理除号/和注释

7.Isother函数识别其他特殊字符

8.Output函数:

输出单词的二元式到目标文件,输出格式(单词助记符,单词内码值),如(int,-)(rlop,>)……

9.Error函数:

输出错误信息到屏幕

10.除此之外,还可以设置查符号表,填写符号表等函数,学生可自行设计。

实验中,可以将某些类型的单词识别过程利用DFA算法实现,DFA算法参考如下:

DFA(S=S0,MOVE[][],F[],ALPHABET[],ALLS[])

/*S为状态,初值为DFA的初态,MOVE[][]为状态转换矩阵,F[]为终态集,ALPHABET[]为字母表,其中的字母顺序与MOVE[][]中列标题的字母顺序一致。

ALLS[]为状态集*/

{

CharWordbuffer[10]=“”//单词缓冲区置空

Nextchar=getchar();//读字符

i=0;

while(nextchar!

=NULL)//NULL代表此类单词

{if(nextchar!

∈ALPHABET[]){ERROR(“非法字符”),return(“非法字符”);}

S=MOVE[S][nextchar]//下一状态

if(S=NULL)return(“不接受”);//下一状态为空,不能识别,单词错误

wordbuffer[i]=nextchar;//保存单词符号

i++;

nextchar=getchar();

}

Wordbuffer[i]=‘\0’;

If(S∈F)return(wordbuffer);//接受

Elsereturn(“不接受”);

}

六、实验过程说明

1.每人单独完成。

2.完成后,由老师验收,并给出成绩。

3.实验完成后,写出实验报告(要求交打印稿)。

报告内容要求如下:

完成人:

班级、学号、姓名

一、实验名称:

简化S语言词法分析器

二、实验目的:

通过手工编写简化C语言词法分析器,熟悉并深入理解编译程序词法分析器的工作原理。

三、实验内容:

1.根据保留字和特殊符号表能区分出源文件中的保留字、普通标识符和特殊符号,并能进行简单的错误处理。

…………

七、测试源程序示例:

//aa.c

voidaa()

{

floatrate,circle;

rate=3;

circle=3.14*rate*rate;

}

输出结果:

(1)输出结果文件:

(void,-)(id,0)((,-)(),-)({,-)(float,-)(id,1)……

(2)标识符的符号表:

Nametypeaddress

0

aa

1

rate

2

circle

3

4

5

(3)常数表:

Namevalue

0

3

1

3.14

2

3

实验地点:

教10五楼计算机学院软一机房

实验时间:

第4周周二3单元、周四1单元、第五周周二3单元

八、实验代码

#include

#include

#include

#include

#defineMAX10//保留字符号长度

#defineMAXSIZE45//保留字和特殊符号表长度

#defineNUM30//标识符和常数的个数

FILE*in,*out;//指向文件的指针

charinfile[MAX];//文件名字

chartoken[MAX];

charWord[NUM][MAX];//标识符

charconsts[NUM][MAX];//常数

charlownum[NUM][MAX]={"0","1","2","3","4","5","6","7","8","9",

"10","11","12","13","14","15","16","17","18","19"

"20","21","22","23","24","25","26","27","28","29"};//自定义表

intn=1;//行号

intnum=0;//错误统计数

typedefstructKey_word//保留字和特殊符号表结构

{

//intkeyNum;

charkeyWord[MAX];

charkeySign[MAX];

charkeyValue[MAX];

}Key_word;

//初始化保留字表

Key_wordKey[MAXSIZE]={{"int","int","-"},{"char","char","-"},{"float","float","-"},

{"void","void","-"},{"const","const","-"},{"for","for","-"},

{"if","if","-"},{"else","else","-"},{"then","then","-"},

{"while","while","-"},{"switch","switch","-"},{"break","break","-"},

{"begin","begin","-"},{"end","end","-"},{"","",""},

{"","",""},{"","id",""},{"","num",""},

{"+","+","-"},{"-","-","-"},{"*","*","-"},

{"/","/","-"},{"%","%","-"},{"(","(","-"},

{")",")","-"},{"[","[","-"},{"]","]","-"},

{"","",""},{"<","rlop","<"},{">","rlop",">"},

{"<=","rlop","<="},{">=","rlop",">="},{"=","rlop","="},

{"!

=","rlop","!

="},{";",";","-"},{"","",""},

{"/=","/=","-"},{"+=","+=","-"},{"-=","-=","-"},

{"*=","*=","-"},{"%=","%=","-"},{"||","or","-"},

{"&&","and","-"},{"!

","not","-"},{"=","=","-"}};

//打开关闭文件

intInitscanner()

{

printf("请输入要输入的文件:

\n");

scanf("%s",infile);

if((in=fopen(infile,"r"))==NULL)

{

printf("cannotopeninfile!

\n");

return0;

}

if((out=fopen("word.txt","a+"))==NULL)

{

printf("cannotopenoutfile!

\n");

return0;

}

return0;

}

//写入文件

voidOutput(intn,intm)

{

fputs("(",out);

fputs(Key[n].keySign,out);

fputs(",",out);

if(m==-1)

fputs(Key[n].keyValue,out);

else

fputs(lownum[m],out);//下标

fputs(")",out);

}

//Isalpha函数:

识别保留字和标识符

intIsalpha()

{

inti;

for(i=0;i<16;i++)//关键字

{

if(strcmp(token,Key[i].keyWord)==0)

{

Output(i,-1);

return0;

}

}

//标识符Word[NUM][MAX]

for(i=0;i

{

if((Word[i][0]!

=NULL)&&strcmp(token,Word[i])==0)

{

Output(16,i);

return0;

}

if(Word[i][0]==NULL)

{

strcpy(Word[i],token);

Output(16,i);

return0;

}

}

return0;

}

intIsnumber()//Isnumber函数:

consts[NUM][MAX]

{

inti;

for(i=0;i

{

if((consts[i][0]!

=NULL)&&strcmp(token,consts[i])==0)

{

Output(17,i);

return0;

}

if(consts[i][0]==NULL)

{

strcpy(consts[i],token);

Output(17,i);

return0;

}

}

return0;

}

voidremove()//扫描指针回退一个字符

{

fseek(in,-1,SEEK_CUR);

}

//Isanotation函数:

处理除号/和注释

voidIsanotation()//提示第一个字符已经存为/了

{

charch,pre;

ch=getc(in);

if(ch=='=')//"/="

Output(36,-1);

elseif(ch=='*')//"/*"

{

ch=getc(in);

do{

if(feof(in))

{

num++;

printf("\n第(%d)行:

注释错误:

/*后面的字符全部当做注释,缺少结束注释*/\n",n);

break;

}

pre=ch;

ch=getc(in);

}while(pre!

='*'||ch!

='/');

}

else//"/"

{

remove();//指针回退一个字符

Output(21,-1);

}

}

//Isother函数识别其他特殊字符

voidIsother()

{inti=1;intj=0;

charch;

if(token[0]=='<'||token[0]=='>'||token[0]=='!

'||token[0]=='%')

{

ch=getc(in);

if(ch=='=')

token[i++]=ch;

else

remove();

}

elseif(token[0]=='|')

{

ch=getc(in);

if(ch=='|')

token[i++]=ch;

else

remove();

}

elseif(token[0]=='&')

{

ch=getc(in);

if(ch=='&')

token[i++]=ch;

else

remove();

}

token[i]='\0';

for(i=18;i<45;i++)

{

if(strcmp(token,Key[i].keyWord)==0)

{

Output(i,-1);

break;

}

}

if(i==45)

{

num++;

printf("\n第(%d)行:

字符错误:

%s字符非法\n",n,token);

}

}

voidScanner()

{

charch;

inti;

ch=getc(in);

while(!

feof(in))

{

while(ch==''||ch=='\t'||ch=='\n')//先统计行数

{

if(ch=='\n')

++n;

ch=getc(in);

}

if(((ch>='a')&&(ch<='z'))||(ch=='_'))//标识符isalpha(ch)单词

{

i=1;

token[0]=ch;

ch=getc(in);

while(((ch>='a')&&(ch<='z'))||((ch>='0')&&(ch<='9')))//wordnumber

{

token[i++]=ch;

ch=getc(in);

}

token[i]='\0';

Isalpha();

}

elseif((ch>='0')&&(ch<='9'))//整数

{

i=1;

token[0]=ch;

ch=getc(in);

while(isdigit(ch))

{

token[i++]=ch;

ch=getc(in);

}

token[i]='\0';

Isnumber();

}

elseif(ch=='/')//区分"/","/=","/*"

{

token[0]=ch;

Isanotation();

ch=getc(in);

}

else//特殊字符

{

token[0]=ch;

Isother();

ch=getc(in);

}

}

}

voidshow()

{

inti;

charch;

printf("\n二元式:

\n");

rewind(out);

while(!

feof(out))

{

printf("%c",getc(out));

}

printf("\n标志符表\n");

for(i=0;i

{

if(Word[i][0]!

=NULL)

printf("%d,%s\n",i,Word[i]);

}

printf("\n常数表\n");

for(i=0;i

{

if(consts[i][0]!

=NULL)

printf("%d,%s\n",i,consts[i]);

}

}

voidmain()

{

Initscanner();

Scanner();

printf("\n共有%d个错误\n",num);

show();

fclose(in);

fclose(out);

}

九、实验结果

输入文件

voidaa()

begin

floatrate,circle;

rate=3;

circle=3.14*rate;/******/

end

输出文件

(void,-)

(id,0)

((,-)

(),-)

(begin,-)

(float,-)

(id,1)

(id,2)

(;,-)

(id,1)

(rlop,=)

(num,0)

(;,-)

(id,2)

(rlop,=)

(num,0)

(num,1)

(*,-)

(id,1)

(;,-)

(end,-)

十、实验总结

经过此次实验,了解了程序的词法构词规则和词法分析过程。

在实验过程中,得到了同学的帮助才得以完成。

本实验基本达到了老师的要求,实现了词法分析的基本功能。

 

B145112014405A114王自达

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

当前位置:首页 > 总结汇报 > 学习总结

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

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