语法分析器Word文件下载.docx

上传人:b****5 文档编号:16859199 上传时间:2022-11-26 格式:DOCX 页数:25 大小:132.19KB
下载 相关 举报
语法分析器Word文件下载.docx_第1页
第1页 / 共25页
语法分析器Word文件下载.docx_第2页
第2页 / 共25页
语法分析器Word文件下载.docx_第3页
第3页 / 共25页
语法分析器Word文件下载.docx_第4页
第4页 / 共25页
语法分析器Word文件下载.docx_第5页
第5页 / 共25页
点击查看更多>>
下载资源
资源描述

语法分析器Word文件下载.docx

《语法分析器Word文件下载.docx》由会员分享,可在线阅读,更多相关《语法分析器Word文件下载.docx(25页珍藏版)》请在冰豆网上搜索。

语法分析器Word文件下载.docx

7)对任意句子使用当前文法归约,打印分析过程。

4、采用的数据结构

两个结构体:

//分析各非终结符的FIRSTVT集和LASTVT集时的栈元素

typedefstruct

{

charnonterm;

//非终结符

charterm;

//终结符

}StackElement;

//存放(A,a)的栈的初始化

StackElement*top;

//栈顶

StackElement*bottom;

//栈底

intstacksize;

//个数

}stack;

5、算法描述

算符优先分析法的具体过程如下:

1)按照实现定义的文件路径,使用ReadFile()函数中,将需要分析的文法通过输入流文件打开函数open()复制到sen[row][col]中。

2)利用FirstVt()构造产生式sen[row][col]的非终结符的FirstVt表。

先找出形如A->

…a…(a为第一个终结符)的产生式,把(A,a)压入Operator栈中。

从Operator栈顶抛出项(A,a),填入first表相应位置。

在找出形如B->

A…的产生式,把(B,a)压入Operator栈中。

循环直到Operator栈为空,此时FirstVt表构造完毕。

3)将产生式右部翻转,调用FirstVt函数求出LastVt表。

4)调用OpPriotable()构造算符优先关系表opTable。

先把产生式中所有终结符填入opTable表第一行和第一列,然后利用产生式和FirstVt表LastVt表分别找出满足=关系、<

关系、>

关系的算符填表。

若相应位已有关系,说明两个终结符之间至少有两种优先关系,该文法不是算符优先文法。

5)调用InputAnalyse()对输入句子进行分析。

初始化分析栈S,依次判断当前输入符a和分析栈中离栈顶最近的终结符S[j]的关系,若S[j]<

a,则a移近,若S[j]<

a,则往前找到第一个S[j]>

a,将S[j-1]到栈顶S[k]规约,若S[j]=a,如果S[j]=#,则接受,如果S[j]!

=#,则移进。

直到接受或者出错,算符优先分析结束。

6、运行结果

1.非算符优先文法的文法分析结果:

2.是算符优先文法的文法分析结果:

成功归约句子:

归约句子失败:

7、调试情况

如下所示为测试的文法:

其中文法不是算符优先文法,文法是算符优先文法。

8、设计技巧及体会

将算符优先法的手工分析过程用程序的方式写出来,实现了算符优先法的判断过程,很容易理解。

通过本次实验,我对算符优先法的分析过程更加熟练了,同时让我对本章内容有了更深入的理解。

9、源程序清单(电子版)

#include<

iostream>

#include<

fstream>

usingnamespacestd;

#definerow20

#definecol20

#defineSIZE20

//两个重要结构体的定义

//FIRSTVT表或LASTVT表中一个表项(A,a)结构体的初始化

typedefstruct

//读文件函数

intReadFile(charsen[][col])

ifstreamfin;

inti=0;

fin.open("

e:

//in2.txt"

ios:

:

in);

cout<

<

"

文法的产生式为:

"

<

endl;

fin>

>

sen[0];

for(i=1;

!

fin.eof();

i++)

{

fin>

sen[i];

cout<

sen[i]<

}

returni;

}

//初始化(A,a)栈

voidInitStack(stack&

S)

S.bottom=newStackElement[SIZE];

S.top=S.bottom;

S.stacksize=SIZE;

//判断(A,a)栈是否为空

boolifEmpty(stackS)

if(S.top==S.bottom)

returntrue;

//如果栈为空,则返回true

returnfalse;

//否则不为空,返回false

//插入栈顶(A,a)元素

voidInsert(stack&

S,StackElemente)

if(S.top-S.bottom>

=S.stacksize)

栈已满,无法插入!

else

S.top->

nonterm=e.nonterm;

term=e.term;

S.top++;

//弹出栈顶(A,a)元素

StackElementPop(stack&

StackElemente;

e.nonterm='

\0'

;

e.term='

if(S.top==S.bottom)

栈为空,无法进行删除操作!

S.top--;

e.nonterm=S.top->

nonterm;

e.term=S.top->

term;

returne;

//终结符与非终结符的判断函数(布尔类型)

boolTerminalJud(charc)

if(c>

='

A'

&

&

c<

Z'

returnfalse;

//非终结符返回false

returntrue;

//终结符返回true

//判断非终结符在first表中是否已存在

boolItemJud(charfirst[][col],intfirst_len,charC)

for(inti=0;

i<

first_len;

if(first[i][0]==C)

returntrue;

//如果first表中已存在此非终结符c,则返回true

//FIRSTVT表和LASTVT表中表项的初始化

voidItemInit(charsen[][col],charfirst[][col],charlast[][col],intsen_len,int&

first_len)

{

inti;

first_len=1;

//是当前first和last表的长度

//初始化表

first[0][0]=sen[0][0];

last[0][0]=sen[0][0];

sen_len;

if(TerminalJud(sen[i][0])==false&

ItemJud(first,first_len,sen[i][0])==false)

{

first[first_len][0]=sen[i][0];

last[first_len][0]=sen[i][0];

first_len++;

}

//构造FIRSTVT集

voidFirstVt(charsen[][col],charfirst[][col],intsen_len,intfirst_len)//sen_len是产生式的个数

StackElementDFS,record[SIZE];

stackOperator;

//创建存放(A,a)的栈

inti,j,r=0;

InitStack(Operator);

//第一次扫描,将能直接得出的first(A,a)放进栈中

for(i=0;

sen_len;

for(j=3;

sen[i][j]!

j++)//候选式开始处

if(TerminalJud(sen[i][j])==true)//遇到的第一个终结符压入

{

intexist=0;

DFS.nonterm=sen[i][0];

DFS.term=sen[i][j];

for(inti1=0;

r;

i++)//当前(A,a)是否已在栈中

if(record[i1].nonterm==sen[i][0]&

record[i1].term==sen[i][j])

{

exist=1;

break;

}

//如果不在则压入栈中

record[r].nonterm=sen[i][0];

record[r].term=sen[i][j];

if(exist==0)

{

Insert(Operator,DFS);

record[r].nonterm=sen[i][0];

record[r].term=sen[i][j];

r++;

}

break;

}

//第二次扫描,考虑候选式第一个符号为非终结符的情况

intlocation[col];

//记录first表中放入终结符的位置

first_len;

i++)

location[i]=1;

while(!

ifEmpty(Operator))

{

intexist=0;

//标志位,记录即将入栈的元素是否已经存在

StackElementIDElement,DElement;

DElement=Pop(Operator);

//弹出栈顶元素

for(i=0;

if(first[i][0]==DElement.nonterm)

intn=location[i];

first[i][n]=DElement.term;

//将终结符填入相应的first表中

location[i]++;

for(j=0;

j<

j++)

{

if(sen[j][3]==DElement.nonterm)//找出能推出当前非终结符的产生式的左部

IDElement.nonterm=sen[j][0];

IDElement.term=DElement.term;

//判断将要放进栈里的元素曾经是否出现过,若没有,才压入栈

for(intr0=0;

r0<

r0++)//r记录record数组中的元素个数

if(record[r0].nonterm==IDElement.nonterm&

record[r0].term==IDElement.term)

{//已存在在栈中

exist=1;

}

if(exist==0)

{//不存在则压入栈中

Insert(Operator,IDElement);

record[r].nonterm=IDElement.nonterm;

record[r].term=IDElement.term;

//构造LASTVT集

voidLastVt(charsen[][col],charlast[][col],intsen_len,intfirst_len)//first_len表示last表的行数

inti,j,i1,j1;

charc,record[row][col]={'

};

for(j=0;

j++)

record[i][j]=sen[i][j];

j=j-1;

for(i1=3,j1=j;

i1<

j1;

i1++,j1--)//做翻转,就可以用求first的方法求last

c=record[i][i1];

record[i][i1]=record[i][j1];

record[i][j1]=c;

}

FirstVt(record,last,sen_len,first_len);

//判断非终结符在term表中是否已存在

boolTermTableJud(charterm[col],intterm_len,charC)

for(inti=0;

term_len;

if(term[i]==C)

//如果first表中已存在此非终结符,则返回1

//构造算符优先关系表

boolOpPriotable(charsen[][col],charfirst[][col],charlast[][col],charopTable[][col],intsen_len,intfirst_len,int&

opTable_len)

inti,j,term_len=0;

inti2,i3,opr,opc;

charc1,c2,c3;

charterm[SIZE]={'

i++)//一维数组term记录关系表中存在的所有终结符

='

if(TerminalJud(sen[i][j])==true)

if(TermTableJud(term,term_len,sen[i][j])==false)//term_len记录term表的长度

term[term_len]=sen[i][j];

term_len++;

}//得到终结符表

//给优先关系表赋初值,都等于空

term_len+1;

j<

opTable[i][j]='

'

//设置优先关系表的表头,即将所有终结符存储

opTable[i][0]=term[i-1];

opTable[0][i]=term[i-1];

//找等于关系

{//形如#E#的情况

for(j=5;

j++)

if(TerminalJud(sen[i][j-2])==true&

TerminalJud(sen[i][j-1])==false&

TerminalJud(sen[i][j])==true)

c1=sen[i][j-2];

c2=sen[i][j];

//在opTable表中找到该存入的行标opr

for(opr=1;

opr<

opr++)

if(opTable[opr][0]==c1)

//在opTable表中找到该存入的列标opc

for(opc=1;

opc<

opc++)

if(opTable[0][opc]==c2)

//若这两者优先级关系之前已定义了,则表示该文法非算符优先

if(opTable[opr][opc]!

cout<

不是算符优先文法!

returnfalse;

else

opTable[opr][opc]='

//形如()的情况

for(j=4;

if(TerminalJud(sen[i][j-1])==true&

c1=sen[i][j-1];

c2=sen[i][j];

//在opTable表中找到该存入的列标j2

if(opTable[0][opc]==c2)

//找小于关系

{//形如aA情况

if(TerminalJud(sen[i][j])==true&

TerminalJud(sen[i][j+1])==false)

c1=sen[i][j];

//c1记录终结符

c2=sen[i][j+1];

//c2记录非终结符

//找出非终结符在first表中的列标opc

for(opc=0;

if(first[opc][0]==c2)

for(i2=1;

first[opc][i2]!

i2++)

c3=first[opc][i2];

for(i3=1;

i3<

i3++)

if(opTable[0][i3]==c3)

{

if(opTable[opr][i3]!

{

cout<

returnfalse;

}

else

opTable[opr][i3]='

'

break;

}

}

//找大于关系

{//形如Aa情况

if(TerminalJud(sen[i][j])==false&

sen[i][j+1]!

TerminalJud(sen[i][j+1])==true)

//c1记录非终结符

c2=sen[i][j+1];

//c2记录终结符

//在opTable表中找到该存入的列标j1

if(opTable[0][opr]==c2)

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

当前位置:首页 > 小学教育 > 数学

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

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