就是按照转换规则对string的操作!左线性,右线性通吃!
参考资料:https://wenku.baidu.com/view/6f1b9e935f0e7cd18425368a.html
转换规则:
1.A-xB B->y A->xy
2.A->xA A->y A->x*y
3.A->x A->y A->x|y
代码:
#include<iostream>
#include<string>
using namespace std;
struct WF{
string left;
string right;
};
void transform(WF *p,int n){
int i,j,m,flag;
//合并产生式
for(i=0;i<n;i++){
for(int j=i+1;j<n;j++){
//合并s->aA s->bA ------s->aA|bA
if(p[i].left==p[j].left&&p[i].right[1]==p[j].right[1]){
p[i].right=p[i].right+"|"+p[j].right;
p[j].right="";
p[j].left="";
}
//合并 s->a s->b--------s->a|b
if(p[i].right.length()==1&&p[j].right.length()==1&&p[i].left==p[j].left){
p[i].right=p[i].right+"|"+p[j].right;
p[j].right="";
p[j].left="";
}
}
}
//提取公因式 S->aA|bA--------------S->(a|b)A 前面是把right【1】相等的才合并到了一起
for(i=0;i<n;i++){
flag=p[i].right.length();
if(p[i].right.length()>2&&'A'<=p[i].right[1]&&p[i].right[1]<='Z'&&p[i].right[2]=='|'){
for(j=1;j<flag-1;j=j+3){
p[i].right[j]=' ';
}
if(j==flag-1){
p[i].right="("+p[i].right.substr(0,p[i].right.length()-1)+")"+p[i].right.substr(p[i].right.length()-1);
}
}
}
//A->xA|y------------A->x*y
for(i=0;i<n;i++){
if(p[i].left[0]==p[i].right[p[i].right.length()-1]&&p[i].right.length()>1){
for(j=0;j<n;j++){
if(p[i].left==p[j].left&&j!=i){
for(m=0;m<p[j].right.length();m++){
if('A'<=p[j].right[m]&&p[j].right[m]<='Z'){
break;
}
}
if(m==p[j].right.length()){
p[i].right=p[i].right.substr(0,p[i].right.length()-1)+"*"+"("+p[j].right+")";
p[j].right="";
p[j].left="";
}
}
}
}
}
//s->zA A->aA ---------s->za*A
for(i=0;i<n;i++){
if(p[i].right.length()>1&&p[i].left[0]!=p[i].right[p[i].right.length()-1]){
for(j=0;j<n;j++){
if(p[j].right.length()>1&&p[i].right[p[i].right.length()-1]==p[j].left[0]&&p[j].left[0]==p[j].right[p[j].right.length()-1]){
p[i].right=p[i].right.substr(0,p[i].right.length()-1)+p[j].right.substr(0,p[j].right.length()-1)+"*"+p[j].right[p[j].right.length()-1];
p[j].right="";
p[j].left="";
}
}
}
}
//将表达式右部所有非终结符替换
flag=n;
while(flag>=0){
for(i=0,flag=flag-1;i<n;i++){
for(j=0;j<p[i].right.length();j++){
if('A'<=p[i].right[j]&&p[i].right[j]<='Z'){
for(m=0;m<n;m++){
if(p[m].left[0]==p[i].right[j]&&m!=i){
p[i].right=p[i].right.substr(0,j)+p[m].right+p[i].right.substr(j+1);
p[m].left="";
p[m].right="";
break;
}
}
}
}
}
}
//再次合并左部相等的产生式
for(i=0;i<n;i++){
for(j=0;j<n;j++){
if(p[i].left[0]==p[j].left[0]&&i!=j){
if(p[j].right.length()>1){
p[i].right=p[i].right+"|"+"("+p[j].right+")";
p[j].left="";
p[j].right="";
}
else{
p[i].right=p[i].right+"|"+p[j].right;
p[j].left="";
p[j].right="";
}
}
}
}
}
int main(){
int i,j,n;
string input;
cout<<"请输入文法产生式个数N"<<endl<<"N=";
cin>>n;
WF *p=new WF[n];
for(int i=0;i<n;i++){
input.erase();
cin>>input;
for(j=0;j<input.length();j++){
if(input[j]=='-'){
p[i].left=input.substr(0,j);
p[i].right=input.substr(j+2,input.length());
}
}
}
transform(p,n);
for(i=0;i<n;i++) {
if(p[i].left[0]!=NULL){
cout<<p[i].left<<"=";
for(j=0;j<p[i].right.length();j++){
if(p[i].right[j]!=' ')
cout<<p[i].right[j];
}
}
}
cout<<endl;
}