项目名称: 文法分析器
编译语言:C++
运行环境:Devcpp
操作系统:Windows 10
对如下课本《编译原理(第3版)》P100,第3题,用递归下降法写出分析程序,输入两个符号串进行测试,一个符号串为符合文法的句子,另一个不是该文法的句子。
S->MH | a
H->LSo |ε
K->dML |ε
L->eHf
M->K | bLM
判断G是否是LL(1)文法,如果是,构造LL(1)分析表。
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;
}
测试符号串 | 实验结果 |
---|---|
bef# | 匹配成功 |
acc# | 匹配失败 |