C++版自下而上文法分析——算符优先文法

#include<iostream>
using namespace std;
char data[20][20];                    //存储算符优先关系
char lable[20];                       //终结符集
char str[20][10];                     //分析输入串
char formula[10][30];                 //存储产生式
char First[10][10];                   //FIRSTVT集
char Last[10][10];                    //LASTVT集
int Tcharacter(char c);               //判断终结符
int Index(char c);                    //返回下标
void FirstVt(char c);                //求FIRSTVT集
void LastVt(char c);                 //求LASTVT集
void Table();                        //创建算符优先分析表
int num;                             //输入文法产生式个数
int f_flag[10]= {0};
int l_flag[10]= {0};
void FirstVt(char c)
{
    int i,j,k,m,n;
    for(i=0; i<num; i++)
    {
        if(formula[i][0]==c)
            break;
    }
    if(f_flag[i]==0)
    {
        n=First[i][0]+1;
        m=0;
        do
        {
            if(m==2||formula[i][m]=='|')
            {
                if(Tcharacter(formula[i][m+1]))
                {
                    First[i][n]=formula[i][m+1];
                    n++;
                }
                else
                {
                    if(Tcharacter(formula[i][m+2]))
                    {
                        First[i][n]=formula[i][m+2];
                        n++;
                    }
                    if(formula[i][m+1]!=c)
                    {
                        FirstVt(formula[i][m+1]);
                        for(j=0; j<num; j++)
                        {
                            if(formula[j][0]==formula[i][m+1])
                                break;
                        }
                        for(k=0; k<First[j][0]; k++)
                        {
                            int t;
                            for(t=0; t<n; t++)
                            {
                                if(First[i][t]==First[j][k+1])
                                    break;
                            }
                            if(t==n)
                            {
                                First[i][n]=First[j][k+1];
                                n++;
                            }
                        }
                    }
                }
            }
            m++;
        }
        while(formula[i][m]!='\0');
        First[i][n]='\0';
        First[i][0]=--n;
        f_flag[i]=1;
    }
}

void LastVt(char c)
{
    int i,j,k,m,n;
    for(i=0; i<num; i++)
    {
        if(formula[i][0]==c)
            break;
    }
    if(l_flag[i]==0)
    {
        n=Last[i][0]+1;
        m=0;
        do
        {
            if(formula[i][m+1]=='\0'||formula[i][m+1]=='|')
            {
                if(Tcharacter(formula[i][m]))
                {
                    Last[i][n]=formula[i][m];
                    n++;
                }
                else
                {
                    if(Tcharacter(formula[i][m-1]))
                    {
                        Last[i][n]=formula[i][m-1];
                        n++;
                    }
                    if(formula[i][m]!=c)
                    {
                        LastVt(formula[i][m]);
                        for(j=0; j<num; j++)
                        {
                            if(formula[j][0]==formula[i][m])
                                break;
                        }
                        for(k=0; k<Last[j][0]; k++)
                        {
                            int t;
                            for(t=0; t<n; t++)
                            {
                                if(Last[i][t]==Last[j][k+1])
                                    break;
                            }
                            if(t==n)
                            {
                                Last[i][n]=Last[j][k+1];
                                n++;
                            }
                        }
                    }
                }
            }
            m++;
        }
        while(formula[i][m]!='\0');
        Last[i][n]='\0';
        Last[i][0]=--n;
        l_flag[i]=1;
    }
}

void Table()
{
    char text[20][10];
    int i,j,k,t,l,x=0,y=0;
    int r1;
    int m,n;
    x=0;
    for(i=0; i<num; i++)
    {
        FirstVt(formula[i][0]);
        LastVt(formula[i][0]);
    }
    for(i=0; i<num; i++)
    {
        text[x][y]=formula[i][0];
        y++;
        for(j=1; formula[i][j]!='\0'; j++)
        {
            if(formula[i][j]=='|')
            {
                text[x][y]='\0';
                x++;
                y=0;
                text[x][y]=formula[i][0];
                y++;
                text[x][y++]='-';
                text[x][y++]='>';
            }
            else
            {
                text[x][y]=formula[i][j];
                y++;
            }
        }
        text[x][y]='\0';
        x++;
        y=0;
    }
    r1=x;
    for(i=0; i<x; i++)

    {
        str[i][0]=text[i][0];
        for(j=3,l=1; text[i][j]!='\0'; j++,l++)
            str[i][l]=text[i][j];
        str[i][l]='\0';
    }


    for(i=0; i<x; i++)
    {
        for(j=1; text[i][j+1]!='\0'; j++)
        {
            if(Tcharacter(text[i][j])&&Tcharacter(text[i][j+1]))
            {
                m=Index(text[i][j]);
                n=Index(text[i][j+1]);
                data[m][n]='=';
            }
            if(text[i][j+2]!='\0'&&Tcharacter(text[i][j])&&Tcharacter(text[i][j+2])&&!Tcharacter(text[i][j+1]))
            {
                m=Index(text[i][j]);
                n=Index(text[i][j+2]);
                data[m][n]='=';
            }
            if(Tcharacter(text[i][j])&&!Tcharacter(text[i][j+1]))
            {
                for(k=0; k<num; k++)
                {
                    if(formula[k][0]==text[i][j+1])
                        break;
                }
                m=Index(text[i][j]);
                for(t=0; t<First[k][0]; t++)
                {
                    n=Index(First[k][t+1]);
                    data[m][n]='<';
                }
            }
            if(!Tcharacter(text[i][j])&&Tcharacter(text[i][j+1]))
            {
                for(k=0; k<num; k++)
                {
                    if(formula[k][0]==text[i][j])
                        break;
                }
                n=Index(text[i][j+1]);
                for(t=0; t<Last[k][0]; t++)
                {
                    m=Index(Last[k][t+1]);
                    data[m][n]='>';
                }
            }
        }
    }
    m=Index('#');
    for(t=0; t<First[0][0]; t++)
    {
        n=Index(First[0][t+1]);
        data[m][n]='<';
    }
    n=Index('#');
    for(t=0; t<Last[0][0]; t++)
    {
        m=Index(Last[0][t+1]);
        data[m][n]='>';
    }
    data[n][n]='=';
}

int Index(char c)
{
    int i;
    for(i=0; lable[i]!='\0'; i++)
    {
        if(c==lable[i])
            return i;
    }
    return -1;
}
int Tcharacter(char c)
{
    int i;
    for(i=0; lable[i]!='\0'; i++)
    {
        if(c==lable[i])
            return 1;
    }
    return 0;
}

int main()
{
    int i,j,k=0;
    string word;
    cout<<"输入文法产生式个数:"<<endl;
    cin>>num;
    cout<<"输入文法产生式:"<<endl;
    for(i=0; i<num; i++)
    {
        cin>>formula[i];
        First[i][0]=0;            //first[i][0]和last[i][0]分别表示st[i][0]非终极符的FIRSTVT集和LASTVT集中元素的个数
        Last[i][0]=0;
    }
    cout<<endl;
    for(i=0; i<num; i++)                         //判断文法是否合法
    {
        for(j=0; formula[i][j]!='\0'; j++)
        {
            if(formula[i][0]<'A'||formula[i][0]>'Z')
            {
                cout<<"所输入的不是算符文法!"<<endl;
                return 0;
            }
            if(formula[i][j]>='A'&&formula[i][j]<='Z')
            {
                if(formula[i][j+1]>='A'&&formula[i][j+1]<='Z')
                {
                    cout<<"所输入的不是算符文法!"<<endl;
                    return 0;
                }
            }
        }
    }
    for(i=0; i<num; i++)
    {
        for(j=0; formula[i][j]!='\0'; j++)
        {
            if((formula[i][j]<'A'||formula[i][j]>'Z')&&formula[i][j]!='-'&&formula[i][j]!='>'&&formula[i][j]!='|')
                lable[k++]=formula[i][j];
        }
    }
    lable[k]='#';
    lable[k+1]='\0';
    Table();

    cout<<"FIRSTVT集如下:"<<endl;
    for(i=0; i<num; i++)
    {
        cout<<formula[i][0]<<":"<<" ";
        for(j=0; j<First[i][0]; j++)
        {
            cout<<First[i][j+1]<<" ";
        }
        cout<<endl;
    }
    cout<<"LASTVT集如下:"<<endl;
    for(i=0; i<num; i++)
    {
        cout<<formula[i][0]<<":"<<" ";
        for(j=0; j<Last[i][0]; j++)
        {
            cout<<Last[i][j+1]<<" ";
        }
        cout<<endl;
    }
    cout<<endl;
    cout<<"算符优先分析表如下:"<<endl;
    for(i=0; lable[i]!='\0'; i++)
        cout<<"\t"<<lable[i];
    cout<<endl;
    for(i=0; i<k+1; i++)
    {
        cout<<lable[i]<<"\t";
        for(j=0; j<k+1; j++)
        {
            cout<<data[i][j]<<"\t";
        }
        cout<<endl;
    }
    cout<<endl;
    for(i=0; i<k+1; i++)
    {
        for(j=0; j<k+1; j++)
        {
            if(data[i][j]=='>'&&data[j][i]!='<'&&data[j][i]!='\0') break;
            else if(data[i][j]=='<'&&data[j][i]!='>'&&data[j][i]!='\0') break;
            else if(data[i][j]=='='&&data[j][i]!='='&&data[j][i]!='\0') break;
        }
    }
    if(i==(k+1)&&j==(k+1)) cout<<"该文法是算符优先文法!"<<endl;
    else
    {
        cout<<"该文法不是算符优先文法!"<<endl;
        return 0;
    }
}

测试用例与结果

 

算符优先分析文法是一种工具,在编译的过程中,隶属于语法分析环节,却又与中间代码的生成息息相关,编译可以分为五个阶段:词法分析、语法分析、语义分析(中间代码的生成)、代码优化、目标代码生成。语法分析是指:在词法分析基础上,将单词符号串转化为语法单位(语法范畴)(短语、子句、句子、程序段、程序),并确定整个输入串是否构成语法上正确的程序。也就是说语法分析是检验输入串的语法是否正确,注意这里的语法正确,只是简单地符合自己定义的规范,而不能检测出运行时错误,比如"X/0",空指针错误,对象未初始化等错误。在这一个实验中,我将通过算符优先分析文法这一个工具,在语法分析的时候,顺便进行语义分析,也就是识别出语法单位,同时简要的将识别出的中间代码进行计算(目标代码的生成+运行),得到相应的结果,来检验自己设计的正确性。可以说题目虽然叫做算符优先分析文法,其实却是一个贯穿了“词法分析+语法分析+语义分析+中间代码优化+目标代码生成+运行”全过程的一个极具概括性的程序。如果能将这个程序得心应手的完成出来,我相信诸位对编译原理的掌握也算是炉火纯青了。时隔将近两年再来整理自己以前写过的实验报告,还是挺有感慨的,对一件东西感兴趣,原来影响还会如此深远,还记得自己当时连续六个小时全神贯注写出的实验报告,现在看看竟然写了五六十页,核心内容也有三四十页,不觉的感慨当年充满热情的时代慢慢的竟走出许久
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值