递归下降LL(1)文法实现文法分析器(附完整代码)

目录

  • 基本信息
  • 项目内容
    • 1 题目
    • 2 程序代码
    • 3 结果截图

基本信息

项目名称: 文法分析器
编译语言:C++
运行环境:Devcpp
操作系统:Windows 10

项目内容

1 题目

对如下课本《编译原理(第3版)》P100,第3题,用递归下降法写出分析程序,输入两个符号串进行测试,一个符号串为符合文法的句子,另一个不是该文法的句子。

例题 3. 已知文法G[S]:

S->MH | a
H->LSo |ε
K->dML |ε
L->eHf
M->K | bLM

判断G是否是LL(1)文法,如果是,构造LL(1)分析表。

2 程序代码

main.cpp

/*
    项目名称:三级项目1 文法分析器
    学号: xxxxxxxx
    姓名:汕大学长 
    班级:19计算机 
    时间:2021/12/19 
*/
#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#define STACK_INIT_SIZE 100  //存储空间初始分配两
#define STACKINCREMENT 10    //存储空间分配增量

//------------栈 结构定义与功能函数-----------// 
typedef struct{
	char *base;
	char *top;
	int stacksize;
}SqStack; 

int InitStack(SqStack &S);  //初始化一个空栈 
int Push(SqStack &S, char e); //插入元素 
int Pop(SqStack &S, char &e); //弹出元素

int InitStack(SqStack &S){
	//构造一个空栈S
	S.base = (char *)malloc(STACK_INIT_SIZE * sizeof(char));
	if(!S.base)exit(OVERFLOW);  //存储分配失败
	S.top = S.base;
	S.stacksize = STACK_INIT_SIZE;
	return 1; 
} //InitStack

int Push(SqStack &S, char e){
	//插入元素e为新的栈顶元素
	if(S.top - S.base>=S.stacksize){ //栈满,追加存储空间
		S.base = (char *)realloc(S.base, 
		            (S.stacksize+STACKINCREMENT) * sizeof(char));
		if(!S.base)exit(OVERFLOW); //存储分配失败
		S.top = S.base + S.stacksize;
		S.stacksize += STACKINCREMENT; 
	}
	*S.top++ = e;
	return 1; 
} //Push

int Pop(SqStack &S, char &e){
	// 若栈不空,则删除S的栈顶元素,用e返回其值
	if(S.top == S.base)return 0;
	e = * --S.top;
	return 1; 
} //Pop



//-------------文法规则函数---------------// 
int S_1(SqStack &S,char e); // S->MH | a;
int H(SqStack &S,char e);   // H->LSo | #
int K(SqStack &S,char e);   // K->dML | #
int L(SqStack &S,char e);   // L->eHf
int M(SqStack &S,char e);   // M->K | bLM


int S_1(SqStack &S,char e){
	switch(e){
		case 'a':
			Push(S,'a');
			break;
		case 'o':
		case 'd':
		case 'e':
		case 'b':
		case '#':
			Push(S,'H');
			Push(S,'M');
			break;
		default:
			return 0;
	}
	
	return 1;
}

int M(SqStack &S,char e){
	switch(e){
		case 'o':
		case 'd':
		case 'e':
		case '#':
			Push(S,'K');
			break;
		case 'b':
			Push(S,'M');
			Push(S,'L');
			Push(S,'b');
			break;
		default:
			return 0;
	}
	
	return 1;
}

int H(SqStack &S,char e){
	switch(e){
		case 'o':
		case 'f':
		case '#':
			break;
		case 'e':
			Push(S,'o');
			Push(S,'S');
			Push(S,'L');
			break;
		default:
			return 0;
	}
	
	return 1;
}

int L(SqStack &S,char e){
	switch(e){
		case 'e':
			Push(S,'f');
			Push(S,'H');
			Push(S,'e');
			break;
		default:
			return 0;
	}
	
	return 1;
}

int K(SqStack &S,char e){
	switch(e){
		case 'o':
		case 'e':
		case '#':
			break;
		case 'd':
			Push(S,'L');
			Push(S,'M');
			Push(S,'d');
			break;
		default:
			return 0;
	}
	
	return 1;
}

//--------------递归下降LL(1)方法------------// 
int check(SqStack &S, SqStack &S_temp){
	// 匹配函数 
	char e;
	char e_top;
	Push(S,'#');
    Push(S,'S'); //初始化栈内容 #S 
    
    int flag=1;  //匹配成功标志 
	Pop(S,e_top);  //e_top='S'
    Pop(S_temp,e); //获取待匹配栈元素
	while(1){
        while(e_top==e){ //弹出匹配的元素 
            if(e_top=='#'&&e=='#'){
    	        printf("匹配成功。\n\n");
    	        return 1; 
	        }
	        Pop(S,e_top);
            Pop(S_temp,e);
		}
        switch(e_top){ //文法规则处理算法 
		    case 'S':
			    flag = S_1(S,e);
			    break;
		    case 'H':
			    flag = H(S,e);
			    break;
		    case 'K':
			    flag = K(S,e);
			    break;
		    case 'L':
			    flag = L(S,e);
			    break;
		    case 'M':
			    flag = M(S,e);
			    break;
			default:
				flag=0; //匹配失败标识 
	    }
	    
	    if(flag==0){
	    	printf("匹配失败。\n\n");
    	    return 0; 
		}
	    
	    Pop(S,e_top);
	} 
	
	return 1;
}


void menu(){  //开始界面 
	printf("Please enter number to choose the funtion.\n");
	printf("0. Exit\n");
	printf("1. Enter\n");
}

//----------------主函数--------------// 
int main() {
	char e;  //栈元素 
	char e_top;  //栈顶元素 
    SqStack S,S_temp;  //检测栈S,分析(读入)栈S_temp
	InitStack(S);
	InitStack(S_temp); //初始化为空栈
	
	int num;
	while(1){
		menu();
		printf("Number:");
		scanf("%d",&num);
		if(num==0) break;
		
		printf("\n请输入需测试的符号串,并以'#'号结尾。\n");
	    printf("符号串:");
	    fflush(stdin);	//强制刷新输入缓冲区,防止换行符的干扰 
        while(1){ //获取输入符号串 
    	    scanf("%c",&e);
    	    Push(S,e);
    	    if(e=='#') break;
	    }
	
	    while(S.top != S.base){ //获得分析栈(余留串) 
		    Pop(S,e);
		    Push(S_temp,e);
	    }

        check(S,S_temp); //匹配函数,开始判断
	}
	
    return 1;
}

3 结果截图

测试符号串 实验结果
bef# 匹配成功
acc# 匹配失败

实验结果如下图所示:
递归下降LL(1)文法实现文法分析器(附完整代码)_第1张图片

你可能感兴趣的:(编译原理,递归下降LL(1)文法,c++)