一、 程序功能描述
本程序由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;
}