编译原理本科课程 专题2 递归下降语法分析设计

一、 程序功能描述

本程序由C语言编写,与专题1词法分析程序相连接,接受词法分析输出的二元式序列,完成以下描述赋值语句的LL(1)文法的递归下降分析程序:
G[S]:
S→V=E
E→TE′
E′→ATE′|ε
T→FT′
T′→MFT′|ε
F→ (E)|i
A→+|-
M→*|/
V→i
本程序可以正确读取二元式序列,并输出对应的单词符号编码,分析时给出递归下降语法分析的过程,并提供分析信息。

二、 主要数据结构描述

首先,程序将数组的最大长度定义为1024,而后定义了字符数组buf接受待分析的二元式序列,并用字符数组input整理后得到算数表达式。整型数组key用于记录各单词对应的编码,flag用于判断赋值语句是否正确。此外,数组paths用于记录测试用例存放的地址。

三、 程序结构描述

程序使用了C语言的三个基本库:<stdio.h>,<stdlib.h>和<string.h>,共创建了10个函数(含main函数),从S到V的子程序设计对应本实验的LL(1)文法:

四、 程序测试

测试案例展示如下:
在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LENGTH 1024
const char* paths[4] = { "./samples/test1.txt","./samples/test2.txt",
		"./samples/test3.txt","./samples/test4.txt" };
int flag = 0;
int index = 0;
int key[MAX_LENGTH];


void S();
void E();
void E_();
void T();
void T_();
void F();
void A();
void M();
void V();

void S() {
	if (flag == 0) {
		printf("S ");
		if (key[index] == 1) {
			V();
			if (flag == 0 && key[index] == 31) {
				index++;
				E();
			}
			else {
				flag = 1;
				printf("\nS处出现错误\n");
			}
		}
		else {
			flag = 1;
			printf("\nS处出现错误\n");
		}
	}
}
void E() {
	if (flag == 0) {
		printf("->E ");
		if (key[index] == 23 || key[index] == 1) {
			T();
			if (flag == 0) {
				if (key[index] == 16 || key[index] == 17) {
					E_();
				}
				else if (key[index] == 24 || key[index] == -1) {
					return;
				}
				else {
					flag = 1;
					printf("\nE处出现错误\n");
				}
			}
		}
		else {
			flag = 1;
			printf("\nE处出现错误\n");
		}
	}
}
void E_() {
	if (flag == 0) {
		printf("->E' ");
		if (key[index] == 16 || key[index] == 17) {
			A();
			if (flag == 0) {
				if (key[index] == 23 || key[index] == 1) {
					T();
					if (flag == 0) {
						if (key[index] == 16 || key[index] == 17) {
							E_();
						}
						else if (key[index] == 24 || key[index] == -1) {
							return;
						}
						else {
							flag = 1;
							printf("\nE'处出现错误\n");
						}
					}
				}
				else {
					flag = 1;
					printf("\nE'处出现错误\n");
				}
			}
		}
		else if (key[index] == 24 || key[index] == -1) {
			return;
		}
		else {
			flag = 1;
			printf("\nE'处出现错误\n");
		}
	}
}
void T() {
	if (flag == 0) {
		printf("->T ");
		if (key[index] == 23 || key[index] == 1) {
			F();
			if (flag == 0) {
				if (key[index] == 18 || key[index] == 19) {
					T_();
				}
				else if (key[index] == 16 || key[index] == 17 || key[index] == 24 || key[index] == -1) {
					return;
				}
				else {
					flag = 1;
					printf("\nT处出现错误\n");
				}
			}
		}
		else {
			flag = 1;
			printf("\nT处出现错误\n");
		}
	}
}
void T_() {
	if (flag == 0) {
		printf("->T' ");
		if (key[index] == 18 || key[index] == 19) {
			M();
			if (flag == 0) {
				F();
				if (flag == 0) {
					T_();
				}
			}
		}
		else if (key[index] == 16 || key[index] == 17 || key[index] == 24 || key[index] == -1) {
			return;
		}
		else {
			flag = 1;
			printf("\nT'处出现错误\n");
		}
	}
}
void F() {
	if (flag == 0) {
		printf("->F ");
		if (key[index] == 23) {
			index++;
			if (key[index] == 23 || key[index] == 1) {
				E();
				if (flag == 0) {
					if (key[index] == 24) {
						index++;
					}
					else {
						flag = 1;
						printf("\nF处出现错误\n");
					}
				}
			}
			else {
				flag = 1;
				printf("\nF处出现错误\n");
			}
		}
		else if (key[index] == 1) {
			index++;
		}
		else {
			flag = 1;
			printf("\nF处出现错误\n");
		}
	}
}
void A()
{
	if (flag == 0) {
		printf("->A ");
		if (key[index] == 16 || key[index] == 17) {
			index++;
		}
		else {
			flag = 1;
			printf("\nA处出现错误\n");
		}
	}
}
void M()
{
	if (flag == 0) {
		printf("->M");
		if (key[index] == 18 || key[index] == 19) {
			index++;
		}
		else {
			flag = 1;
			printf("\nM处出现错误\n");
		}
	}
}
void V()
{
	if (flag == 0) {
		printf("->V ");
		if (key[index] == 1) {
			index++;
		}
		else {
			flag = 1;
			printf("\nV处出现错误\n");
		}
	}
}
int main() {
	for (int t = 0; t < 4; t++) {
		flag = 0;

		FILE* fp;
		char buf[MAX_LENGTH] = { 0 };		//用于保存文件词法分析的结果 
		char input[MAX_LENGTH] = { 0 };		//input为待检测的语句
		const char* path = paths[t];
		int len = 0;
		int k = 0, x = 0, j = 0;
		if ((fp = fopen(path, "r")) != NULL) {
			printf("专题2_递归下降语法分析-----\n测试用例%c: \n\n", path[strlen(path) - 5]);
			printf("词法分析输出的二元式序列:\n");
			while (fgets(buf, MAX_LENGTH, fp) != NULL) {	//每次读取一行 
				len = strlen(buf);
				buf[len] = '\0';						//去除换行符 
				printf("%s \n", buf);
				for (index = 0; index < len; index++) {
					if (buf[index] == '(') {				//将单词符号类别编码转换成数字 
						if (buf[index + 2] != ',' && ('0' <= buf[index + 1] && buf[index + 1] <= '9'))
							key[j++] = int((buf[index + 1] - '0') * 10 + buf[index + 2] - '0');
						else if (buf[index + 2] == ',' && '0' <= buf[index + 1] && buf[index + 1] <= '9')
							key[j++] = int(buf[index + 1] - '0');
						continue;
					}
					if (buf[index] == ',') {
						index++;
						if (buf[index] == ')')
						{
							input[x++] = ')';
							index++;
							continue;
						}
						while (buf[index] != ')') {
							input[x++] = buf[index];
							index++;
						}
					}
				}
			}
		}
		input[x++] = ';';
		key[j++] = -1;
		fclose(fp);
		printf("算术表达式为:\n%s\n", input);
		printf("表达式中单词符号类别编码依次为:\n");
		for (index = 0; index < j - 1; index++)
			printf("%d\t", key[index]);
		printf("\n");
		if (key[0] == -1)
			return 0;
		printf("递归下降语法分析过程:\n");
		index = 0;
		S();
		printf("\n");
		if (key[index] == -1 && flag == 0) {
			printf("赋值语句合法!\n\n\n");
		}
		else {
			printf("赋值语句不合法!\n\n\n");
		}
		
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值