构造识别规范句型活前缀DFA的源代…

#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define PROJECT_SET_SIZE 20  
#define PROJECT_ID_POS 0
#define GRAMMER_ID_POS 1
#define GRAMMER_START_CHAR_POS 5
#define BFCHAR_POS 2
#define AFCHAR_POS 3
#define PROJECT_LEN_POS 4
#define ID 10000
char st[20][30]; 
int r;

struct grammer
{
 char **g;
 char vt[127];
 char vn[27];
 char s;
 int line;
};

typedef struct
{
 int id;
 char ch;
}SElemType;


struct gprjt
{
 char **gp;
 char s;
 int line;
};

typedef struct prjset
{
 int id;
 struct prjset *next;
 char prjt[PROJECT_SET_SIZE+1];
 char pointafter[PROJECT_SET_SIZE+1];
 struct prjset *actorgo[PROJECT_SET_SIZE];
 char pointbefore;
}prjset,*pprjset;

struct head
{
 prjset *I;
 prjset *tail;
 int size;
};


char DOT = '~';
grammer g;
gprjt project;
head root;
void Input();
int OpenFile(char *s);
void CreateProjectSet();
void Closure(prjset *prjset);
int go(int rk, prjset *prjset);
void PrintPojectSet();
int IsInSet(char *s, char ch);
void JoinSet(char *s, char ch);
void main()
{
 for(;;){   
    r=1;
    cout<<"请输入文法规则(以#作为结尾):"<<endl;
    for(;;){
      string z;
   cin>>z;
   int m=0;
   int w=0;
   for(;m
    if(z[m]=='#'){w=1;break; }
     st[r][m]=z[m];
   }
   st[r][m]='@'; 
   r=r+1;
   if(w==1) break;
    }
    st[0][0]=st[1][0];st[0][1]='-';st[0][2]='>';st[0][3]=st[1][0];st[0][4]='@';
 int count;
 int i;
 int j;
 count = r;
 g.line=count;
 g.g=(char **)malloc(sizeof(char *)*g.line);
 for(i=0; i
 {
     g.g[i]=(char *)malloc(21);
  g.g[i][0] = i;
  g.g[i][1] = 0;
 }
 for(int x=0;x
  
  j = 2;
  for(int y=0;st[x][y]!='@';y++)
   
   if(st[x][y]=='-' && st[x][y+1]=='>'){y=y+1;continue;}
      else
      {
    char ch=st[x][y];
    g.g[x][j] = ch;
    g.g[x][1]++;
    j++;  
      
  }
 }
 g.vn[0] = g.vt[0] = 0;
 for(i=0; i
 {
  for(j=2; j<=g.g[i][1]+1; j++)
  {
   if(g.g[i][j]>='A' && g.g[i][j]<='Z')
    JoinSet(g.vn, g.g[i][j]);
   else
    JoinSet(g.vt, g.g[i][j]);
  }
 }
 g.s = g.vn[1];
 count = 0;
 for(i=0; i
  count += g.g[i][1];
 if((project.gp=(char **)malloc(sizeof(char *)*count)) == NULL)exit(1);
 int k;
 int pointpos;
 int m;
 int n;
 k = 0;
 for(i=0; i
 {
  pointpos = GRAMMER_START_CHAR_POS + 1;
  for(j=0; j
  {
   if((project.gp[k]=(char *)malloc(6+g.g[i][1])) == NULL)exit(1);   
   project.gp[k][PROJECT_ID_POS] = k;
   project.gp[k][GRAMMER_ID_POS] = i;
   project.gp[k][PROJECT_LEN_POS] = g.g[i][1]+1;
   project.gp[k][GRAMMER_START_CHAR_POS] = g.g[i][2];
   n = 3;
   for(m=GRAMMER_START_CHAR_POS+1; m
   {
    project.gp[k][m] = g.g[i][n];
    n++;
   }
   project.gp[k][pointpos] = DOT;
  
   for(m=pointpos+1; m<=project.gp[k][PROJECT_LEN_POS]+PROJECT_LEN_POS; m++)
   {
    project.gp[k][m] = g.g[i][n];
    n++;
   }
   if(pointpos==project.gp[k][PROJECT_LEN_POS]+PROJECT_LEN_POS)
   {
    project.gp[k][AFCHAR_POS] = '\0';
   }
   else
   {
    project.gp[k][AFCHAR_POS] = project.gp[k][pointpos+1];
   }
   if(pointpos==GRAMMER_START_CHAR_POS+1)
   {
    project.gp[k][BFCHAR_POS] = '\0';
   }
   else
   {
    project.gp[k][BFCHAR_POS] = project.gp[k][pointpos-1];
   }
   pointpos++;
   k++;
  }
 }
 project.s = g.s;
 project.line = k;
 cout<<"输出拓广文法:"<<"\n";
 for(i=0; i
 {
  cout<<'('<<i+1<<')';
  for(j=2; j<=g.g[i][1]+1; j++)
  {
   if(j == 3)
    cout<<"->";
   cout<<g.g[i][j];
  }
  cout<<"\n";
 }
 cout<<"输出项目集:"<<"\n";
 cout<<"--------------------------------------\n";
 for(i=0; i
 {
  cout<<'('<<i+1<<')';
  for(j=GRAMMER_START_CHAR_POS; j<=project.gp[i][PROJECT_LEN_POS]+PROJECT_LEN_POS; j++)
  {
   if(j==GRAMMER_START_CHAR_POS+1)
    cout<<"->";
   if(project.gp[i][j] == DOT)
    cout<<"·";
   else
    cout<<project.gp[i][j];
  }
  cout<<"\n";
 }
 cout<<"--------------------------------------\n";
 cout<<"\n";
    CreateProjectSet();
   PrintPojectSet();

 for(;;)
 {
 pprjset p;
 p=root.I;
 cout<<"输入字符串,判断其是否为当前文法的活前缀:";
 string u;cin>>u;
 int v[100]={0};
 int s=1;
 int k=0;
    for(int e=0;e
              int t=0;
     for(i=1;i<=p->pointafter[0]; i++)
       {
     if(p->pointafter[i]==u[e]) {  v[s]=p->actorgo[i-1]->id-ID;   s++;  p=p->actorgo[i-1];  t=1; break;}
       }
     if(t==0) { k=1;break;}
       }
    if(k==0) {cout<<"该字符串为该文法的活前缀"<<"\n";
              cout<<"其路径为:";
      for(int j=0;j
      {cout<<"I"<<v[j];
          if(j!=s-1) cout<<"->";
         }
     cout<<"\n";
    }
   else cout<<"该字符串不是该文法的活前缀"<<"\n";
   cout<<"继续输入字符串?(输入N停止输入,输入其他字符继续)";
   char q;cin>>q;
   if(q=='N') break;
 }
 }
}

void CreateProjectSet()
{
 int i;
 int j;
 int k;
 int id = ID;
 pprjset p,q;
 root.I = root.tail = NULL;
 if((p = (pprjset)malloc(sizeof(prjset))) == NULL) exit(1);
 p->id = id;
 p->next = NULL;
 p->prjt[0] = 0;
 p->pointafter[0] = 0;
 p->pointbefore = '\0';
 for(j=0; j
  p->actorgo[j] = NULL;
 for(j=0; j
  p->actorgo[j] = NULL;
 root.I = p;
 root.tail = p;
 root.size = 1;
 for(i=0; i
 {
  if(project.s == project.gp[i][GRAMMER_START_CHAR_POS] && DOT == project.gp[i][GRAMMER_START_CHAR_POS+1])
  {
   JoinSet(root.I->prjt, project.gp[i][PROJECT_ID_POS]);
   JoinSet(root.I->pointafter, project.gp[i][AFCHAR_POS]);
   break;
  }
 }
 Closure(root.I);
 int pos;
 for(q=root.I; q!=NULL; q=q->next)
 {
  for(i=1; i<=q->pointafter[0]; i++)
  {
   pos = i;
   pos--;
   if((p = (pprjset)malloc(sizeof(prjset))) == NULL) exit(1);  
   p->next = NULL;
   p->prjt[0] = 0;
   p->pointafter[0] = 0;
   p->pointbefore = q->pointafter[i];
   for(j=0; j
    p->actorgo[j] = NULL;
   for(j=1; j<=q->prjt[0]; j++)
   {
    if(project.gp[q->prjt[j]][AFCHAR_POS] == p->pointbefore)
     go(q->prjt[j], p);
   }
   Closure(p);
   pprjset ptr;
   int flag;
   int flagsame;
   flagsame = 1;
   flag = 1;
   for(ptr=root.I; ptr!=NULL; ptr=ptr->next)
   {
    flag = 1;
    if(p->prjt[0] == ptr->prjt[0])
    {
     for(k=1; k<=p->prjt[0]; k++)
     {
      if(!IsInSet(ptr->prjt, p->prjt[k]))
      {
       flag = 0;
       break;
      }//if      
     }//for
     
    }//if
    else
    {
     flag = 0;     
    }//else
    if(flag == 0)
     flagsame = 0;
    else
    {
     flagsame = 1;
     break;
    }
   }//for
   if(flagsame)//flagsame == 1 , 有与*p相同的项目集,删除*p
   {
    q->actorgo[i-1] = ptr;
    free(p);
   }
   else//将p挂到root.tail
   {
    q->actorgo[i-1] = p;
    p->id = ++id;
    root.tail->next = p;
    root.tail = p;
    root.size++;
   }

  }//for
 }//for
}//CreateProjectSet


void Closure(prjset *pset)
{//rk 为项目的编号,prjset指向项目集
 int i;
 int j;
 int rk;
 
 for(i=1; i<=pset->prjt[0]; i++)
 {
  rk = pset->prjt[i];
  if(IsInSet(g.vn, project.gp[rk][AFCHAR_POS]))//若圆点后字符为vn
  {
   for(j=0; j
   {
    if(project.gp[j][GRAMMER_START_CHAR_POS] == project.gp[rk][AFCHAR_POS] && project.gp[j][GRAMMER_START_CHAR_POS+1] == DOT)
    {
     JoinSet(pset->prjt, project.gp[j][PROJECT_ID_POS]);
     JoinSet(pset->pointafter, project.gp[j][AFCHAR_POS]);
    }//if
   }//for
  }//if
 }//for 
}//Closure

 

int go(int rk, pprjset prjset)
{//rk为项目编号,将rk的去向加入prjset指向的项目集中,返回项目编号,若无,返回-1
 int i;
 int j;
 int rksize;
 char rkS;
 char rkpointafter;
 if((rkpointafter = project.gp[rk][AFCHAR_POS]) == '\0')
 {
  return -1; 
 }
 int pointpos;
 pointpos = IsInSet(&project.gp[rk][PROJECT_LEN_POS], DOT);
 pointpos += PROJECT_LEN_POS;
 rksize = project.gp[rk][PROJECT_LEN_POS];
 rkS = project.gp[rk][GRAMMER_START_CHAR_POS];
 
 for(i=0; i
 {
  if(project.gp[i][GRAMMER_START_CHAR_POS] == rkS && project.gp[i][PROJECT_LEN_POS] == rksize && project.gp[i][BFCHAR_POS] == rkpointafter)
  {
   int flag;
   flag = 1;
   for(j=pointpos+2; j<=project.gp[i][PROJECT_LEN_POS]+PROJECT_LEN_POS; j++)
   {
    if(project.gp[i][j] != project.gp[rk][j])
    {
     flag = 0;
     break;
    }
   }//for
   if(flag)
   {
    JoinSet(prjset->prjt, project.gp[i][PROJECT_ID_POS]);//将项目加入项目集
    if(project.gp[i][AFCHAR_POS] != '\0')
    {JoinSet(prjset->pointafter, project.gp[i][AFCHAR_POS]);}//将项目圆点后的字符加入
    return project.gp[i][PROJECT_ID_POS];
   }//if
   else
    return -1;
  }//if
 }//for
}//go


void PrintPojectSet()
{
 pprjset p;
 int rk;
 int i;
 int j;
 cout<<"输出识别活前缀的DFA\n";
 for(p=root.I; p!=NULL; p=p->next)
 {
  cout<<"---------------------\n";
  cout<<'I'<<p->id-ID<<"\n";
  for(j=1; j<=p->prjt[0]; j++)
  {
   rk = p->prjt[j];
   for(i=GRAMMER_START_CHAR_POS; i<=project.gp[rk][PROJECT_LEN_POS]+PROJECT_LEN_POS; i++)
   {
    if(i==GRAMMER_START_CHAR_POS+1)
     cout<<"->";
    if(project.gp[rk][i] == DOT)
     cout<<"·";
    else
     cout<<project.gp[rk][i];
   }//for
   cout<<"\n";
  }//for
  cout<<"\n";
  for(i=1; i<=p->pointafter[0]; i++)
  {
   cout<<"出度:"<<p->pointafter[i]<<"指向->"<<"I"<<p->actorgo[i-1]->id-ID<<"\n";
  }//for
 }//for
 cout<<"---------------------\n";
}//PrintPojectSet

 

int IsInSet(char *s, char ch)
{
 int i;
 for(i=1; i<=s[0]; i++)
 {
  if(s[i] == ch) return i;
 }
 return 0;
}

void JoinSet(char *s, char ch)
{
 int i;
 if(!IsInSet(s,ch))
 {
  s[0]++;
  i = s[0];
  s[i] = ch;
 }
}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值