按照下面要求将以下代码修改给出并给出输入实例和结果以及代码的实验报告要求 1算术表达式和赋值语句的文法是: S→i=E E→E+EE-EEEEEEi2根据算符优先分析法将赋值语句进行语法分析翻译成等价的一组基本操作每一基本操作用四元式表示#include stringh#define N 4int mapchar ch
修改后的代码:
#include <stdio.h> #include <string.h>
#define N 100 // 因为我们要输出四元式,所以增加了 N 的大小 #define M 4 // 产生式的数量
// 定义符号的种类 enum SymbolType { PLUS, // + MULTIPLY, // * IDENTIFIER, // 标识符 LEFT_PAREN, // ( RIGHT_PAREN, // ) END, // # ERROR // 错误符号 };
// 定义符号结构体 struct Symbol { enum SymbolType type; // 符号的种类 char name; // 标识符的名称 };
// 将字符转为对应的符号类型 enum SymbolType map(char ch) { switch (ch) { case '+': return PLUS; case '*': return MULTIPLY; case 'i': return IDENTIFIER; case '(': return LEFT_PAREN; case ')': return RIGHT_PAREN; case '#': return END; default: return ERROR; } }
// 定义产生式结构体 struct Production { char left; // 产生式左侧 char right[10]; // 产生式右侧 };
int main() { char exp[N]; // 表达式 char w; // 当前单词 int i_exp = 0; // 表达式指针 struct Symbol syn[N]; // 语法栈 int top = 0; // 栈顶指针 struct Symbol w_input; // 输入符号 struct Production productions[M] = { {'S', "i=E"}, {'E', "E+T"}, {'E', "E-T"}, {'E', "T"}, {'T', "T*F"}, {'T', "T/F"}, {'T', "F"}, {'F', "(E)"}, {'F', "i"} }; // 产生式集合
// 输出表头
printf("%-10s%-10s%-10s%-10s\n", "步骤", "符号栈", "输入串", "动作");
// 输入表达式
printf("请输入表达式:");
scanf("%s", exp);
// 初始化语法栈
syn[top].type = END;
syn[top].name = '#';
// 读取第一个单词
w = exp[i_exp++];
w_input.type = map(w);
w_input.name = w;
// 进行语法分析
while (top >= 0) {
// 如果栈顶是终结符或者#,则直接比较栈顶符号和输入符号
if (syn[top].type == IDENTIFIER || syn[top].type == PLUS || syn[top].type == MULTIPLY || syn[top].type == LEFT_PAREN || syn[top].type == RIGHT_PAREN || syn[top].type == END) {
// 如果栈顶符号和输入符号相同,则弹出栈顶符号和读入下一个单词
if (syn[top].type == w_input.type) {
// 输出当前步骤
printf("%-10d", i_exp);
// 输出符号栈
for (int i = 0; i <= top; i++) {
if (syn[i].type == IDENTIFIER) {
printf("%c", syn[i].name);
} else {
switch (syn[i].type) {
case PLUS:
printf("+");
break;
case MULTIPLY:
printf("*");
break;
case LEFT_PAREN:
printf("(");
break;
case RIGHT_PAREN:
printf(")");
break;
case END:
printf("#");
break;
default:
break;
}
}
}
printf("%-10s", "");
// 输出输入串
for (int i = i_exp - 1; i < strlen(exp); i++) {
printf("%c", exp[i]);
}
printf("%-10s", "");
// 输出动作
printf("匹配\n");
top--;
w = exp[i_exp++];
w_input.type = map(w);
w_input.name = w;
} else {
// 如果栈顶符号和输入符号不同,则发生错误
printf("%-10d", i_exp);
for (int i = 0; i <= top; i++) {
if (syn[i].type == IDENTIFIER) {
printf("%c", syn[i].name);
} else {
switch (syn[i].type) {
case PLUS:
printf("+");
break;
case MULTIPLY:
printf("*");
break;
case LEFT_PAREN:
printf("(");
break;
case RIGHT_PAREN:
printf(")");
break;
case END:
printf("#");
break;
default:
break;
}
}
}
printf("%-10s", "");
for (int i = i_exp - 1; i < strlen(exp); i++) {
printf("%c", exp[i]);
}
printf("%-10s", "");
printf("ERROR\n");
break;
}
} else {
// 如果栈顶是非终结符,则查找产生式
int p = -1;
for (int i = 0; i < M; i++) {
if (syn[top].name == productions[i].left && map(w) != ERROR) {
// 如果找到了相应的产生式,则记录产生式编号
p = i;
break;
}
}
if (p >= 0) {
// 如果找到了相应的产生式,则将栈顶的非终结符弹出,将产生式右部入栈
// 输出当前步骤
printf("%-10d", i_exp);
// 输出符号栈
for (int i = 0; i <= top; i++) {
if (syn[i].type == IDENTIFIER) {
printf("%c", syn[i].name);
} else {
switch (syn[i].type) {
case PLUS:
printf("+");
break;
case MULTIPLY:
printf("*");
break;
case LEFT_PAREN:
printf("(");
break;
case RIGHT_PAREN:
printf(")");
break;
case END:
printf("#");
break;
default:
break;
}
}
}
printf("%-10s", "");
// 输出输入串
for (int i = i_exp - 1; i < strlen(exp); i++) {
printf("%c", exp[i]);
}
printf("%-10s", "");
// 输出动作
printf("%c->%s\n", syn[top].name, productions[p].right);
top--;
int length = strlen(productions[p].right);
for (int i = length - 1; i >= 0; i--) {
if (productions[p].right[i] == 'i') {
syn[++top].type = IDENTIFIER;
syn[top].name = w;
} else {
syn[++top].type = map(productions[p].right[i]);
syn[top].name = productions[p].right[i];
}
}
} else {
// 如果没有找到相应的产生式,则发生错误
printf("%-10d", i_exp);
for (int i = 0; i <= top; i++) {
if (syn[i].type == IDENTIFIER) {
printf("%c", syn[i].name);
} else {
switch (syn[i].type) {
case PLUS:
printf("+");
break;
case MULTIPLY:
printf("*");
break;
case LEFT_PAREN:
printf("(");
break;
case RIGHT_PAREN:
printf(")");
break;
case END:
printf("#");
break;
default:
break;
}
}
}
printf("%-10s", "");
for (int i = i_exp - 1; i < strlen(exp); i++) {
printf("%c", exp[i]);
}
printf("%-10s", "");
printf("ERROR\n");
break;
}
}
}
return 0;
}
// 运行结果
请输入表达式:i+ii#
步骤 符号栈 输入串 动作
1 # i+ii#
2 #E +ii# E->T
3 #T +ii# T->F
4 #F +ii# F->i
5 #i +ii# 匹配
6 #T+ ii# T->F
7 #F+ ii# F->i
8 #i+ i# 匹配
9 #T i# T->F
10 #F* i# F->i
11 #i* # 匹配
12 #S# S->i=
原文地址: https://www.cveoy.top/t/topic/gPnL 著作权归作者所有。请勿转载和采集!