编译原理实验——LR(0)分析法

本程序演示了如何从输入文件读取文法,生成规范的LR(0)项目族,并构建ACTION和GOTO表。通过分析文法并进行闭包操作,实现了状态转换和ACTION、GOTO表的构造,为编译器的词法和语法分析阶段提供了基础。
摘要由CSDN通过智能技术生成

/*本程序从文件读入文法,可以根据文法自动生成规范LR(0)项目族,并根据DFA自动构造ACTION和GOTO表,希望各位大虾批评指正*/

/*所用文法

SA
SB
AaAb
Ac
BaBb
Bd

*/

 

#include<iostream>
#include<stdio.h>
#include<fstream>
#include<malloc.h>
using namespace std;

#define OK 1
#define ERROR 0
#define N 50
#define Y 20

int vtnum,vnnum,pronum;//依次是终结符个数,非终结符个数,产生式个数          
char vt[N];           
char vn[N];//终结符和非终结符集
char old[N][N]={'/0'};//用于存储文法
char oldz[N][N]={'/0'};//用于存储增广文法
int ACTION[N][N]={0};
int GOTO[N][N]={0};

typedef struct SqE{
   int t;//状态编号
   char c1;
}SqE;//堆栈元素

typedef struct item{
   int f;//项目前部,表示产生式编号
   int l;//项目后部,表示停顿点在产生式的位置
}item;//定义项目

typedef struct link{
   int f;//连接前部,表示所用符号的编号,非终结符编号=在vn[]中的下标+100
   int l;//连接后部,即状态编号
}link;//定义状态之间的连接

typedef struct cd{
   int item_num;//状态中的项目数
   int link_num;//状态的连接数
   item w[N];//项目集
   link u[N];//连接集
}cd;//定义状态

typedef struct DFA{
   int cd_num;//状态个数
   cd s[N+1];//状态集
}DFA;//定义规范LR(0)项目族,D.s[N]用作状态转换函数go_switch()的存储空间

DFA D;

void dfa();
void closure(int);
void go_switch(int,int);
int test_go_switch();
void add_go_switch();
void del_go_switch();
void action();
void go_answer();
int control();
int length(int);
int test(char);
void printf_ag();
bool test_link(int i,int num);

void main()
{
   int i,j;

   ifstream in("input1.txt",ios_base::in);//读文件,从文件中读入pronum,vtnum,vnnum以及产生式
   in>>pronum>>vnnum>>vtnum;
   in>>vn;
   in>>vt;
   for(i=1;i<=pronum;i++)
      in>>old[i];//将产生式存入old[][],old[1]为第一个产生式
   for(i=1;i<=pronum;i++)
      for(j=0;old[i][j]!='/0';j++)
      oldz[i][j]=old[i][j];//将产生式从old[][]录入oldz[][]
   oldz[0][0]='P';
   oldz[0][1]=old[1][0];//加入P->S,将原文法扩充,使其变为增广文法
   vt[vtnum]='$';//把结束符'$'加入终结符集
   D.cd_num=0;
   for(i=0;i<=N;i++)
   {
      D.s[i].item_num=0;
   D.s[i].link_num=0;
   }//初始化状态个数、连接个数、项目个数
 
   dfa();
   action();
   go_answer();
   printf_ag();
   control();
}

//求一个状态的闭包
void closure(int i)
{
   int j,k,m,x,flag;

   do
   {
      j=D.s[i].item_num;//j是本轮循环开始前的项目数
      for(k=0;k<D.s[i].item_num;k++)
   {
         for(m=0;m<=pronum;m++)
   {
            if(oldz[m][0]==oldz[D.s[i].w[k].f][D.s[i].w[k].l])//对当前状态i中的每个项目,查询每个产生式,例如:A->a.Ab应找到A->...
   {
               f

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值