编译原理实验之语法分析程序.docx

上传人:b****5 文档编号:30221514 上传时间:2023-08-07 格式:DOCX 页数:22 大小:61.04KB
下载 相关 举报
编译原理实验之语法分析程序.docx_第1页
第1页 / 共22页
编译原理实验之语法分析程序.docx_第2页
第2页 / 共22页
编译原理实验之语法分析程序.docx_第3页
第3页 / 共22页
编译原理实验之语法分析程序.docx_第4页
第4页 / 共22页
编译原理实验之语法分析程序.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

编译原理实验之语法分析程序.docx

《编译原理实验之语法分析程序.docx》由会员分享,可在线阅读,更多相关《编译原理实验之语法分析程序.docx(22页珍藏版)》请在冰豆网上搜索。

编译原理实验之语法分析程序.docx

编译原理实验之语法分析程序

 

《编译原理》实验报告

——之语法分析程序

 

姓名:

卢旭

学号:

U200917806

班级:

软工0901班

2011年10月22日

目录

一、实验题目3

一、实验题目

编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。

单词符号

单词符号

种别编码

单词值

main

1

 

int

2

 

float

3

 

double

4

 

char

5

 

if

6

 

else

7

 

do

8

 

while

9

 

l(l|d)*

10

内部字符串

(+|-|ε)dd*(.dd*|ε)(e(+|-|ε)dd*|ε)

20

二进制数值表示

=

21

 

+

22

-

23

 

*

24

 

/

25

 

26

 

27

 

{

28

 

}

29

 

30

 

;

31

 

>

32

 

>=

33

 

<

34

 

<=

35

 

==

36

 

!

=

37

 

语法结构定义:

<表达式>:

:

=<项>{+<项>|-<项>}

<项>:

:

=<因子>{*<因子>|/<因子>}

<因子>:

:

=ID|num|(<表达式>)

num:

:

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

ID:

:

=字母(字母|数字)*

字母:

:

=a|b|c…|z|A|B|C…|Z

数字:

:

=0|1|2…|9

二、实验目的

1)练习用C语言来编写语法分析程序

2)加深对编译原理中语法分析流程的理解

三、实验要求

输入单词串,以‘#’结束,如果是文法正确的句子,则输出成功信息,打印“success”,否则输出“error”。

例如:

输入:

begina:

=9;x:

=2*3;b:

=a+xend#

输出success

输入x:

=a+b*cend#

输出error

四、实验设计

基本设计思路

1)关键字表置初值:

char*rwtab[6]={"begin","if","then","while","do","end"};识别出标识符,然后查这个关键字表,给出相应的种别码;

2)识别无符号整数是将数字串转换为无符号整数。

3)设计扫描函数scanner(),扫描程序每次读取1个独立意义的单词符号,并判断单词类型;

4)递归下降分析法是对文法的每个非终结符编制一个递归过程(函数),按规则右部符号串的顺序编写:

若为终结符,则读下一个单词符号;非终结符,调用相应的递归过程(函数)。

流程框图

图C2.1函数E

图C2.2函数T

图C2.3函数F

算法设计

设置全局变量

1)charch字符变量,存放当前读进的源程序字符。

2)chartoken[8]字符数组,存放构成单词符号的字符串。

3)charprog[80]字符数组,存放所有用户输入的字符。

4)intsyn整数,存放当前单词的种别码。

5)doublesum双精度浮点型变量,存放无符号整数,或者浮点数。

6)intisDecimal整数,是否为浮点数。

值为1,则为浮点数。

7)doubledecimal双精度浮点型变量(double),浮点数的小数部分。

8)intisExp整数,是否为指数形式表示的浮点数(即是否存在符号E或者e)。

值为1,则为指数形式。

9)intindex整数,指数形式的幂。

10)intisNegative整数,是否为负数幂。

值为1,则为负数幂。

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

12)intrepeat;是否连续出现+,-。

设置函数:

1)scanner()扫描子程序。

2)getchar()从控制台读取一个字符数据。

3)doublepow(doublex,doubley),计算x的y次幂。

4)intstrcmp(char*str1,char#str2),字符串比较。

5)voidE();递归下降分析程序中,为非终结符E编写的函数

6)voidT();递归下降分析程序中,为非终结符T编写的函数

7)voidF();递归下降分析程序中,为非终结符F编写的函数

函数相关说明

voidE()

{

T();

while((syn==22)||(syn==23))

{

scanner();

T();

}

}

voidT()

{

F();

while((syn==24)||(syn==25))

{

scanner();

F();

}

}

voidF()

{

if((syn==20)||(syn==10))

scanner();

elseif(syn==26)

{

scanner();

E();

if(syn==27)

{

scanner();

}

elseisError=1;

}

elseisError=1;

}

输入与输出

输入:

所给文法的源程序字符串。

(字符串以“#”号结束)

输出:

success是文法正确句子

error不是文法正确句子

例如:

输入begina:

=9;x:

=2*3;b:

=a+xend#输出success.

程序运行结果

五、实验实现方式

在windows7下,借助vc6.0++,用C语言实现;

采用递归下降分析法做语法分析;

六、分析器使用说明

1)输入待识别字符串,并以“#”结尾

2)回车后程序自动输出语法分析结果

七、心得与体会

因为之前只是听了课,上机之前木有自己去写过代码,因此上机课还是没有做出来,以至于直接放弃走了,连调试都没有做……这是很失败的地方……以后一定得提前写出代码,然后直接拿到现场去做调试!

这样就能很快的解决问题!

通过这次实验后,基本上掌握了采用递归下降分析法来做语法分析,还是很有自豪感滴~~

八、源程序清单

#include

#include

#include

intisError;

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

chartoken[8];//存放词组

charch;//单个字符

intsyn,p,m,n;//syn:

种别编码

doublesum;

intcount;

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

intisDecimal;//是否是小数

doubledecimal;//小数

intisExp;//是否是指数

intindex;//指数幂

intisNegative;//是否带负号

doubletemp;

inttemp2;

intrepeat;//是否连续出现+,-

voidscanner();

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

voidE();

voidT();

voidF();

voidscanner();

voidmain()

{

p=0;

count=0;

isDecimal=0;

index=0;

repeat=0;

printf("\npleaseinputthesourcestring:

\n");

do{

ch=getchar();

prog[p++]=ch;

}while(ch!

='#');

p=0;

isError=0;

scanner();

if((syn==20)||(syn==10)||(syn==26))

{

E();

}

if((ch=='#')&&(isError==0))

printf("success\n");

else

printf("error\n");

}

voidE()

{

T();

while((syn==22)||(syn==23))

{

scanner();

T();

}

}

voidT()

{

F();

while((syn==24)||(syn==25))

{

scanner();

F();

}

}

voidF()

{

if((syn==20)||(syn==10))

scanner();

elseif(syn==26)

{

scanner();

E();

if(syn==27)

{

scanner();

}

elseisError=1;

}

elseisError=1;

}

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;//标识符

//如果是"begin","if","then","while","do","end"标识符中的一个

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=20;

}

elseswitch(ch)

{

case'<':

m=0;

token[m++]=ch;

ch=prog[p++];

if(ch=='=')

{

syn=35;

token[m++]=ch;

}

else

{

syn=34;

p--;

}

break;

case'>':

m=0;

token[m++]=ch;

ch=prog[p++];

if(ch=='=')

{

syn=33;

token[m++]=ch;

}

else

{

syn=32;

p--;

}

break;

case'=':

m=0;

token[m++]=ch;

ch=prog[p++];

if(ch=='=')

{

syn=36;

token[m++]=ch;

}

else

{

syn=21;

p--;

}

break;

case'+':

temp2=prog[p];

token[m++]=ch;

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

{

isSignal=2;

ch=prog[p++];

repeat=0;

gotoIsNum;

}

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

{

repeat=1;

//ch=prog[p++];

}

syn=22;

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=23;

break;

/*

case'*':

syn=24;

token[m++]=ch;

break;

*/

case'*':

temp2=prog[p];

token[m++]=ch;

if(temp2=='+')

{

isSignal=2;

repeat=1;

}

elseif(temp2=='-')

{

isSignal=1;

repeat=1;

}

syn=24;

break;

case'/':

syn=25;

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=26;

break;

case')':

syn=27;

token[m++]=ch;

break;

case'{':

syn=28;

token[m++]=ch;

break;

case'}':

syn=29;

token[m++]=ch;

break;

case',':

syn=30;

token[m++]=ch;

break;

case';':

syn=31;

token[m++]=ch;

break;

case'#':

syn=0;

token[m++]=ch;

break;

default:

syn=-1;

}

}

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

当前位置:首页 > 考试认证 > IT认证

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

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