实验三算符优先分析算法的设计与实现.docx

上传人:b****8 文档编号:9345848 上传时间:2023-02-04 格式:DOCX 页数:22 大小:23.47KB
下载 相关 举报
实验三算符优先分析算法的设计与实现.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

实验三算符优先分析算法的设计与实现

实验三算符优先分析算法的设计与实现

(8学时)

一、实验目的

根据算符优先分析法,对表达式进行语法分析,使其能够判断一个表达式是否正确。

通过算符优先分析方法的实现,加深对自下而上语法分析方法的理解。

二、实验要求

1、输入文法。

可以是如下算术表达式的文法(你可以根据需要适当改变):

E→E+T|E-T|T

T→T*F|T/F|F

F→(E)|i

2、对给定表达式进行分析,输出表达式正确与否的判断。

程序输入/输出示例:

输入:

1+2;

输出:

正确

输入:

(1+2)/3+4-(5+6/7);

输出:

正确

输入:

((1—2)/3+4

输出:

错误

输入:

1+2-3+(*4/5)

输出:

错误

三、实验步骤

1、参考数据结构

char*VN=0,*VT=0;//非终结符和终结符数组

charfirstvt[N][N],lastvt[N][N],table[N][N];

typedefstruct//符号对(P,a)

charVn;

charVt;

}VN_VT;

typedefstruct//栈

VN_VT*top;

VN_VT*bollow;

intsize;

}stack;

2、根据文法求FIRSTVT集和LASTVT集

给定一个上下文无关文法,根据算法设计一个程序,求文法中每个非终结符的FirstVT集和LastVT集.

算符描述如下:

/*求FirstVT集的算法*/

PROCEDUREinsert(P,a);

IFnotF[P,a]then

begin

F[P,a]=true;//(P,a)进栈

end;

ProcedureFirstVT;

Begin

for对每个非终结符P和终结符ado

F[P,a]=false

for对每个形如Pa…或P→Qa…的产生式do

Insert(P,a)

whilestack非空

begin

栈顶项出栈,记为(Q,a)

for对每条形如P→Q…的产生式do

insert(P,a)

end;

end.

同理,可构造计算LASTVT的算法。

3、构造算符优先分析表

依据文法和求出的相应FirstVT和LastVT集生成算符优先分析表。

算法描述如下:

for每个形如P—>X1X2…Xn的产生式do

fori=1ton—1do

begin

ifXi和Xi+1都是终结符then

Xi=Xi+1

ifi〈=n—2,Xi和Xi+2是终结符,但Xi+1为非终结符then

Xi=Xi+2

ifXi为终结符,Xi+1为非终结符then

forFirstVT中的每个元素ado

Xi〈a;

ifXi为非终结符,Xi+1为终结符then

forLastVT中的每个元素ado

a〉Xi+1;

end

4、构造总控程序

算法描述如下:

stackS;

k=1;//符号栈S的使用深度

S[k]=‘#'

REPEAT

把下一个输入符号读进a中;

IfS[k]

VTthenj=kelsej=k-1;

WhileS[j]〉ado

Begin

Repeat

Q=S[j];

ifS[j—1]

VTthenj=j-1elsej=j—2

untilS[j]

把S[j+1]…S[k]归约为某个N,并输出归约为哪个符号;

K=j+1;

S[k]=N;

endofwhile

ifS[j]〈aorS[j]=athen

begink=k+1;S[k]=aend

elseerror//调用出错诊察程序

untila=‘#’

5、对给定的表达式,给出准确与否的分析过程

6、给出表达式的计算结果。

(本步骤可选作)

四、实验报告要求

1.写出编程思路、源代码(或流程图);

2。

写出上机调试时发现的问题,以及解决的过程;

3。

写出你所使用的测试数据及结果;

4。

谈谈你的体会.

5.上机8小时,完成实验报告2小时.

五、源代码

#include〈iostream。

h〉

#include〈string.h〉

#include

typedefstruct

    charR;

    charr;

    intflag;

}array;

typedefstruct

{

    charE;

    chare;

}charLode;

typedefstruct

{

    charLode*base;

    inttop;

}charstack;

charstr[80][80],arr[80][80],brr[80][80];

arrayF[20];

intm,kk,p,ppp,FF=1;

charr[10];

intcrr[20][20],FLAG=0;

charccrr1[1][20],ccrr2[20][1];

voidInitstack(charstack&s)//定义栈

    s.base=newcharLode[20];

    s.top=—1;

}

voidpush(charstack&s,charLodew)    //入栈

{

  s。

top++;

  s。

base[s。

top].E=w.E;

  s.base[s.top].e=w。

e;

}

voidpop(charstack&s,charLode&w)    //出栈

  w。

E=s.base[s。

top].E;

  w。

e=s.base[s。

top]。

e;

  s.top—-;

intIsEmpty(charstacks)    //判断是否到栈顶

{

    if(s.top==—1)

        return1;

    else

        return0;

}

intIsLetter(charch)    //判断是不是大写字母(非终结符)

{

  if(ch>=’A’&&ch〈='Z')

      return1;

  else

      return0;

}

//judge1是判断是否是算符文法:

若产生式中含有两个相继的非终结符则不是算符文法

intjudge1(intn)

    intj=3,flag=0;

    for(inti=0;i<=n;i++)

        while(str[i][j]!

=’\0’)

        {

            chara=str[i][j];

            charb=str[i][j+1];

            if(IsLetter(a)&&IsLetter(b))    //两个非终结符相连,不是算符文法

            {

                flag=1;

                break;

            }

            else

                j++;

        }

        

        if(flag==1)        //根据flag设定返回值

            return0;

        else

            return1;

//judge2是判断文法G是否为算符优先文法:

若不是算符文法或若文法中含空字或终结符的优先级不唯一则不是算符优先文法

voidjudge2(intn)

    for(inti=0;i<=n;i++)

        if(str[i][3]==’~’||FLAG==1)//’~’代表空

        {

            cout〈〈"文法G不是算符优先文法!

"〈

            FF=0;

            break;

        }

        

        if(i>n)

            cout〈〈”文法G是算符优先文法!

”〈

//search1是查看存放终结符的数组r中是否含有重复的终结符

intsearch1(charr[],intkk,chara)

{

    for(inti=0;i

        if(r[i]==a)

            break;

        if(i==kk)

            return0;

        else

            return1;

//createF函数是用F数组存放每个终结符与非终结符和组合,并且值每队的标志位为0;F数组是一个结构体

voidcreateF(intn)

    intk=0,i=1;charg;

    chart[10];//t数组用来存放非终结符

    t[0]=str[0][0];

    while(i〈=n)

    {

        if(t[k]!

=str[i][0])

        {

            k++;

            t[k]=str[i][0];

            g=t[k];

            i++;

        }

        elsei++;

    }

    kk=0;

    charc;

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

    {

        intj=3;

        while(str[i][j]!

=’\0')

        {

            c=str[i][j];

            if(IsLetter(c)==0)

            {

                if(!

search1(r,kk,c))

                    r[kk]=c;

                kk++;//r数组用来存放终结符

            }

            j++;

        }

    }

    m=0;

    for(i=0;i〈k;i++)

        for(intj=0;j

        {

            F[m]。

R=t[i];

            F[m]。

r=r[j];

            F[m].flag=0;

            m++;

        }

}

//search函数是将在F数组中寻找到的终结符与非终结符对的标志位值为1

voidsearch(charLodew)

    for(inti=0;i〈m;i++)

        if(F[i]。

R==w。

E&&F[i]。

r==w。

e)

        {

            F[i].flag=1;break;

        }

}

voidFirstVT(intn)//求FirstVT

{

    charstacksta;

    charLodew;

    inti=0;

    Initstack(sta);

    while(i<=n)

    {

        intk=3;

        w。

E=str[i][0];

        chara=str[i][k];

        charb=str[i][k+1];

        if(!

IsLetter(a))    //产生式的后选式的第一个字符就是终结符的情况

        {

            w。

e=a;

            push(sta,w);

            search(w);

            i++;

        }

        elseif(IsLetter(a)&&b!

=’\0’&&!

IsLetter(b))        //产生式的后选式的第一个字符是非终结符的情况

        {

            w.e=b;

            push(sta,w);

            search(w);

            i++;

        }

        elsei++;

}

    charLodeww;

    while(!

IsEmpty(sta))

    {

        pop(sta,ww);

        for(i=0;i〈=n;i++)

        {

            w。

E=str[i][0];

            if(str[i][3]==ww。

E&&str[i][4]=='\0')

            {

                w.e=ww。

e;

                push(sta,w);

                search(w);

                break;

            }

        }

    }

    p=0;intk=1;i=1;

    while(i〈m)

    {

        if(F[i—1]。

flag==1)

        {

            arr[p][0]=F[i—1].R;

            arr[p][k]=F[i—1].r;

        }

        while(F[i]。

flag==0&&i

            i++;

        if(F[i]。

flag==1)

        {

            if(F[i].R==arr[p][0])

                k++;

            else{arr[p][k+1]=’\0’;p++;k=1;}

            i++;

        }

    }  

voidLastVT(intn)//求LastVT

{

    charstacksta;

    charLodew;

    for(inti=0;i

        F[i].flag=0;

    i=0;

    Initstack(sta);

    while(i<=n)

    {

        intk=strlen(str[i]);

        w。

E=str[i][0];

        chara=str[i][k-1];

        charb=str[i][k-2];

        if(!

IsLetter(a))

        {

            w.e=a;

            push(sta,w);

            search(w);

            i++;

        }

        elseif(IsLetter(a)&&!

IsLetter(b))

        {

            w。

e=b;

            push(sta,w);

            search(w);

            i++;

        }

        elsei++;

    }

    charLodeee;

    while(!

IsEmpty(sta))

    {

        pop(sta,ee);

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

        {

            w。

E=str[i][0];

            if(str[i][3]==ee。

E&&str[i][4]=='\0')

            {

                w.e=ee。

e;

                push(sta,w);

                search(w);

            }

        }

    }

    intk=1;i=1;

    ppp=0;

    while(i

    {

        if(F[i-1].flag==1)

        {

            brr[ppp][0]=F[i—1].R;

            brr[ppp][k]=F[i—1].r;

        }

        while(F[i].flag==0&&i

            i++;

        if(F[i]。

flag==1)

        {

            if(F[i]。

R==arr[ppp][0])

                k++;

            else{brr[ppp][k+1]=’\0’;ppp++;k=1;}

            i++;

        }

    }  

}

voidcreateYXB(intn)//构造优先表

{

    inti,j;

    for(j=1;j〈=kk;j++)

        ccrr1[0][j]=r[j-1];

    for(i=1;i〈=kk;i++)

        ccrr2[i][0]=r[i—1];

    for(i=1;i〈=kk;i++)

        for(j=1;j〈=kk;j++)

            crr[i][j]=0;

        intI=0,J=3;

        while(I〈=n)

        {

            if(str[I][J+1]==’\0')        //扫描右部

            {

                I++;

                J=3;

            }

            else

            {

                while(str[I][J+1]!

=’\0')

                {

                    charaa=str[I][J];

                    charbb=str[I][J+1];

                    if(!

IsLetter(aa)&&!

IsLetter(bb))//优先及等于的情况,用1值表示等于

                    {  

                        for(i=1;i<=kk;i++)

                        {

                            if(ccrr2[i][0]==aa)

                                break;

                        }

                        for(j=1;j〈=kk;j++)

                        {

                            if(ccrr1[0][j]==bb)

                                break;  

                        }

                        if(crr[i][j]==0)

                            crr[i][j]=1;

                        else{

                            FLAG=1;

                            I=n+1;

                        }

                        J++;

                    }

                    if(!

IsLetter(aa)&&IsLetter(bb)&&str[I][J+2]!

=’\0'&&!

IsLetter(str[I][J+2]))//优先及等于的情况

                    {  

                        for(i=1;i<=kk;i++)

                        {

                            if(ccrr2[i][0]==aa)

                                break;

                        }

                        for(intj=1;j〈=kk;j++)

                        {

                            if(ccrr1[0][j]==str[I][J+2])

                                break;

                        }

                        if(crr[i][j]==0)

                            crr[i][j]=1;

                        else

                        {

                            FLAG=1;

                            I=n+1;

                        }

                    }

                    if(!

IsLetter(aa)&&IsLetter(bb))//优先及小于的情况,用2值表示小于

                    {  

                        for(i=1;i〈=k

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

当前位置:首页 > 高等教育 > 医学

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

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