LR(1)文法智能分析

LR1文法全智能分析


// by  hfut yzk
#include "stdafx.h"
#include<fstream>
#include<string>
#include<map>
#include<vector>
#include<stack>
#include<set>
#include<cstring>
#include<queue>
using namespace std;

#pragma region vars
struct xiangmu										  //一个项目
{
    int nump;										   //产生式编号
    int id;											 //.的位置
    string fst;										 //集合
};

map<char,int>getnum;	
char getchars[100];									//获得对应字符
vector<string>proce;								  //产生式
int table[30][30];									 //预测分析表 -1
int tb_s_r[30][30];								   //是移进项还是规约项,-1,-2.
int num=0;int numvt=0;							 //numvt是终结符集合,0是‘#’,numvt表空字
string first[100];									//每个符号的first集
bool gotfirst[100];									//是否已经完成FIRST集合
string getp[100];								//获得某终结符在左边的产生式集合
vector<vector<xiangmu> >v;						//项目集族
int e[100][3];
int head[100];
int nume=0;		                             //链式前向星项目集族图


fstream cin ("H:/课程设计/编译原理2015/lr(1)/in.txt");
fstream cout ("H:/课程设计/编译原理2015/lr(1)/out.txt");
fstream cout2 ("H:/课程设计/编译原理2015/lr(1)/out2.txt");
#pragma endregion

#pragma region functions
void readin();
void getpp();
void dfsgetfirst(int nv,int nump);
void get_first();
void clear() ;
void addegde(int from,int to,int w)    ;
inline bool xmeq(xiangmu a,xiangmu b);
bool isin(xiangmu a,vector<xiangmu> b) ;								  //xm a is in xmji b
bool xmjieq(vector<xiangmu> a,vector<xiangmu> b) ;						 //两个项目集是否相等
vector<xiangmu>  hebing(vector<xiangmu>a ,vector<xiangmu>b) ;			//合并项目集 a,b 复给 a
int xmji_isin_xmjizu(vector<xiangmu>a,vector<vector<xiangmu> >b) ;     //查找项目集,若有,则返回编号,一举俩得
vector<xiangmu> get_close(xiangmu t)    ;                              //对项目 T作闭包
void get_xiangmujizu()        ;									     //获得项目集族
void print_xmjizu()           ;                                     //打印项目集族
bool get_table();
void print_table();
void  print_now_state(int count,stack<int>state,stack<int>wd,int i);
bool analyze(); 


#pragma endregion

/*******************************************读入vt,vn,编号1-num,读入所有产生式*********************************************/
void readin()                                  
{
    memset(table,-1,sizeof(table));
    getnum['#']=0;
    getchars[0]='#';
    //cout<<"请输入所有终结符:"<<endl;
    char x;
    do
    {
      cin>>x;
      getnum[x]=++num;
      getchars[num]=x;
    }while(cin.peek()!='\n');
     numvt=++num;
     getnum['@']=numvt;        //kong zi
     getchars[num]=('@');
   // cout<<"请输入非终结符集:"<<endl;
    do
    {
      cin>>x;
      getnum[x]=++num;
      getchars[num]=x;
    }while(cin.peek()!='\n');
 //   cout<<"输入所有产生式(空字用‘@’表示),以‘end’结束:"<<endl;
    string pro;
     while(cin>>pro&&pro!="end")
     {
         string ss;
         ss+=pro[0];
         for(int i=3;i<pro.size();i++)
         {
             if(pro[i]=='|')
             {
                  proce.push_back(ss);
                  ss.clear();ss+=pro[0];
             }
             else
             {
                 ss+=pro[i];
             }
         }
          proce.push_back(ss);
    }
}

void getpp()
{
    for(int i=0;i<proce.size();i++)
    {
        int temp=getnum[proce[i][0]];
        getp[temp]+=char('0'+i);
    }
}

/****************************************************获得first集************************************************************/
void dfsgetfirst(int nv,int nump)							 //当前的符号,和对应产生式编号
{
   int temp=getnum[proce[nump][1]];							 //产生式推出来的首符
    gotfirst[nump]=1;										  //标记
    if(temp<=numvt)first[nv]+=char('0'+temp);				//是终结符
    else
    {
        for(int i=0;i<getp[temp].size();i++)				 //所有temp可以推出来的符号对应的产生式
          {
              if(proce[nump][0]==proce[nump][1])continue;	//左递归的产生式不用不影响求fisrt集
              dfsgetfirst(temp,getp[temp][i]-'0');
          }

        first[nv]+=first[temp];								//回溯时候沿途保存
    }
}
void get_first()
{
    for(int i=1;i<=numvt;i++)										  //    终结符first集合是它自己.
    {
        first[i]=char('0'+i);
    }
     for(int i=0;i<proce.size();i++)
    {
        if(proce[i][0]==proce[i][1])continue; //左递归的产生式不用不影响求fisrt集
        if(gotfirst[i])continue;              //已经生成。
        int temp=getnum[proce[i][0]];
          dfsgetfirst(temp,i);
    }
}
/***************************************************添加边*****************************************************************/
void addegde(int from,int to,int w)           
{
    e[nume][0]=to;e[nume][1]=head[from];head[from]=nume;
    e[nume++][2]=w;
}
/******************************************************初始化函数*********************************************************/
void clear()                
{
    for(int i=0;i<100;i++
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值