欢迎来到淘文阁 - 分享文档赚钱的网站! | 帮助中心 好文档才是您的得力助手!
淘文阁 - 分享文档赚钱的网站
全部分类
  • 研究报告>
  • 管理文献>
  • 标准材料>
  • 技术资料>
  • 教育专区>
  • 应用文书>
  • 生活休闲>
  • 考试试题>
  • pptx模板>
  • 工商注册>
  • 期刊短文>
  • 图片设计>
  • ImageVerifierCode 换一换

    实验三-算符优先分析算法的设计与实现(共17页).doc

    • 资源ID:13514833       资源大小:50.50KB        全文页数:17页
    • 资源格式: DOC        下载积分:20金币
    快捷下载 游客一键下载
    会员登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录   QQ登录  
    二维码
    微信扫一扫登录
    下载资源需要20金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    实验三-算符优先分析算法的设计与实现(共17页).doc

    精选优质文档-倾情为你奉上实验三 算符优先分析算法的设计与实现(8学时)一、 实验目的根据算符优先分析法,对表达式进行语法分析,使其能够判断一个表达式是否正确。通过算符优先分析方法的实现,加深对自下而上语法分析方法的理解。二、 实验要求1、输入文法。可以是如下算术表达式的文法(你可以根据需要适当改变): EE+T|E-T|TTT*F|T/F|FF(E)|i2、对给定表达式进行分析,输出表达式正确与否的判断。程序输入/输出示例:输入:1+2;输出:正确输入:(1+2)/3+4-(5+6/7);输出:正确输入:(1-2)/3+4输出:错误输入:1+2-3+(*4/5)输出:错误三、实验步骤1、参考数据结构char *VN=0,*VT=0;/非终结符和终结符数组char firstvtNN,lastvtNN,tableNN;typedef struct /符号对(P,a)char Vn;char Vt; VN_VT;typedef struct /栈 VN_VT *top; VN_VT *bollow; int size;stack;2、根据文法求FIRSTVT集和LASTVT集给定一个上下文无关文法,根据算法设计一个程序,求文法中每个非终结符的FirstVT 集和LastVT 集。算符描述如下:/*求 FirstVT 集的算法*/ PROCEDURE insert(P,a); IF not FP,a then begin FP,a = true; /(P,a)进栈 end; Procedure FirstVT; Begin for 对每个非终结符 P和终结符 a do FP,a = false for 对每个形如 Pa或 PQa的产生式 do Insert(P,a) while stack 非空 begin 栈顶项出栈,记为(Q,a) for 对每条形如 PQ的产生式 do insert(P,a) end; end.同理,可构造计算LASTVT的算法。3、构造算符优先分析表依据文法和求出的相应FirstVT和 LastVT 集生成算符优先分析表。算法描述如下:for 每个形如 P->X1X2Xn的产生式 do for i =1 to n-1 do begin if Xi和Xi+1都是终结符 then Xi = Xi+1 if i<= n-2, Xi和Xi+2 是终结符, 但Xi+1 为非终结符 then Xi = Xi+2 if Xi为终结符, Xi+1为非终结符 then for FirstVT 中的每个元素 a do Xi < a ; if Xi为非终结符, Xi+1为终结符 then for LastVT 中的每个元素 a do a > Xi+1 ; end4、构造总控程序 算法描述如下: stack S; k = 1; /符号栈S的使用深度 Sk = # REPEAT 把下一个输入符号读进a中; If Sk VT then j = k else j = k-1; While Sj > a do Begin Repeat Q = Sj; if Sj-1 VT then j = j-1 else j = j-2 until Sj < Q; 把Sj+1Sk归约为某个N,并输出归约为哪个符号; K = j+1; Sk = N; end of while if Sj < a or Sj = a then begin k = k+1; Sk = a end else error /调用出错诊察程序 until a = #5、对给定的表达式,给出准确与否的分析过程6、给出表达式的计算结果。(本步骤可选作)四、实验报告要求1.写出编程思路、源代码(或流程图);2.写出上机调试时发现的问题,以及解决的过程;3.写出你所使用的测试数据及结果;4.谈谈你的体会。5.上机8小时,完成实验报告2小时。五、源代码 #include<iostream.h>#include<string.h>#include<stdio.h>typedef struct    char R;    char r;    int flag;array;typedef struct     char E;    char e;charLode;typedef struct    charLode *base;    int top;charstack;char str8080,arr8080,brr8080;array F20;int m,kk,p,ppp,FF=1;char r10;int crr2020,FLAG=0;char ccrr1120,ccrr2201;void Initstack(charstack &s)/定义栈    s.base=new charLode20;    s.top=-1;void push(charstack &s,charLode w)    /入栈   s.top+;   s.bases.top.E=w.E;   s.bases.top.e=w.e;void pop(charstack &s,charLode &w)    /出栈   w.E=s.bases.top.E;   w.e=s.bases.top.e;   s.top-;int IsEmpty(charstack s)    /判断是否到栈顶    if(s.top=-1)        return 1;    else         return 0;int IsLetter(char ch)    /判断是不是大写字母(非终结符)   if(ch>='A'&&ch<='Z')       return 1;   else        return 0;/judge1是判断是否是算符文法:若产生式中含有两个相继的非终结符则不是算符文法int judge1(int n)    int j=3,flag=0;    for(int i=0;i<=n;i+)        while(strij!='0')                    char a=strij;            char b=strij+1;            if(IsLetter(a)&&IsLetter(b)    /两个非终结符相连,不是算符文法                            flag=1;                break;                        else                 j+;                        if(flag=1)        /根据flag设定返回值            return 0;        else            return 1;/judge2是判断文法G是否为算符优先文法:若不是算符文法或若文法中含空字或终结符的优先级不唯一则不是算符优先文法void judge2(int n)    for(int i=0;i<=n;i+)        if(stri3=''|FLAG=1)/''代表空                    cout<<"文法G不是算符优先文法!"<<endl;            FF=0;            break;                        if(i>n)            cout<<"文法G是算符优先文法!"<<endl;/search1是查看存放终结符的数组r中是否含有重复的终结符int search1(char r,int kk,char a)    for(int i=0;i<kk;i+)        if(ri=a)            break;        if(i=kk)             return 0;        else             return 1;/createF函数是用F数组存放每个终结符与非终结符和组合,并且值每队的标志位为0;F数组是一个结构体void createF(int n)    int k=0,i=1;char g;    char t10;/t数组用来存放非终结符    t0=str00;    while(i<=n)            if(tk!=stri0)                    k+;            tk=stri0;            g=tk;            i+;                else i+;        kk=0;    char c;    for(i=0;i<=n;i+)             int j=3;        while(strij!='0')                    c=strij;            if(IsLetter(c)=0)                            if(!search1(r,kk,c)                    rkk=c;                kk+;/r数组用来存放终结符                        j+;                m=0;    for(i=0;i<k;i+)        for(int j=0;j<kk-1;j+)                    Fm.R=ti;            Fm.r=rj;            Fm.flag=0;            m+;        /search函数是将在F数组中寻找到的终结符与非终结符对的标志位值为1void search(charLode w)    for(int i=0;i<m;i+)        if(Fi.R=w.E&&Fi.r=w.e)                    Fi.flag=1;break;        void FirstVT(int n)/求FirstVT    charstack sta;    charLode w;    int i=0;    Initstack(sta);    while(i<=n)            int k=3;        w.E=stri0;        char a=strik;        char b=strik+1;        if(!IsLetter(a)    /产生式的后选式的第一个字符就是终结符的情况                    w.e=a;            push(sta,w);            search(w);            i+;                else if(IsLetter(a)&&b!='0'&&!IsLetter(b)        /产生式的后选式的第一个字符是非终结符的情况                    w.e=b;            push(sta,w);            search(w);            i+;                else i+;    charLode ww;    while(!IsEmpty(sta)            pop(sta,ww);        for(i=0;i<=n;i+)                    w.E=stri0;            if(stri3=ww.E&&stri4='0')                            w.e=ww.e;                push(sta,w);                search(w);                break;                            p=0;int k=1;i=1;    while(i<m)            if(Fi-1.flag=1)                    arrp0=Fi-1.R;            arrpk=Fi-1.r;                while(Fi.flag=0&&i<m)            i+;        if(Fi.flag=1)                    if(Fi.R=arrp0)                k+;            else arrpk+1='0'p+;k=1;            i+;               void LastVT(int n)/求LastVT    charstack sta;    charLode w;    for(int i=0;i<m;i+)        Fi.flag=0;    i=0;    Initstack(sta);    while(i<=n)            int k=strlen(stri);        w.E=stri0;        char a=strik-1;        char b=strik-2;        if(!IsLetter(a)                    w.e=a;            push(sta,w);            search(w);            i+;                else if(IsLetter(a)&&!IsLetter(b)                    w.e=b;            push(sta,w);            search(w);            i+;                else i+;        charLode ee;    while(!IsEmpty(sta)            pop(sta,ee);        for(i=0;i<=n;i+)                    w.E=stri0;            if(stri3=ee.E&&stri4='0')                            w.e=ee.e;                push(sta,w);                search(w);                            int k=1;i=1;    ppp=0;    while(i<m)            if(Fi-1.flag=1)                    brrppp0=Fi-1.R;            brrpppk=Fi-1.r;                while(Fi.flag=0&&i<m)            i+;        if(Fi.flag=1)                    if(Fi.R=arrppp0)                k+;            else brrpppk+1='0'ppp+;k=1;            i+;               void createYXB(int n)/构造优先表    int i,j;    for(j=1;j<=kk;j+)        ccrr10j=rj-1;    for( i=1;i<=kk;i+)        ccrr2i0=ri-1;    for(i=1;i<=kk;i+)        for(j=1;j<=kk;j+)            crrij=0;        int I=0,J=3;        while(I<=n)                    if(strIJ+1='0')        /扫描右部                            I+;                J=3;                        else                            while(strIJ+1!='0')                                    char aa=strIJ;                    char bb=strIJ+1;                    if(!IsLetter(aa)&&!IsLetter(bb)/优先及等于的情况,用1值表示等于                                              for(i=1;i<=kk;i+)                                                     if(ccrr2i0=aa)                                break;                                                 for(j=1;j<=kk;j+)                                                    if(ccrr10j=bb)                                break;                                                  if(crrij=0)                            crrij=1;                        else                             FLAG=1;                            I=n+1;                                                J+;                                        if(!IsLetter(aa)&&IsLetter(bb)&&strIJ+2!='0'&&!IsLetter(strIJ+2)/优先及等于的情况                                              for(i=1;i<=kk;i+)                                                     if(ccrr2i0=aa)                                break;                                                for(int j=1;j<=kk;j+)                                                     if(ccrr10j=strIJ+2)                                break;                                                if(crrij=0)                            crrij=1;                        else                                                     FLAG=1;                            I=n+1;                                                                if(!IsLetter(aa)&&IsLetter(bb)/优先及小于的情况,用2值表示小于                                              for(i=1;i<=kk;i+)                                                     if(aa=ccrr2i0)                                break;                                                for(j=0;j<=p;j+)                                                     if(bb=arrj0)                                break;                                                for(int mm=1;arrjmm!='0'mm+)                                                     for(int pp=1;pp<=kk;pp+)                                                            if(ccrr10pp=arrjmm)                                    break;                                                        if(crripp=0)                                crripp=2;                            else                                 FLAG=1;I=n+1;                                                                            J+;                                        if(IsLetter(aa)&&!IsLetter(bb)/优先及大于的情况,用3值表示大于                                             for(i=1;i<=kk;i+)                                                     if(ccrr10i=bb)                                break;                                                for(j=0;j<=ppp;j+)                                                    if(aa=brrj0)                                break;                                                for(int mm=1;brrjmm!='0'mm+)                                                      for(int pp=1;pp<=kk;pp+)                                                            if(ccrr2pp0=brrjmm)                                    break;                                                        if(crrppi=0)                                crrppi=3;                            else FLAG=1;I=n+1;                                                J+;                                                /judge3是用来返回在归约过程中两个非终结符相比较的值int judge3(char s,char a)    int i=1,j=1;    while(ccrr2i0!=s)        i+;    while(ccrr10j!=a)        j+;    if(crrij=3)         return 3;    else         if(crrij=2)             return 2;        else             if(crrij=1)                return 1;            else                 return 0;void print(char s,char STR20,int q,int u,int ii,int k)/打印归约的过程    cout<<u<<"        "    for(int i=0;i<=k;i+)        cout<<si;    cout<<"         "    for(i=q;i<=ii;i+)        cout<<STR0i;    cout<<"        "void process(char STR20,int ii)/对输入的字符串进行归约的过程     cout<<"步骤"<<"    "<<"符号栈"<<"    "<<"输入串"<<"       "<<"动作"<<endl;    int k=0,q=0,u=0,b,i,j;    char s40,a;    sk='#'    print(s,STR,q,u,ii,k);    cout<<"预备"<<endl;    k+;    u+;    sk=STR0q;    q+;    print(s,STR,q,u,ii,k);    cout<<"移进"<<endl;    while(q<=ii)            a=STR0q;        if(!IsLetter(sk) j=k;        else j=k-1;        b=judge3(sj,a);        if(b=3)/大于的情况进行归约                    while(IsLetter(sj-1)                j-;            for(i=j;i<=k;i+)                si='0'            k=j;            sk='N'            u+;            print(s,STR,q,u,ii,k);            cout<<"归约"<<endl;                else if(b=2|b=1)/小于或等于的情况移进                    k+;            sk=a;            u+;            q+;            print(s,STR,q,u,ii,k);            if(s0='#'&&s1='N'&&s2='#')                cout<<"接受"<<endl;            else cout<<"移进"<<endl;                else                     cout<<"出错"<<endl;            break;                if(s0='#'&&s1='N'&&s2='#')        cout<<"归约成功"<<endl;    else cout<<"归约失败"<<endl;void main()    int n,i,j;    cout<<"请输入你要定义的文法G的产生式的个数n:"    cin>>n;    cout<<"请输入文法产生式:"<<endl;    for(i=0;i<n;i+)            gets(stri);        j=strlen(stri);        strij='0'        stri0='Q'        /最末行添加扩展    stri1='-'    stri2='>'    stri3='#'    stri4=str00;    stri5='#'    cout<<"你定义的产生式如下:"<<endl;    stri6='0'    for(i=0;i<=n;i+)        cout<<stri<<endl;    if(judge1(n)=0)    /判断文法G是否为算符文法        cout<<"文法G不是算符文法!"<<endl;    if(judge1(n)=1)            cout<<"文法G是算符文法!"<<endl;            createF(n);        FirstVT(n);        LastVT(n);        createYXB(n);        for(i=0;i<=p;i+)/打印FirstVT                    cout<<"FirstVT("<<arri0<<")="            for(int l=1;arril+1!='0'l+)                cout<<arril<<","            cout<<arril<<""<<endl;                cout<<"FirstVT(Q)=#"<<endl;         for(i=0;i<=ppp;i+)/打印LastVT                    cout<<"LastVT("<<arri0<<")="            for(int l=1;brril+1!='0'l+)                cout<<brril<<","            cout<<brril<<""<<endl;                cout<<"LastVT(Q)=#"<<endl;        cout<<"优先表如下:"<<endl;        for(i=1;i<kk;i+)/打印优先关系表        

    注意事项

    本文(实验三-算符优先分析算法的设计与实现(共17页).doc)为本站会员(飞****2)主动上传,淘文阁 - 分享文档赚钱的网站仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知淘文阁 - 分享文档赚钱的网站(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于淘文阁 - 版权申诉 - 用户使用规则 - 积分规则 - 联系我们

    本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

    工信部备案号:黑ICP备15003705号 © 2020-2023 www.taowenge.com 淘文阁 

    收起
    展开