求follow集的c语言代码
时间: 2023-10-22 18:23:31 浏览: 86
下面是一个简单的C语言程序,用于计算给定文法的Follow集合:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_RULES 100
#define MAX_SYMBOLS 100
char rules[MAX_RULES][MAX_SYMBOLS]; // 存放产生式的数组
int num_rules = 0; // 产生式的数量
// 判断一个符号是否是非终结符
int is_nonterminal(char c) {
return (c >= 'A' && c <= 'Z');
}
// 计算符号c的Follow集合
void follow(char c, char *result, int *num_results) {
int i, j, k, n;
char first_symbol, last_symbol;
// 如果c是文法的起始符号,则Follow集合包含$
if (c == rules[0][0]) {
result[0] = '$';
*num_results = 1;
}
// 遍历所有产生式
for (i = 0; i < num_rules; i++) {
n = strlen(rules[i]);
// 在产生式右部查找c
for (j = 2; j < n; j++) {
if (rules[i][j] == c) {
// 如果c在产生式右部的末尾,则计算产生式左部符号的Follow集合
if (j == n - 1) {
follow(rules[i][0], result, num_results);
}
else {
// 否则,计算c后面的第一个符号的First集合
first_symbol = rules[i][j+1];
if (is_nonterminal(first_symbol)) {
for (k = 0; k < num_rules; k++) {
if (rules[k][0] == first_symbol) {
follow(rules[i][j], result, num_results);
follow(first_symbol, result, num_results);
break;
}
}
}
else {
result[0] = first_symbol;
*num_results = 1;
}
// 如果该First集合包含空串,则计算产生式左部符号的Follow集合
if (result[0] == '\0') {
follow(rules[i][0], result, num_results);
}
}
}
}
}
}
int main() {
int i, j, num_results;
char result[MAX_SYMBOLS];
// 读入产生式
printf("请输入产生式,以空行结束:\n");
while (fgets(rules[num_rules], MAX_SYMBOLS, stdin) != NULL && rules[num_rules][0] != '\n') {
num_rules++;
}
// 计算每个非终结符的Follow集合
for (i = 0; i < num_rules; i++) {
for (j = 2; j < strlen(rules[i]); j++) {
if (is_nonterminal(rules[i][j])) {
follow(rules[i][j], result, &num_results);
printf("Follow(%c) = { ", rules[i][j]);
for (int k = 0; k < num_results; k++) {
printf("%c ", result[k]);
}
printf("}\n");
}
}
}
return 0;
}
```
该程序使用了递归的方式计算Follow集合。在计算某个非终结符的Follow集合时,需要遍历所有产生式,找到产生式右部包含该非终结符的产生式,并计算该非终结符后面的第一个符号的First集合。如果该First集合包含空串,则还要计算产生式左部符号的Follow集合。最终得到的Follow集合就是所有产生式右部包含该非终结符的Follow集合的并集。如果该符号是文法的起始符号,则它的Follow集合包含$。
阅读全文