资源简介

编译原理作业:输出LR(0)分析表,并且可以判断一个语句是否符合文法。整个过程我是使用codeblocks的c++编写的,其中用了一下STL标准库中的队列、映射。这是实现功能的详细代码,有注释的伪代码以及测试用的相关样例数据。

资源截图

代码片段和文件信息

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long LL;
const int INF=0x7fffffff;
const int MAX_N=10000;

int num_of_anum_of_Anum_of_Stotalnum;
//小写字母个数、大写字母个数、推导式个数、最终结点总数
char a[50];//字母
char S[50][50];//推导式
bool pushed[100];//访问一个结点的时候,再往外拓展时记录非终结符是否已经被push过
int ans[100][100];
char analyse[50];//分析串
int stack1[50];
char stack2[50];
char stack3[50];
int L1L2L3;//三个栈的长度
mapM;
map::iterator m;

struct node{//结点
    int id;//编号
    int num;//包含的推导式个数
    char s[20][50];
};
queueq;//结点型队列
node N[100];
int numN=0;

void outputnd(node k){//输出一个结点的s
    for(int i=0;i        cout<    }
}

void outputlb(){//输出一个数组的s
    cout<<“链表“<    for(int i=0;i        outputnd(N[i]);
        cout<    }
}

bool samenode(node xnode y){//比较两个node是否一样
     if(x.num!=y.num)return 0;//如果两个node包含的s数量不同直接输出不同
     for(int i=0;i        int flag=0;
        for(int j=0;j            if(strcmp(x.s[i]y.s[j])==0){
                flag=1;
                break;
            }
        }
        if(flag==0)return 0;
     }
     return 1;
}

void init(){//初始化
    totalnum=0;//结点数量
    while(!q.empty())q.pop();//情况队列
    memset(S0sizeof(S));
    for(int i=0;i<100;i++){
        for(int j=0;j<100;j++){
            ans[i][j]=-10000;
        }
    }
    M.clear();//清空映射
}

void input(){//顾名思义,输入数据
    printf(“请输入终结符的个数:“);
    scanf(“%d“&num_of_a);
    printf(“请输入%d个终结符(小写字母):“num_of_a);
    for(int i=0;i        scanf(“ %c“&a[i]);
        M.insert(make_pair(a[i]i));//建立映射
    }
    a[num_of_a]=‘#‘;
    M.insert(make_pair(a[num_of_a]num_of_a));
    printf(“请输入非终结符的个数(不包含起始符):“);
    scanf(“%d“&num_of_A);
    printf(“请输入%d个非终结符(大写字母):“num_of_A);
    for(int i=0;i        scanf(“ %c“&a[num_of_a+1+i]);
        M.insert(make_pair(a[num_of_a+1+i]num_of_a+1+i));
    }
    printf(“请输入初始推导式的个数:“);
    scanf(“%d“&num_of_S);
    printf(“下面%d行每行请输入1个推导式:前后用下划线“_”链接(起始为S):\n“num_of_S);
    for(int i=0;i        scanf(“%s“S[i]);
        for(int j=strlen(S[i]);j>=3;j--){
            S[i][j]=S[i][j-1];
        }
        S[i][2]=‘.‘;
    }
}

node pushback(char pnode f){//node f里把所有p开头的推导式push进去
    for(int i=0;i        if(S[i][0]==p){
            strcpy(f.s[f.num++]S[i]);
        }
    }
    return f;
}

void bfs(){//宽度优先搜索
    node aa;//声明一个空的状态
    aa.num=0;
    aa.id=totalnum++;//初始化num和id
    aa=pushback(‘S‘aa);//把S开头的推导式放到这个起始结点里
    memset(pushed0sizeof(pushed));//用于记录哪些字母被一次性push过,避免重复push
    for(int j=0;j        if(aa

评论

共有 条评论