以上述文法为基础 补充完整这个程序#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 18:38:48 浏览: 165
这段程序是一个递归下降分析算法,用于对给定的表达式进行语法分析。其中包含了产生式的描述和对应的函数实现,以及符号堆栈的操作。
具体来说,程序中定义了符号堆栈(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;
}
```
请给出判断所输入字符串是否为四则运算的程序,请使用ll(1)文法
在C语言中,判断一个字符串是否符合四则运算并使用LL(1)文法规则,我们需要首先定义一个简单的解析器来识别合法的算术表达式。由于直接编写完整的LL(1)解析器较为复杂,我们通常会采用递归下降解析器或者使用现成的库(如ANTLR等)。下面是一个简化的例子,展示了如何使用栈来检查运算符优先级和括号匹配:
```c
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
bool is_valid_expression(char* expr, int precedence[4], int max_precedence) {
int stack_size = 0;
bool negative = false;
char current = expr[0];
if (current == '-') {
negative = true;
current = expr[1];
}
for (int i = 1; expr[i]; i++) {
if (isdigit(current)) { // 数字字符
while (i < strlen(expr) && isdigit(expr[i])) {
current = expr[i++];
}
return check_number(current - '0', negative);
} else if (current == '(') { // 开始一个新的运算
stack_size++;
} else if (current == ')') { // 结束运算
stack_size--;
if (stack_size < 0) {
return false;
}
} else if (is_operator(current, precedence, max_precedence)) { // 运算符
while (stack_size > 0 && is_operator(stack[-1], precedence, max_precedence) && precedence[current] <= precedence[stack[-1]]) {
push_result(stack, negative);
stack_size--;
negative = false;
}
stack[stack_size++] = current;
} else {
return false; // 非法字符
}
current = expr[i];
}
// 如果所有括号都关闭了
while (stack_size > 0) {
push_result(stack, negative);
stack_size--;
negative = false;
}
return stack_size == 0;
}
// 其他辅助函数,如检查数字、运算符优先级等
int main() {
int precedence[] = {4, 3, 2, 1}; // 根据操作符的优先级设置
const char* test_cases[] = {"3 + 5", "3 + (5 * 2)", "-1 / 0", "3 + a"}; // 测试案例
for (const char* case_str : test_cases) {
if (is_valid_expression(case_str, precedence, 4)) {
printf("%s is a valid expression.\n", case_str);
} else {
printf("%s is not a valid expression.\n", case_str);
}
}
return 0;
}
```
请注意,这个简化版本仅适用于最基础的四则运算,实际应用中可能需要更复杂的语法处理。
阅读全文
相关推荐
















