以上述文法为基础 补充完整这个程序#include "stdio.h" #include "string.h" char stack[80]="#E"; /* 符号堆栈描述为stack ,#为符号堆栈栈底符*,E为文法开始符*/ char sym[80]={"i*i+i#"}; /* 输入串描述,以表达式i*i+i,#为输入串结束符 */ char str[80]=""; /* 记录所用产生式 */ void push(char ch) /* 实现将CH中的字符压入stack栈 */ { .......} char pop() /* 实现将stack栈栈顶的字符弹出给CH,并返回CH值 */ { .....} void E() /* 关于产生式 E->TM 的描述*/ { push('M'); push('T'); strcpy(str,"E->TM");} void M( )/* 关于产生式 M->+TM | ε的描述*/ { ......} void T( )/* 关于产生式 T->FK 的描述*/ { .....} void K()/* 关于产生式 K->*FK | ε的描述*/ { ......} void F()/* 关于产生式 F->(E) | i的描述*/ { .....} void main() { char ch; strcpy(str,""); int i,j=0; printf("\n递归下降分析算法\n"); printf("\n%-6d%-20s%20s%10s",j,stack,sym,str); j=j+1; ch=pop(); while(ch!='#') {strcpy(str,""); if(ch=='i' || ch=='*' || ch=='+' || ch=='(' || ch == ')') /* 如果栈顶字符为文法终结符集VT*/ if(ch == sym[0]) {i=0; while(sym[i]) sym[i++]=sym[i+1];} else printf("\n EERROR "); else/* 如果栈顶字符为文法非终结符集VN*/ switch(ch) {case 'E':E();break; case 'M':M();break; case 'T':T();break; case 'K':K();break; case 'F':F();break; default : printf("\n error!\n");} printf("\n\n %-6d%-20s%20s%10s",j,stack,sym,str); j++; ch=pop();} }
时间: 2024-03-29 21:38:48 浏览: 153
这段程序是一个递归下降分析算法,用于对给定的表达式进行语法分析。其中包含了产生式的描述和对应的函数实现,以及符号堆栈的操作。
具体来说,程序中定义了符号堆栈(stack)、输入串(sym)和所用产生式(str)三个字符数组。其中,符号堆栈包含了文法开始符号(E)和栈底符号(#),输入串以#为结束符号,所用产生式用于记录语法分析的过程。
程序中实现了将字符压入栈的函数push和将栈顶字符弹出的函数pop。同时,根据文法描述,实现了产生式E->TM、M->+TM|ε、T->FK、K->*FK|ε、F->(E)|i的函数实现。这些函数的作用是根据文法规则对符号堆栈进行操作,生成一系列的产生式。
在主函数中,程序首先初始化符号堆栈和所用产生式,并输出表头。然后,程序进行循环,每次将栈顶字符弹出,根据其是否为终结符或非终结符进行相应的操作。最后输出每次操作后的符号堆栈、输入串和所用产生式。
通过上述递归下降分析算法,可以对给定的表达式进行语法分析,并输出每次操作后的符号堆栈和所用产生式,从而帮助程序员更好地理解语法分析的过程。
相关问题
修改以下代码 让它正常运行 #include "stdio.h" #include "string.h" char stack[80]="#E"; /* 符号堆栈描述为stack ,#为符号堆栈栈底符*,E为文法开始符*/ char sym[80]={"i*i+i#"}; /* 输入串描述,以表达式i*i+i,#为输入串结束符 */ char str[80]=""; /* 记录所用产生式 */ void push(char ch) /* 实现将CH中的字符压入stack栈 */ { .......} char pop() /* 实现将stack栈栈顶的字符弹出给CH,并返回CH值 */ { .....} void E() /* 关于产生式 E->TM 的描述*/ { push('M'); push('T'); strcpy(str,"E->TM");} void M( )/* 关于产生式 M->+TM | ε的描述*/ { ......} void T( )/* 关于产生式 T->FK 的描述*/ { .....} void K()/* 关于产生式 K->*FK | ε的描述*/ { ......} void F()/* 关于产生式 F->(E) | i的描述*/ { .....} void main() { char ch; strcpy(str,""); int i,j=0; printf("\n递归下降分析算法\n"); printf("\n%-6d%-20s%20s%10s",j,stack,sym,str); j=j+1; ch=pop(); while(ch!='#') {strcpy(str,""); if(ch=='i' || ch=='*' || ch=='+' || ch=='(' || ch == ')') /* 如果栈顶字符为文法终结符集VT*/ if(ch == sym[0]) {i=0; while(sym[i]) sym[i++]=sym[i+1];} else printf("\n EERROR "); else/* 如果栈顶字符为文法非终结符集VN*/ switch(ch) {case 'E':E();break; case 'M':M();break; case 'T':T();break; case 'K':K();break; case 'F':F();break; default : printf("\n error!\n");} printf("\n\n %-6d%-20s%20s%10s",j,stack,sym,str); j++; ch=pop();} }
由于push和pop函数的具体实现并未给出,这里用假设的方式实现它们,同时修正了注释中的错误:
```c
#include <stdio.h>
#include <string.h>
char stack[80] = "#E"; // 符号堆栈描述为stack,#为符号堆栈栈底符号,E为文法开始符
char sym[80] = "i*i+i#"; // 输入串描述,以表达式i*i+i,#为输入串结束符
char str[80] = ""; // 记录所用产生式
void push(char ch) { // 实现将ch中的字符压入stack栈
stack[strlen(stack)] = ch;
}
char pop() { // 实现将stack栈栈顶的字符弹出给ch,并返回ch值
char ch = stack[strlen(stack) - 1];
stack[strlen(stack) - 1] = '\0';
return ch;
}
void E() { // 关于产生式 E->TM 的描述
push('M');
push('T');
strcpy(str, "E->TM");
}
void M() { // 关于产生式 M->+TM | ε的描述
char ch = sym[0];
if (ch == '+') {
pop();
push('M');
push('T');
push('+');
strcpy(str, "M->+TM");
} else {
strcpy(str, "M->ε");
}
}
void T() { // 关于产生式 T->FK 的描述
char ch = sym[0];
if (ch == 'i' || ch == '(') {
push('K');
push('F');
strcpy(str, "T->FK");
} else {
printf("\nEERROR");
}
}
void K() { // 关于产生式 K->*FK | ε的描述
char ch = sym[0];
if (ch == '*') {
pop();
push('K');
push('F');
push('*');
strcpy(str, "K->*FK");
} else {
strcpy(str, "K->ε");
}
}
void F() { // 关于产生式 F->(E) | i 的描述
char ch = sym[0];
if (ch == 'i') {
pop();
push('i');
strcpy(str, "F->i");
} else if (ch == '(') {
pop();
push(')');
push('E');
push('(');
strcpy(str, "F->(E)");
} else {
printf("\nEERROR");
}
}
int main() {
char ch;
printf("\n递归下降分析算法\n");
int i, j = 0;
printf("\n%-6d%-20s%20s%10s", j, stack, sym, str);
j = j + 1;
ch = pop();
while (ch != '#') {
strcpy(str, "");
if (ch == 'i' || ch == '*' || ch == '+' || ch == '(' || ch == ')') { // 如果栈顶字符为文法终结符集VT
if (ch == sym[0]) {
i = 0;
while (sym[i]) {
sym[i] = sym[i + 1];
i++;
}
}
} else { // 如果栈顶字符为文法非终结符集VN
switch (ch) {
case 'E':
E();
break;
case 'M':
M();
break;
case 'T':
T();
break;
case 'K':
K();
break;
case 'F':
F();
break;
default:
printf("\nerror!\n");
return 1;
}
}
printf("\n\n%-6d%-20s%20s%10s", j, stack, sym, str);
j++;
ch = pop();
}
return 0;
}
```
给出文法G(E):E→a | b | (T) T->cT' |ET' T'->+E |*E | ε 的预测分析程序
以下是文法G(E):E→a | b | (T) T->cT' | ET' T'->+E |*E | ε的预测分析程序:
```
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define SIZE 10
char stack[SIZE]; //定义栈
int top = -1; //栈顶指针初始化为-1
void push(char c) { //入栈操作
top++;
stack[top] = c;
}
void pop() { //出栈操作
top--;
}
char get_top() { //获取栈顶元素
return stack[top];
}
void error() { //错误处理函数
printf("Error\n");
exit(0);
}
int is_terminal(char c) { //判断是否为终结符
if(c == 'a' || c == 'b' || c == 'c' || c == '+' || c == '*' || c == '(' || c == ')' || c == '$') {
return 1;
}
return 0;
}
int get_index(char c) { //获取索引值
if(c == 'a') {
return 0;
} else if(c == 'b') {
return 1;
} else if(c == 'c') {
return 2;
} else if(c == '+') {
return 3;
} else if(c == '*') {
return 4;
} else if(c == '(') {
return 5;
} else if(c == ')') {
return 6;
} else if(c == '$') {
return 7;
}
}
char table[6][8][3] = { //预测分析表
{ {"a", ""}, {"b", ""}, {"c", ""}, {"", ""}, {"", ""}, {"(T)", ""}, {"", ""}, {"", ""} },
{ {"", ""}, {"", ""}, {"cT'", ""}, {"", ""}, {"", ""}, {"ET'", ""}, {"", ""}, {"", ""} },
{ {"a", ""}, {"b", ""}, {"cT'", ""}, {"", ""}, {"", ""}, {"(T)", ""}, {"", ""}, {"", ""} },
{ {"", "+E"}, {"", "", ""}, {"", "", ""}, {"+E", ""}, {"*E", ""}, {"", ""}, {"", "ε"}, {"", "ε"} },
{ {"", "ε"}, {"", "ε"}, {"", "*E"}, {"+E", ""}, {"*E", ""}, {"", ""}, {"", "ε"}, {"", "ε"} },
{ {"a", ""}, {"b", ""}, {"cT'", ""}, {"", ""}, {"", ""}, {"(T)", ""}, {"", ""}, {"", ""} }
};
int main() {
char input[SIZE];
printf("请输入要分析的字符串:");
scanf("%s", input);
strcat(input, "$"); //在输入字符串末尾加上结束符"$"
push('$');
push('E');
int i = 0;
while(input[i] != '\0') { //遍历输入字符串
if(get_top() == '$' && input[i] == '$') {
printf("Success\n");
break;
} else if(get_top() == input[i]) {
pop();
i++;
} else if(is_terminal(get_top())) {
error();
} else {
int row = get_top() - 'E'; //获取行号
int col = get_index(input[i]); //获取列号
if(strcmp(table[row][col], "") == 0) {
error();
} else if(strcmp(table[row][col], "ε") == 0) {
pop();
} else {
char* str = table[row][col];
int len = strlen(str);
pop();
int j;
for(j = len - 1; j >= 0; j--) {
push(str[j]);
}
}
}
}
return 0;
}
```
注:在该程序中,使用了一个栈来模拟预测分析表中的栈操作,使用了一个预测分析表来判断下一步要进行的操作,其中行号和列号分别为非终结符的编号和终结符的编号。
阅读全文