语法分析

选定一个文法

 预测分析
a) 对该文法进行 LL(1)判别,若不是 LL(1)文法,则进行等价变换。
b) 构造预测分析表。
c) 构造预测分析程序。

能从文件中读取串分析,不过只能分析一行!汗

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<dos.h>
#include<fstream>
using namespace std;
char A[20];		/*分析栈*/
char B[20];		/*剩余串*/
char v1[20]= {'p','q','a','c','d','e','#'};	/*终结符  */
char v2[20]= {'S','A','B','E'};		/*非终结符   */
int j=0,b=0,top=0,l;					/*L为输入串长度 */
typedef struct type						/*产生式类型定义  */
{
    char origin;	/*大写字符  */
    char array[5];	/*产生式右边字符 */
    int length;		/*字符个数      */
} type;
type s,t,a,a1,r,v,f,f1;	/*结构体变量  */
type C[10][10];				/*预测分析表  */
/*--------------------------------*/
/*输出分析栈  */
void print()
{
    int a;	/*指针*/
    for(a=0; a<=top+1; a++)
        printf("%c",A[a]);
    printf("\t\t");
}
/*--------------------------------*/
/*输出剩余串*/
void print1()
{
    int j;
    for(j=0; j<b; j++)	/*输出对齐符*/
        printf(" ");
    for(j=b; j<=l; j++)
        printf("%c",B[j]);
    printf("\t\t\t");
}
/*--------------------------------*/
int main()
{
    int m,n,k=0,flag=0,finish=0;
    char ch,x;
    type cha;/*用来接受C[m][n]*/
    /*把文法产生式赋值结构体*/
    s.origin='S';strcpy(s.array,"AEp");s.length=3;
    t.origin='S';strcpy(t.array,"Bq");t.length=2;
    a.origin='A';strcpy(a.array,"a");a.length=1;
    a1.origin='A';strcpy(a1.array,"cA");a1.length=2;
    r.origin='B';strcpy(r.array,"dB");r.length=2;
    v.origin='B';v.array[0]='^';v.length=1;
    f.origin='E';strcpy(f.array,"eE");f.length=2;
    f1.origin='E';f1.array[0]='^';f1.length=1;

    /*初始化分析表*/
    for(m=0; m<=3; m++)
        for(n=0; n<=6; n++)
            C[m][n].origin='N';/*全部赋为空*/

    /*填充分析表*/
    C[0][0]=C[0][4]=t;C[0][2]=C[0][3]=s;
    C[1][2]=a;C[1][3]=a1;
    C[2][1]=v;C[2][4]=r;C[2][6]=v;
    C[3][0]=C[3][6]=f1;C[3][5]=f;

    printf("提示:本程序只能对由'p','q','a','c','d','e'构成的以'#'结束的字符串进行分析,\n");
    printf("请输入要分析的字符串:");
    int np;
    printf("单行输入:按1 \\ 读入文件:按2");
    scanf("%d",&np);
    if(np==1)
    {
        do/*读入分析串*/
        {
            scanf("%c",&ch);
            if ((ch!='p') &&(ch!='q') &&(ch!='a')&&(ch!='c')&&(ch!='d')&&(ch!='e')&&(ch!='#'))
            {
                printf("输入串中有非法字符\n");
                exit(1);
            }
            B[j]=ch;
            j++;
        }
        while(ch!='#');
    }
    else
    {
        fstream out;
        out.open("ww.txt",ios::in);
        char *str=new char[sizeof out];
        out.getline(str,(sizeof out));
        for(int i=0; i<strlen(str); i++)
        {
            if(str[i]!='\0')
            {
                ch=str[i];
                if ((ch!='p') &&(ch!='q') &&(ch!='a')&&(ch!='c')&&(ch!='d')&&(ch!='e')&&(ch!='#'))
                {
                    printf("输入串中有非法字符\n");
                    exit(1);
                }
                B[j]=ch;
                j++;
            }
        }
    }
    l=j;		/*分析串长度*/
    ch=B[0];	/*当前分析字符*/
    A[top]='#';
    A[++top]='S';	/*'#','S'进栈*/
    printf("步骤\t\t分析栈 \t\t剩余字符 \t\t所用产生式 \n");
    do
    {
        x=A[top--];/*x为当前栈顶字符*/
        printf("%d",k++);
        printf("\t\t");
        for(j=0; j<=6; j++) /*判断是否为终结符*/
            if(x==v1[j])
            {
                flag=1;
                break;
            }

        if(flag==1)/*如果是终结符*/
        {
            if(x=='#')
            {
                finish=1;			/*结束标记*/
                printf("acc!\n");	/*接受 */
                getchar();
                getchar();
                exit(1);
            }
            if(x==ch)
            {
                print();
                print1();
                printf("%c匹配\n",ch);
                ch=B[++b];		/*下一个输入字符*/
                flag=0;			/*恢复标记*/
            }
            else
            {
                /*出错处理*/
                print();
                print1();
                printf("%c出错\n",ch);/*输出出错终结符*/
                exit(1);
            }
        }
        else
        {
            /*非终结符处理*/
            for(j=0; j<=3; j++)
                if(x==v2[j])
                {
                    m=j;	/* m: 分析表行号*/
                    break;
                }

            for(j=0; j<=6; j++)
                if(ch==v1[j])
                {
                    n=j;	/*n: 分析表列号*/
                    break;
                }

            cha=C[m][n];
            if(cha.origin!='N')/*判断是否为空*/
            {
                print();
                print1();
                printf("%c-",cha.origin);	/*输出产生式*/
                for(j=0; j<cha.length; j++)
                    printf("%c",cha.array[j]);
                printf("\n");

                // Fanru modifed
//				for(j=(cha.length-1);j=0;j--)	/*产生式逆序入栈*/
                for(j=(cha.length-1); j>=0; j--)	/*产生式逆序入栈*/
                    A[++top]=cha.array[j];

                if(A[top]=='^')	/*为空则不进栈*/
                    top--;
            }
            else/*出错处理*/
            {
                print();
                print1();
                printf("%c出错\n",x);/*输出出错非终结符*/
                exit(1);
            }
        }/*else*/
    }
    while(finish==0);
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值