哈工大编译原理实验语法分析_LL(1)语法分析过程

02bc1db4748b462481f126262c6d0cd6.png

最近在做编译原理的实验,有一个实验是LL(1)语法分析设计。LL(1)语法分析主要有一下几个步骤:1、给定文法构造FIRST集、SELECT集与FOLLOW集。2、构造文法预测分析表。3、进行语法分析,构造语法分析过程表。因为这个实验我是和同学合写的,大佬同学构造出了FIRST集、SELECT集与FOLLOW集,而我在已有文法预测表的情况下完成了语法分析。

首先给定文法G[S]:
S->aH
H->aMd
H->d
M->Ab
M->@ //@为空串
A->aM
A->e

对此文法手动构造文法预测分析表

a       
string table[6][6]={
{"","a","d","b","e","#"},
{"S","aH","","","",""},
{"H","aMd","d","","",""},
{"M","Ab","@","@","Ab",""},
{"A","aM","","","e",""},
{"","","","","",""}
};

在此分析中用到了两个栈:

stack<char> s1;///分析栈
stack<char> s2;///剩余输入串

在分析栈中首先push一个#和文法开始符,分析栈栈顶元素与剩余输入串栈顶元素相遇查找文法预测分析表进行分析,匹配或者选择相应产生式。在这里我写了一个CharToNumber函数进行终结符和非终结符在文法预测分析表的映射,返回数组下标。

int CharToNumber(char c)
{
    switch(c)
    {
        case 'a':return 1;
        case 'S':return 1;break;
        case 'd':return 2;
        case 'H':return 2;break;
        case 'b':return 3;
        case 'M':return 3;break;
        case 'e':return 4;
        case 'A':return 4;break;
        case '#':return 5;break;
    }
    return 0;
}

然后进行循环分析

    while(++x)
    {
        if(s1.top()=='#'&&s2.top()=='#'||table[CharToNumber(s1.top())][CharToNumber(s2.top())]!="")
        {
            name=table[CharToNumber(s1.top())][CharToNumber(s2.top())];
            reverse(name.begin(),name.end());
            p=name;
            if(s1.top()=='#'&&s2.top()=='#')
            {
                ss="接受";
                cout<<x<<"t";
                toStr2();
                cout<<"t";
                toStr1();
                cout<<"tt"<<ss<<endl;
                flag=true;
                break;
            }
            else if(s1.top()==s2.top()&&s1.top()!='#'&&s2.top()!='#')
            {
                ss="匹配";
                cout<<x<<"t";
                toStr1();
                cout<<"t";
                toStr2();
                cout<<"tt"<<s1.top()<<ss<<endl;
                s1.pop();
                s2.pop();
            }
            else
            {
                reverse(name.begin(),name.end());
                ss=name;
                p=s1.top();
                cout<<x<<"t";
                toStr1();
                cout<<"t";
                toStr2();
                cout<<"tt"<<s1.top()<<"->"<<ss<<endl;

                for(int i=0;i<p.size();i++)
                    s1.pop();
                for(int i=name.length()-1;i>=0;i--)
                {
                    s1.push(name[i]);
                    if(s1.top()=='@')
                        s1.pop();
                }
            }
        }
        else
        {
            ss="分析错误";
            cout<<x<<"t";
            toStr1();
            cout<<"t";
            toStr2();
            cout<<"tt"<<ss<<endl;
            break;
        }
    }

语法分析判断:

9cb282d7f49f879fb23d9b8b853e818d.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值