编译原理第二次上机实验报告软工李U172xxWord文件下载.docx

上传人:b****5 文档编号:19850330 上传时间:2023-01-10 格式:DOCX 页数:26 大小:68.17KB
下载 相关 举报
编译原理第二次上机实验报告软工李U172xxWord文件下载.docx_第1页
第1页 / 共26页
编译原理第二次上机实验报告软工李U172xxWord文件下载.docx_第2页
第2页 / 共26页
编译原理第二次上机实验报告软工李U172xxWord文件下载.docx_第3页
第3页 / 共26页
编译原理第二次上机实验报告软工李U172xxWord文件下载.docx_第4页
第4页 / 共26页
编译原理第二次上机实验报告软工李U172xxWord文件下载.docx_第5页
第5页 / 共26页
点击查看更多>>
下载资源
资源描述

编译原理第二次上机实验报告软工李U172xxWord文件下载.docx

《编译原理第二次上机实验报告软工李U172xxWord文件下载.docx》由会员分享,可在线阅读,更多相关《编译原理第二次上机实验报告软工李U172xxWord文件下载.docx(26页珍藏版)》请在冰豆网上搜索。

编译原理第二次上机实验报告软工李U172xxWord文件下载.docx

内部字符串

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

20

二进制数值表示

=

21

+

22

-

23

*

24

/

25

26

27

{

28

}

29

30

;

31

>

32

33

<

34

35

==

36

!

37

#

(2)语法结构定义

表达式>

:

:

=<

项>

{+<

|-<

因子>

{*<

|/<

=ID|num|(<

num:

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

ID:

=字母(字母|数字)*

字母:

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

数字:

=0|1|2…|9

(3)语法分析器功能及基本要求

处理用户提交的符合上述文法的源代码序列,进行语法分析,并给出语法是否正确的结论。

(1)总体设计思想

利用自上而下的分析方法;

本实验所采用的是LL

(1)分析法即预测分析法;

每次通过词法分析模块读入一个完整的单词,在语法分析中判断正确性,最终将结果输出。

(2)详细算法设计

语法分析

用字母替代后写成如下:

E→T{+T|-T}

T→F{*F|/F}

F→i|n|(E)

将该扩充文法还原

EE+T|E-T|T

TT*F|T/F|F

F(E)|i|n

消除非终结符E、T的直接左递归后,文法变为

ETE’

E’+TE’|-TE’|ε

TFT’

T’*FT’|/FT’|ε

此文法是LL

(1)文法

求出该文法的预测分析表

i

n

-

*

/

$

E

ETE’

E’(e)

E’+TE’

E’TE’

E’ε

T

TFT’

TF’

T’(t)

T’ε

T’*FT’

T’/FT’

F

Fi

Fn

F(E)

根据预测分析表、分析栈和一个总控程序来判断一个语句是否正确;

(3)流程框图

(4)函数相关说明

charinput[300];

//存放输入的字符串

chartoken[20];

//存放符合C语言词法规则的单词

charch;

//单个字符

charprevious;

//ch的前一个字符

charlatter;

//ch的后一个字符

charch1,ch2;

//当处理注释的时候使用

inttypenum;

//表示单词的种别码

intp,m,n,cx;

doubledecimal;

//记录小数

doublesum;

//存放数字

intindex;

//存放指数

intisNum;

//是否是数字

intisDecimal;

//记录是否为小数

intisExp;

//记录是否为指数

intisNegative;

//是否带负号(对于指数)

intisNegative1;

//是否为负数

charX,a;

charstack[200];

voidscanner();

char*rwtab[11]={"

main"

"

int"

float"

double"

char"

if"

else"

while"

do"

end"

};

//记录预测分析表,0表示没有产生式,其他数字表示产生式的序号

intList[5][9]={

{1,2,0,0,0,0,3,0,0},

{0,0,4,5,0,0,0,6,7},

{8,9,0,0,0,0,10,0,0},

{0,0,11,12,13,14,0,15,16},

{17,18,0,0,0,0,19,0,0}

};

charreturnResult()函数返回n、i、e、+、-、*、/、(、);

voidscanner()扫描函数判断种别码

boolisVT(charx)判断是否为终结符

boolcheckList(intx,inty)查询是否在分析表中

intgetX()、intgetY()获取要查询数组M[X,a]元素的下标

voidmakeTop()把栈顶放入X中

voidpush(intxy)将y1y2...yn逆序放入S栈中

intmain()主函数

(5)输入与输出(包括出错处理)

输入以$结束回车即可运行程序

输出success!

或者unsuccess!

或者error!

unsuccess!

出错分为两种情况

1.词法错误:

error!

2.词法正确但语法错误:

unsuccess!

(6)程序运行结果(屏幕截图)

(7)词法分析器使用说明

打开编译器VS或者VC++;

文件新建项目;

将代码复制粘贴,编译运行,按照提示输入即可使用;

(8)心得与体会

加强了自己对于LL

(1)分析法的理解与记忆;

第二次试验难度要大于第一次;

主要难在求预测分析表;

开始由于预测分析表求错误导致程序运行一直出错也不知道到底bug出在哪里,后来才发现自己预测分析表求错了;

对于词法分析实验一已经给出,预测分析总控制程序算法书本上已经给出;

所以最大的难点就是求预测分析表;

这需要足够的耐心和细心才能保证FIRSE集和FOLLOW集不多一个,也不漏掉其中一个;

后期需要加强练习;

(9)源程序清单

//语法编译器01.cpp:

定义控制台应用程序的入口点。

//

#include"

stdafx.h"

#include<

stdio.h>

string.h>

math.h>

charreturnResult()

scanner();

switch(typenum)

{

case20:

return'

n'

//表示返回一个数字number

case10:

i'

//表示返回id

case22:

+'

case23:

-'

case24:

*'

case25:

/'

case26:

('

case27:

)'

case0:

$'

default:

e'

//表示error!

}

voidscanner()

cx=0;

//用来记录小数点后面的位数

m=0;

sum=0;

decimal=0;

index=0;

isDecimal=0;

isNegative=0;

isNegative1=0;

isExp=0;

for(n=0;

n<

8;

n++)

token[n]='

\0'

ch=input[p++];

//处理回车换行空格

while((ch=='

'

)||(ch==9)||(ch==10))

{

ch=input[p++];

}

//处理注释

if(ch=='

ch1=input[p];

if(ch1=='

do

{

ch=input[p++];

ch2=input[p];

}while((ch!

='

)||(ch2!

));

p=p+1;

ch=input[p++];

if(((ch>

a'

)&

&

(ch<

z'

))||((ch>

A'

Z'

)))//如果当前ch为字母

while(((ch>

0'

9'

)))

token[m++]=ch;

token[m++]='

typenum=10;

//10表示l(l|d)*

p=p-1;

//回退一步

for(n=0;

n<

10;

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

typenum=n+1;

break;

elseif((ch>

))

isNum:

while((ch>

sum=sum*10+(ch-'

);

if(ch=='

.'

isDecimal=1;

while(ch>

&

ch<

cx=cx+1;

decimal=decimal*10+(ch-'

}

if(ch=='

typenum=-1;

return;

for(inta=0;

a<

cx;

a++)

decimal=decimal*0.1;

sum=sum+decimal;

if((ch=='

)||(ch=='

E'

isExp=1;

isNegative=1;

//表示指数为负数

isNegative=0;

//表示指数为正

while((ch>

index=index*10+(ch-'

if(isNegative==1)//如果指数为负数

for(intk=0;

k<

index;

k++)

sum=sum*0.1;

else

sum=sum*10;

if(isNegative1==1)

sum=sum*(-1);

p--;

typenum=20;

//表示为数字

//运算符、界运算符

else{

switch(ch)

case'

='

typenum=21;

case'

previous=input[p-2];

latter=input[p];

//当+号前面为空或者(或者=并且后面为数字时,+表示正负号;

if(((previous=='

)||(previous=='

))&

((latter>

(latter<

isNegative1=0;

//表示此+号为正负号

gotoisNum;

//当+号前面为+、-、*、/号且后面为数字时,-号表示正负号;

elseif(((previous=='

//如果+号后面是+、-号,则表示为加减号

elseif((latter=='

)||(latter=='

typenum=22;

token[m++]=ch;

break;

//如果+号后面是字母;

elseif(((latter>

))||((latter>

elseif((((previous>

(previous<

))||((previous>

)))&

=0)||(latter<

//当-号前面为空或者(或者=并且后面为数字时,-表示正负号;

isNegative1=1;

//当-号前面为+、-、*、/号且后面为数字时,-号表示正负号;

//如果-号后面是+、-号,则表示为加减号

typenum=23;

//如果-号后面是字母;

//如果前面为字母或者数字且后面为数字,则表示-号

typenum=24;

typenum=25;

'

typenum=33;

typenum=32;

p--;

typenum=35;

typenum=34;

typenum=26;

typenum=27;

{'

typenum=28;

}'

typenum=29;

typenum=30;

typen

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

当前位置:首页 > 成人教育 > 自考

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

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