C 语言实现用算符优先分析法判断任意字符串是否符合文法S -> XY X -> aX | bX | ε Y -> aaZ | bbZ Z -> aZ | bZ | ε
时间: 2023-08-07 22:12:26 浏览: 115
以下是用 C 语言实现算符优先分析法判断任意字符串是否符合文法 S -> XY X -> aX | bX | ε Y -> aaZ | bbZ Z -> aZ | bZ | ε 的代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LEN 100
char stack[MAX_LEN]; // 栈
int top = -1; // 栈顶指针
int is_operator(char op) {
// 判断是否为运算符
return op == 'a' || op == 'b' || op == 'Z' || op == 'Y' || op == '(' || op == ')';
}
int get_priority(char op) {
// 获取运算符优先级
if (op == 'a' || op == 'b')
return 2;
else if (op == 'Z')
return 1;
else
return 0;
}
char get_top() {
// 获取栈顶元素
if (top == -1)
return '#';
return stack[top];
}
void push(char c) {
// 入栈
stack[++top] = c;
}
char pop() {
// 出栈
if (top == -1)
return '#';
return stack[top--];
}
int is_valid(char s[]) {
int i, j, len;
char ch, cur_op, top_op;
len = strlen(s);
push('#'); // 将 '#' 入栈
for (i = 0; i < len; ) {
ch = s[i];
if (!is_operator(ch)) {
// 如果是操作数,则直接输出
i++;
continue;
}
top_op = get_top();
if (get_priority(ch) > get_priority(top_op)) {
// 如果当前运算符优先级大于栈顶运算符优先级,则将其入栈
push(ch);
i++;
} else if (get_priority(ch) == get_priority(top_op)) {
// 如果当前运算符优先级等于栈顶运算符优先级,则将栈顶运算符出栈
pop();
i++;
} else {
// 如果当前运算符优先级小于栈顶运算符优先级,则将栈顶运算符出栈
cur_op = pop();
if (cur_op == 'a' || cur_op == 'b') {
// 如果是终结符 a 或者 b,则需要再出栈一个操作数
pop();
}
if (cur_op == 'Y') {
// 如果是非终结符 Y,则需要查看下一个输入符号的优先级
if (s[i] == 'a') {
// 如果下一个输入符号是 a,则执行移进操作
push(cur_op);
push('a');
i++;
} else {
// 如果下一个输入符号是 b 或者 $,则执行归约操作
pop();
pop();
i++;
}
}
}
}
// 如果栈顶元素为 '#',则表示输入的字符串符合文法
return get_top() == '#';
}
int main() {
char s[MAX_LEN];
printf("请输入待判断的字符串:");
scanf("%s", s);
if (is_valid(s))
printf("该字符串符合文法!\n");
else
printf("该字符串不符合文法!\n");
return 0;
}
```
该代码中,使用栈来进行算符优先分析,对于输入字符串中的每个字符,如果是操作数,则直接输出;如果是运算符,则根据当前运算符的优先级与栈顶运算符的优先级进行比较,执行相应的移进、归约操作。需要注意的是,在对非终结符 Y 进行归约操作时,需要查看下一个输入符号的优先级,执行相应的移进、归约操作。最终,判断栈顶元素是否为 '#',如果是,则表示输入的字符串符合文法。
阅读全文