LL1语法分析设计原理与实现技术实验报告

时间:2020-10-08 08:37:12 手机站 来源:网友投稿

LL(1)语法分析设计原理与实现技术

实验报告

变更说明

日期

版本

变更位置

变更说明

作者

2014/4/30

1、0

初稿生成

房皓

、 实 验目的 :

本实验的目的在于在教师的引导下以问题回朔与思维启发的方式 , 使学生在 不断的探究过程中掌握编译程序设计与构造的基本原理与实现技术 , 启迪学生的 抽象思维、激发学生的学习兴趣、培养学生的探究精神与专业素养 , 从而提高学 生发现问题、分析问题与解决问题的能力。

、实验内容

[ 实验项目 ]

实现LL(1)分析中控制程序(表驱动程序);完成以下描述算术表达式的LL(1)文 法的LL(1)分析程序。

G[E]: E — TE

E'— ATE | &

T— F「

T'— MFT | &

F— (E)|i

A—+|-

M—*|/

[ 实验说明 ]

终结符号 i 为用户定义的简单变量 , 即标识符的定义。

[ 设计要求 ]

输入串应就是词法分析的输出二元式序列 ,即某算术表达式“实验项目 一”的输出结果。输出为输入串就是否为该文法定义的算术表达式的判断结果

LL(1) 分析过程应能发现输入串出错 ;

设计两个测试用例 (尽可能完备,正确与出错), 并给出测试结果。

三、实验环境

操作系统 :Windows 7 软件: VC++6、 0

四、程序功能描述

提供了文件输入方式 , 且输入的内容为二元式序列 ; 能够对输入的字符串做出正确的 LL(1) 分析判断,并给出判断结果 ,判断结果 输出到文件 , 并显示在屏幕 ;

能发现输入串中的错误 ,包含非法字符 , 输入不匹配等 ; 能够处理一些可预见性的错误 ,如文件不存在 , 输入非法等。

五、数据结构设计

全局:

MAX 50

ch^r dn^lvseSt^cl<[MAX]; 丿/勺?析丰戋

char toRen[HAJ<]|; "匾人車

typedef= struct CSS "严主式结构体

<

char loft;

char Klgtlt[5];

int rightlength;

}CSS; _

CSS E,G9G1,T9H,H1,F.F1PA,A1PM JI1 ;|

CSS anali)5elable[7][8];

局部(mai n()中):

int nain()

<

C1 h 3 厂 a "

int i=0,j = 0fni,u=6(u=n; "i指示栈顶位貳j扌繇剩余串扫描位置

Int num un,num ut;

bool Flag=true;

char tokenl[MAK];

char token2[HAX];

FILE *fpin,*fpout;

六、程序结构描述

设计方法:

本程序采用从文件读取的输入方式,输入的内容需为二元式序列,然后按 照LL(1)分析的方法对输入的字符串进行分析判断 ,并输出判断结果,程序通

过对输入串的检查能够发现输入串中的错误。 程序规定的单词符号及其种别

码见下表:

单词符号及其种别码表

单词符号

种别码

单词符号

种别码

(

1

*

5

)

2

/

6

+

3

i

7

-

4

#

8

分析表

i

+

-

*

/

(

)

#

E

E t TG

Et tg

G

Gt ATG

Gt ATG

G t£

Gt£

T

T t FH

T t FH

H

H t£

Ht£

Ht mfh

H t MFH

H t£

H t£

F

Ft i

Ft (E)

A

A t +

A t -

M

M t *

M t /

主要函数说明:

-Globals

P check_VT(chHr ch)

0 create_analyseT3ble[)

.error[FILE *lp|

9 gctnurn_VN(char ch)

? getnuni_VT[char ch)

.jiisWyfctiar chu int i]

check_VT(char ch):

bool型函数,检查ch就是否为终结字符,就是则返回true;

create_a nalyseTable():

构建分析表函数,无返回值;

error(FILE *fp):

输出错误,表示不就是该文法的句子,参数fp用于退出前将打开的文件关 闭;

get nu m_VN(char ch):

int型函数,查找ch在非终结字符中的位置并返回;

get nu m_VT(char ch):

int型函数,查找ch在终结字符中的位置并返回;

justify。:

bool型函数,判断文件读取内容就是否合法,包括检查非法字符与不匹配 现象,出错返回false否则返回true;

mai n():

主函数。

函数调用关系说明:

main()调用 check_VT(char ch)、create_analyseTable() error(FILE *fp)、 getnum_VN(char ch)、getnum_VT(char ch)、justify();

执行框图:

牛‘0进栈.当前终结符送吕读下苻入号

牛‘0进栈.当前终结符送吕

读下苻

七、实验过程结果截图

| input.trt -记善本

丈他号爲(E)梧式(0)童看M 嵇助(H)

斤i)(気后亿15 (反巧亿i)爲/)⑺Q [&町

£]?F:S诳二学朝偉谨屜爭刃竟宦甲每LL⑴语法分祈设汁腿

读入字符串询;丨i it

SUCCISS?

Press any key to continue

result txt -记事:舉

文件(F)輛? 袒式Q〕査看曲牯丽j SUCCESS'

测试用例二:i+i*i/#

| input.txt -込事本

K D"怎 炳 冗 i?反 D 6 /)teTS

? ■ F;滾大嘩二学期繰爰原理、硏空性黑蠱丄L;H会圭亠丁■鹿

费入字符串対:l+i**iz4t

AIL!

ress any key to continue

result.txt -记華茶

文的 jftStE) ^rt(O) S^M 粥助(H)

FAIL:

八、实验总结:

实验心得:

通过本次实验我锻炼了自己的上机操作能力及编程能力 ,并对理论知识有了

进一步的了解。老师提供的LL(1)分析法的流程图给了我很大的帮助,使得本 实验基本思路变得很清晰,用较为简单的算法就能实现,程序的难点就是产生 式结构体的构造、分析表的构造、解决实验中遇到的问题也花费了一部分时 间,我增长了处理关于文件错误的能力。

实验中遇到的问题及解决方法:

问题主要有

从文件输入二元式时,需要检查输入的内容就是否符合程序规定的字

符种别码,解决方法就是用了两个字符数组 token,token2分别记录种

别码与字符,并增加了一个函数justify()根据既定的种别码表判断;

当输入内容不匹配或输入内容非法时要退出程序 ,此时若不关闭已经

打开的文件可能导致文件内容受到破坏;解决方法就是给error()函数

设置一个文件指针变量参数FILE* fp,在退出程序之前通过fp关闭文 件

程序的自我评价 :

此程序实现了要求中的所有功能 ,并增加了输入串错误检测的功能 ,但因编程 能力及经验的有限 ,其中有的地方不免有些繁杂 ,还有一些潜藏的问题 ,需要进 一步测试与修改来提高程序的健壮性。

九、 程序清单 :

/**************************************************** 课题名称 :LL(1) 语法分析设计原理与实现技术 作者 :房皓 进修生最后修改时间 :2014、 4、30

***************************************************/

************************************************单词符号及其分类编码单词符号 种别码1234567

************************************************

单词符号及其分类编码

单词符号 种别码

1

2

3

4

5

6

7

8

/**********************

G[E]:

E t TE '

E、ATE ' | £

T t FT'

T't MFT ' |£

F t (E)|i

A t +|-

M t *|/

/********************

G[E]:

EtTG

Gt ATG| £

TtFH

HtMFH| £

文法

**********************

改为等价文法

**************

Ft(E)|i At+|- M t *|/

'*******************

'******************* ************************

'*******************

'******************* ************************

i

+

-

* / (

)

#

E

EtTG

EtTG

G

GtATG G tATG

G t£

G t£

T

TtFH

TtFH

H

H t£

H t£

H tMFH H tMFH

H t£

H t£

F

Fti

Ft(E)

A

At+

At-

M M t * M t /

***********************************************

#include<iostream> #include<conio 、 h> #include<string 、 h> using namespace std; #define MAX 50 char analyseStack[MAX]; char token[MAX]; typedef struct CSS {

char left;

//分析栈

//分析栈

//输入串

//产生式结构体

int right_length;

}CSS;

CSS E,G,G1,T,H,H1,F,F1,A,A1,M,M1;

CSS analyseTable[7][8];

void error(FILE *fp)

{ fprintf(fp,"%s","FAIL!"); fclose(fp); cout<<"FAIL!"<<endl; exit(0);

}

bool justify(char ch,int i) //判断文件读取内容就是否合法 ,包括检查非法字符与不匹配现

{

switch(ch)

{

case '1':

if(token[i]!='(')

return false;

break;

case '2':

if(token[i]!=')')

return false; break;

case '3':

if(token[i]!='+') return false;

break;

case '4':

if(token[i]!='-') return false;

break;

case '5':

if(token[i]!='*') return false;

break;

case '6':

if(token[i]!='/') return false;

break;

case '7':

if(token[i]!='i') return false;

break;

case '8':

if(token[i]!='#') return false;

break;

default:

return false; break;

}

return true;

}

bool check_VT(char ch)

{ if(ch=='i' || ch=='+' || ch=='-' || ch=='*' || ch=='/' || ch=='(' || ch==')') return true;

return false;

}

int getnum_VN(char ch)

{

char VN[7]={'E','G','T','H','F','A','M'};

int i; for(i=0;i<7;i++) if(ch==VN[i])

break;

return i;

}

int getnum_VT(char ch)

{

char VT[8]={'i','+','-','*','/','(',')','#'};

int i;

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

if(ch==VT[i]) break;

if(i==8)

{

cout<<"FAIL!"<<endl;

exit(0);

}

return i;

}

void create_analyseTable()

{

int i,j;

E、left='E';

strcpy(E、 right,"TG");

E、 right_length=2;

G、 left='G';

strcpy(G 、 right,"ATG");

G、 right_length=3;

G1、left='G'; strcpy(G1、right,"NULL");

G1、 right_length=0;

T、left='T';

strcpy(T、 right,"FH");

T、 right_length=2;

H 、 left='H';

strcpy(H 、right,"MFH");

H、 right_length=3;

H1、left='H'; strcpy(H1 、 right,"NULL");

H1、 right_length=0;

F、left='F';

strcpy(F、 right,"(E)");

F、 right_length=3;

F1、left='F';

strcpy(F1 、 right,"i");

F1、 right_length=1;

A 、 left='A';

strcpy(A 、 right,"+");

A 、 right_length=1;

A1、left='A';

strcpy(A1 、 right,"-");

A1 、 right_length=1;

M 、 left='M';

strcpy(M 、 right,"*");

M 、 right_length=1;

M1 、 left='M';

strcpy(M1 、 right,"/");

M1 、 right_length=1;

for(i=0;i<7;i++)

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

{

analyseTable[i][j] 、 left='N';

analyseTable[i][j] 、 right_length=0;

}

analyseTable[0][0]=E;

analyseTable[0][5]=E;

analyseTable[1][1]=G;

analyseTable[1][2]=G;

analyseTable[1][6]=G1;

analyseTable[1][7]=G1;

analyseTable[2][0]=T;

analyseTable[2][5]=T;

analyseTable[3][1]=H1;

analyseTable[3][2]=H1;

analyseTable[3][3]=H;

analyseTable[3][4]=H;

analyseTable[3][6]=H1;

analyseTable[3][7]=H1;

analyseTable[4][0]=F1;

analyseTable[4][5]=F;

analyseTable[5][1]=A;

analyseTable[5][2]=A1;

analyseTable[6][3]=M;

analyseTable[6][4]=M1;

}

int main()

{

char a,X;

int i=0,j=0,m,u=0,v=0; //i 指示栈顶位置 ,j 指示剩余串扫描位置 int num_vn,num_vt;

bool flag=true;

char token1[MAX];

char token2[MAX];

FILE *fpin,*fpout;

create_analyseTable(); //创建分析表

//读文件部分 if((fpin=fopen("input 、 txt","r"))==NULL)

{

cout<<" 文件打开失败! "<<endl; exit(0);

} if((fpout=fopen("result 、 txt","w"))==NULL)

{ fclose(fpin); cout<<" 文件打开失败! "<<endl; exit(0);

} token1[v++]=fgetc(fpin); while(!feof(fpin))

{ token1[v++]=fgetc(fpin); if((v%5)==0)

{ token2[u]=token1[v-4]; token[u]=token1[v-2]; if(justify(token2[u],u)) u++;

else

{

fclose(fpin); error(fpout);

}

}

}

fclose(fpin);

if((v-1)%5 != 0)

error(fpout);

}

}

cout<<" 读入字符串为 :"<<token<<endl;

//分析器部分 analyseStack[i++]='#';

analyseStack[i]='E';

a=token[j];

while(flag)

{

X=analyseStack[i]; if(check_VT(X))

if(X==a)

{

a=token[++j];

i--;

}

else

error(fpout);

else

if(X=='#')

if(X==a) flag=false;

else

{ fprintf(fpout,"%s","FAIL!"); cout<<"FAIL!"<<endl; fclose(fpout); exit(0);

}

else

{

num_vn=getnum_VN(X); num_vt=getnum_VT(a);

if(analyseTable[num_vn][num_vt] 、 left!='N')

{

if(analyseTable[num_vn][num_vt] 、 right_length!=0)

、right[m];{ m=analyseTable[num_vn][num_vt] 、 right_length-1; for(;m>=0;m--)

、right[m];

}

i--;

}

else error(fpout);

} fprintf(fpout,"%s","SUCCESS!"); fclose(fpout); cout<<"SUCCESS!"<<endl; return 1;

}

推荐访问:实验报告 语法 原理 实验 LL1语法分析设计原理与实现技术实验报告

版权声明 :以上文章中选用的图片文字均来源于网络或用户投稿 ,如果有侵权请立即联系我们 , 我们立即删除 。