编译原理LL1文法

本文档介绍了如何构建和分析LL1文法,包括构造关系图、存储first集、follow集、select集以及预测分析表。通过示例展示了文法输入、非终结符First集和Follow集的输出,以及LL1文法的分析过程演示。
摘要由CSDN通过智能技术生成

//判空已经是完美的,follow集也已经设标志位方法,是我最完美的LL1文法!
#include <stdlib.h>//#include <stdio.h>
#include <conio.h>
#include<iostream>
#include<string>
#include<fstream>
#include<iomanip>
using namespace std;
const int MaxVnNum = 10;
const int MaxVtNum = 10;
const int MaxPLength = 20;
const int MaxStackDepth = 20;

typedef struct  /*此结构用来存储文法的所有产生式*/
{
    char p[50][10];  /*P数组用来存储产生式*/
    int length; /*产生式个数*/
}G;
typedef struct    /*此结构用来存储终结符*/
{
    char id[20];     /*所有终结符名称*/
 int length;      /*终结符个数*/
}VT;
typedef struct    /*此结构用来存储非终结符*/
{
    char id[20];    /*所有非终结符*/
 int empty[20];  /*是否可以推出空,1表示可以推出空,0表示不可以推出空,-1表示待定*/
    int length;   /*非终结符个数*/
}VN;
typedef struct    /*此结构为关系图中的结点类型*/
{
   char id;      /*结点名称*/
   char tn;      /*标志终结符还是非终结符,t表示终结符,n表示非终结符*/
   int style;    /*若是非终结符的话,用来标识first集,1表示first,0表示follow*/
}node;
typedef struct    /*此结构为关系图的数据结构*/
{
    node  n[60];   /*一维数组存储顶点信息*/
    int length;    /*顶点个数*/
    int s[60][60]; /*存储顶点之间的关系*/
}rela;
G *g;
VT *vt;
VN *vn;
rela *r;
int first[20][20];  /*存储first集*/
int follow[20][20]; /*存储follow集*/
int select[20][20]; /*存储select集*/
int analyseTable[20][20]; /*存储select集(预测分析表)analyseTable*/
char digui='S';int icount=0;
int followFlag[10];

char ch; /*符号或string ch;*/
string st; /*要分析的符号串*/
char stack[MaxStackDepth];
int top;

void input();
void init();
char menu();
void printg();
void fileinput();
int product_Length(int r);
int vnnum(char c) /*查找非终结符c在数组vn中所对应的编号*/
{
   int i;
   for(i=0;vn->id[i]!=c&&i<vn->length;i++);
   if(i!=vn->length) return(i);
   else return(-1);
}

int vtnum(char c) /*查找终结符c在数组vt中所对应的编号*/
{
   int i;
   for(i=0;vt->id[i]!=c&&i<vt->length;i++);
   if(i!=vt->length) return(i);
   else return(-1);
}

int rvtnum(char c)    /*在关系图中查找终结符c的编号*/
{
  int i;
  for(i=0;r->n[i].id!=c&&i<r->length;i++);
  if(i!=r->length) return(i);
  else return(-1);
}

int rvnnum(char c,int s)   /*在关系图中查找非终结符c的编号,s表示是first集还是follow集*/
{
  int i=0;
  for(i=0;(r->n[i].id!=c||r->n[i].style!=s)&&i<r->length;i++);
  if(i!=r->length)
   return i;
  else return(-1);
}


void make_rela()   /*构造关系图*/
{
  int i,j,k;
  /*连接first关系*/
  for(i=0;i<g->length;i++)
  {
     for(j=3;g->p[i][j]!='/0';j++)
     {
        if(g->p[i][j]<'A'||g->p[i][j]>'Z')
        {
           r->s[rvnnum(g->p[i][0],1)][rvtnum(g->p[i][j])]=1;
           break;
        }
        else if(g->p[i][0]!=g->p[i][j])
        {
           r->s[rvnnum(g->p[i][0],1)][rvnnum(g->p[i][j],1)]=1;
           if(vn->empty[vnnum(g->p[i][j])]!=1) break;
           else continue;
        }
     }
  if(g->p[i][j]=='/0')
  r->s[rvnnum(g->p[i][0],1)][rvtnum('@')]=1;
  }
 
  /*连接follow关系*/
  r->s[rvnnum(vn->id[0],0)][rvtnum('#')]=1;
  for(i=0;i<g->length;i++)
  {
     for(j=3;g->p[i][j]!='/0';j++)
     {
        if(g->p[i][j]>='A'&&g->p[i][j]<='Z')
        {
           for(k=j+1;g->p[i][k]!='/0';k++)
           {
              if(g->p[i][k]<'A'||g->p[i][k]>'Z')//终结符
              {
                r->s[rvnnum(g->p[i][j],0)][rvtnum(g->p[i][k])]=1;
                break;
              }
              else
              {
                r->s[rvnnum(g->p[i][j],0)][rvnnum(g->p[i][k],1)]=1;
                if(vn->empty[vnnum(g->p[i][k])]==0) break;  //if(vn->empty[vnnum(g->p[i][k])]!=1) 对比一下吧
                else continue;
              }
           }//for
           if(g->p[i][k]=='/0')
             r->s[rvnnum(g->p[i][j],0)][rvnnum(g->p[i][0],0)]=1;
        }
     }
  }
 // getchar();
}

void outputfir_fol_sel(int a[20][20],int length)  /*输出函数*/
{
  int i,j;
  printf("/n/n");
  for(i=0;i< length;i++)
  { 
   if(length==vn->length)
       printf("/t %c的集为: ",vn->id[i]);
   else  printf("/t(%d) %s 的select集: ",i,g->p[i]);
   for(j=0;j<vt->length ;j++)
   {  
    if(a[i][j]==1)
    {
       printf("/t %c ",vt->id[j]);
 
    }
   } 
      printf("/n");

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值