词法分析实验报告.docx

上传人:b****5 文档编号:7906115 上传时间:2023-01-27 格式:DOCX 页数:16 大小:44.65KB
下载 相关 举报
词法分析实验报告.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

词法分析实验报告

大连民族学院

计算机科学与工程学院实验报告

实验题目:

词法分析

课程名称:

编译原理

实验类型:

□演示性□验证性□操作性□设计性□综合性

专业:

计算机科学与技术班级:

104姓名:

张家琪学号:

2010081427

实验日期:

2012年11月10日实验地点:

多媒体实验室

实验学时:

实验成绩:

指导教师签字:

2012年11月10日

实验报告正文部分(具体要求详见实验报告格式要求)

 

一、总体设计思想

1实验目的

设计编制并调试一个词法分析程序,加深对构造词法分析器的原理和技术的理解与应用。

2实验要求

针对计算机高级程序语言——C语言子语言,运用恰当的词法分析技术线路,设计和实现C语言子语言的词法分析器。

Ø编程语言:

C语言/JAVA语言

Ø平台选择:

Linux/Windows

Ø技术线路(任选其一)

⏹正规式→NFA→DFA→minDFA→程序设计

⏹正规文法→NFA→DFA→minDFA→程序设计

Ø词法分析器程序输出形式,参见◤输出形式设计◢

Ø词法分析器程序输出结果存入到磁盘文件中*

Ø具有出错处理功能

(带*号的实验要求为附加实验要求,可选择实现)

3词法分析器构造原理

C语言子语言词法描述——涉及的单词类如下:

(1)关键字

mainifelsewhiledoforintvoidchar

(2)运算符和界符

=

*

<

<=

>

>=

!

=

==

;

#

{

}

注:

#为结束标志符,详见◤程序框架◢

(3)标识符

正规式:

ID=letter(letter|digit)*

(4)整型常数

正规式:

NUM=digit(digit)*

二、种别码表设计及其在计算机中的存放表示

(1)单词种别码设计

单词种别码对照表

单词符号

种别码

单词符号

种别码

main

1

16

if

2

17

else

3

=

18

while

4

}

19

do

5

<

20

for

6

!

=

21

int

7

<=

22

char

8

>

23

void

9

>=

24

标识符

10

==

25

整型常数

11

;

26

{

12

27

13

28

14

#

0

*

15

(2)输出形式设计

词法分析器的输入是源程序字符串,输出是对应的单词串。

每个单词按照二元组(种别码,单词符号本身)格式输出。

例如:

假设源程序为

main()

{

x=9;

y=4;

if(x>0)

x=2*x+1/3;

}#

则词法分析器对应输出的结果是:

(1,main)(27,()(28,))(12,{)(10,x)(18,=)(11,9)(26,;)(10,y)(18,=)

(11,4)(26,;)(2,if)(27,()(10,x)(23,>)(11,0)(10,x)(18,=)(11,2)

(15,*)(10,x)(13,+)(11,1)(16,/)(11,3)(26,;)(19,})(0,#)

三、词法分析程序详细设计

1)算法构造思想

依据建立的识别单词的DFA,设计算法,其框架如下。

其中,

1syn存放单词的种别码;

2token存放符合C语言子语言词法规则的单词;

3sum存放整型常量的单词。

实现技术细节注意的几个要点:

A)标识符和关键字,属于同一构词规则,识别方法是建立一个关键字表,在识别出标识符单词时,查关键字表,以确认或区别是否是关键字,还是标识符。

B)对前导空格符、制表符和换行符,均须过滤;C)约定标识符单词32位有效。

2)主要模块算法的框图描述

 

四、 主要代码

#include

#include

#include

charprog[80];//存放所有输入字符

chartoken[32];//②token存放符合C语言子语言词法规则的单词;

charch;//单个字符

intsyn,p,m,n;//①syn存放单词的种别码

doublesum;//③sum存放整型常量的单词。

intcount;

intisSignal;//是否带正负号(0不带,1负号,2正号)

intisDecimal;//是否是小数

doubledecimal;//小数

intisExp;//是否是指数

intindex;//指数幂

intisNegative;//是否带负号

doubletemp;

inttemp2;

intrepeat;

voidscanner();

char*rwtab[9]={"main","if","else","while","do","for","int","char","void"};

voidmain()

{

p=0;

count=0;

isDecimal=0;

index=0;

repeat=0;

printf("\npleaseinputarangeofdata,withtheendof#:

\n");

do{

ch=getchar();

prog[p++]=ch;

}while(ch!

='#');/*#为结束标志符*/

p=0;

do{

scanner();//扫描,单词

switch(syn)

{

case11:

if(isDecimal==0)

{

//加了1个强制类型转换

printf("(%d,%d)",syn,(int)sum);

break;

}

elseif(isExp==1)

{

printf("(%d,%e)",syn,sum);

isExp=0;

isDecimal=0;

break;

}

elseif(isDecimal==1)

{

printf("(%d,%f)",syn,sum);

isDecimal=0;

break;

}

case-1:

printf("出错");

break;

default:

printf("(%d,%s)",syn,token);

}

}while(syn!

=0);

getchar();

}

voidscanner()

{

sum=0;

decimal=0;

m=0;

for(n=0;n<8;n++)

token[n]=NULL;

ch=prog[p++];//从prog中读出一个字符到ch中

while(ch=='')//跳过空字符(无效输入)

ch=prog[p++];

if(((ch>='a')&&(ch<='z'))||((ch>='A')&&(ch<='Z')))//ch是字母字符

{

while(((ch>='a')&&(ch<='z'))||((ch>='A')&&(ch<='Z'))||((ch>='0')&&(ch<='9')))

{

token[m++]=ch;//ch=>token

ch=prog[p++];//读下一个字符

}

token[m++]='\0';

p--;//回退一格

syn=10;

//如果是"main","if","else","while","do","for","int","char","void"标识符中的一个

for(n=0;n<9;n++)

if(strcmp(token,rwtab[n])==0)

{

syn=n+1;

break;

}

}

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

{

IsNum:

if(isSignal==1)

{

//token[m++]='-';

}

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

{

sum=sum*10+ch-'0';//ch中数字本身是当做字符存放的

ch=prog[p++];

}

if(ch=='.')

{

isDecimal=1;

ch=prog[p++];

count=0;//之前忘了清零,123.123+123.123#两个浮点数就无法识别

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

{

//pow(x,y)计算x的y次幂

temp=(ch-'0')*pow(0.1,++count);

decimal=decimal+temp;

//AddToDec();

ch=prog[p++];

}

sum=sum+decimal;

}

if(ch=='e'||ch=='E')

{

isExp=1;

ch=prog[p++];

if(ch=='-')

{

isNegative=1;

ch=prog[p++];

}

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

{

//指数

index=index*10+ch-'0';

ch=prog[p++];

}

//10的幂

//123e3代表123*10(3)

//sum=sum*pow(10,index);是错误的

if(isNegative)

sum=sum*pow(0.1,index);

else

sum=sum*pow(10,index);

}

if(isSignal==1)

{

sum=-sum;

isSignal=0;

}

p--;

syn=11;

}

elseswitch(ch)

{

case'<':

m=0;

token[m++]=ch;

ch=prog[p++];

if(ch=='!

')

{

syn=21;//<>对应21

token[m++]=ch;

}

elseif(ch=='=')

{

syn=22;

token[m++]=ch;

}

else

{

syn=20;

p--;

}

break;

case'>':

m=0;

token[m++]=ch;

ch=prog[p++];

if(ch=='=')

{

syn=24;

token[m++]=ch;

}

else

{

syn=23;

p--;

}

break;

case':

':

syn=17;

token[m++]=ch;

break;

case'+':

temp2=prog[p];

token[m++]=ch;

if((temp2>='0')&&(temp2<='9')&&(repeat==1))

{

isSignal=2;//isSignal正数

ch=prog[p++];

repeat=0;

gotoIsNum;

}

if(((temp2=='+')||(temp2=='-'))&&(repeat==0))//如果重复出现符号,才将后边的+,-视为正负号

{

repeat=1;

//ch=prog[p++];

}

syn=13;

break;

case'-':

temp2=prog[p];

token[m++]=ch;

if((temp2>='0')&&(temp2<='9')&&(repeat==1))

{

isSignal=1;

ch=prog[p++];//读“-”下一个字符

repeat=0;

gotoIsNum;//转到数字的识别

}

if(((temp2=='+')||(temp2=='-'))&&(repeat==0))//如果重复出现符号,才将后边的+,-视为正负号

{

repeat=1;//预言会重复

//ch=prog[p++];//读下一个字符

}

syn=14;

break;

case'*':

temp2=prog[p];

token[m++]=ch;

if(temp2=='+')

{

isSignal=2;

repeat=1;

}

elseif(temp2=='-')

{

isSignal=1;

repeat=1;

}

syn=15;

break;

case'/':

syn=16;

token[m++]=ch;

break;

case'=':

syn=18;

token[m++]=ch;

break;

case';':

syn=26;

token[m++]=ch;

break;

case'(':

temp2=prog[p];

token[m++]=ch;

if(temp2=='+')

{

isSignal=2;

repeat=1;

}

elseif(temp2=='-')

{

isSignal=1;

repeat=1;

}

syn=27;

break;

case'{':

temp2=prog[p];

token[m++]=ch;

if(temp2=='+')

{

isSignal=2;

repeat=1;

}

elseif(temp2=='-')

{

isSignal=1;

repeat=1;

}

syn=12;

break;

case'}':

temp2=prog[p];

token[m++]=ch;

if(temp2=='+')

{

isSignal=2;

repeat=1;

}

elseif(temp2=='-')

{

isSignal=1;

repeat=1;

}

syn=19;

break;

case')':

syn=28;

token[m++]=ch;

break;

case'#':

syn=0;

token[m++]=ch;

break;

default:

syn=-1;

}

}

五、设计体会与收获

通过这次试验我学会了如何设计编制并调试一个词法分析程序,加深对构造词法分析器的原理和技术的理解与应用。

也对编译原理有了更深的理解,又学会了一些小的c++的知识,程序需要不断调试才能有更好的收获,很开心又有了收获!

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

当前位置:首页 > 工作范文 > 行政公文

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

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