LL(1)文法系列(一)first集和follow集
阿新 • • 發佈:2018-12-22
Problem Description
已知文法G[S]的表示式,計算文法中終結符的first集和follow集。在文法G[S]中使用’@’代表空。
現在我們規定文法G[S]中每個表示式只包含一個語句,也就是說不會含有S->A|B這樣的表示式。
Input
第一行輸入一個n(n<10),表示表示式的個數,接下來n行,每行一個表示式。終結符和非終結符的個數都小於10
Output
按照終結符和非終結符輸入的順序輸出。如果集合中包含’@’或’#’,要求’@’位於第一個,’#’位於最後一個。
輸出格式為:
first[c] = a b c
follow[c] = a b c
每個非終結符後都有空格
Sample Input
4
S->ABC
A->a
B->@
C->c
Sample Output
first[S] = a
first[A] = a
first[B] = @
first[C] = c
follow[S] = #
follow[A] = c
follow[B] = c
follow[C] = #
code:
#include <bits/stdc++.h> using namespace std; struct node { char s1[50], s2[50]; }g[100]; char s[110]; int num; map<char, int> Map1; map<char, int> Map2; int Map1_num; int Map2_num; char s1[110], s2[110]; int first[50][50]; int follow[50][50]; int vis[110]; int acc[50]; int select1[100][50]; int c[50][50]; char sta[110]; int cnt; void dfs1(char ch, int dis[]) { if(acc[Map1[ch]]) { for(int i = 1;i<=Map2_num;i++) { dis[i] = first[Map1[ch]][i]; } return; } int value[20]; memset(value, 0, sizeof(value)); for(int i = 1;i<=num;i++) { if(vis[i]) continue; if(g[i].s1[0]!=ch) continue; int j, k, len = strlen(g[i].s2); for(j = 0;j<len;j++) { if(Map1[g[i].s2[j]]) { vis[i] = 1; dfs1(g[i].s2[j], value); for(k = 2;k<=Map2_num;k++) { if(value[k]) dis[k] = 1; } if(value[1] == 0) return; } else { dis[Map2[g[i].s2[j]]] = 1; break; } } if(j == len) { dis[1] = 1; } } return; } void dfs2(char ch, int dis[]) { int i, j, k, len, flag = 0; if(acc[Map1[ch]]) { for(int i = 1;i<=Map2_num;i++) { dis[i] = follow[Map1[ch]][i]; } return; } for(i = 1;i<=num;i++) { len = strlen(g[i].s2); for(j = 0;j<len;j++) { if(g[i].s2[j] == ch) { flag = 1; continue; } if(!flag) continue; if(Map1[g[i].s2[j]]) { for(k = 2;k<=Map2_num;k++) { if(first[Map1[g[i].s2[j]]][k]) { dis[k] = 1; } } if(!first[Map1[g[i].s2[j]]][1]) { flag = 0; } } else { dis[Map2[g[i].s2[j]]] = 1; flag = 0; } } if(!flag||vis[i]) continue; int value[20]; memset(value, 0, sizeof(value)); vis[i] = 1; dfs2(g[i].s1[0], value); for(i = 1;i<=Map2_num;i++) { if(value[i]) dis[i] = 1; } } } int main() { int i, j, len; num = Map1_num = Map2_num = 0; Map1.clear(); Map2.clear(); Map2['@'] = ++Map2_num; s2[Map2_num] = '@'; int m; scanf("%d", &m); while(m--) { scanf("%s", s); len = strlen(s); num++; for(i = 0;i<1;i++) { g[num].s1[i] = s[i]; if(!Map1[s[i]]) { Map1[s[i]] = ++Map1_num; s1[Map1_num] = s[i]; } } g[num].s1[i] = '\0'; for(i = 3;i<len;i++) { g[num].s2[i-3] = s[i]; if(s[i]>='A'&&s[i]<='Z') { if(!Map1[s[i]]) { Map1[s[i]] = ++Map1_num; s1[Map1_num] = s[i]; } } else { if(!Map2[s[i]]) { Map2[s[i]] = ++Map2_num; s2[Map2_num] = s[i]; } } } g[num].s2[i-3] = '\0'; } memset(first, 0, sizeof(first)); memset(acc, 0, sizeof(acc)); for(i = 1;i<=Map1_num;i++) { int value[20]; memset(vis,0,sizeof(vis)); memset(value,0,sizeof(value)); dfs1(s1[i],value); for(j = 1 ; j <= Map2_num; j++) { first[i][j] = value[j] ; } acc[i] = 1 ; printf("first[%c] = ", s1[i]); for(j = 1 ; j <= Map2_num ; j++) { if( first[i][j] ) { printf("%c ", s2[j]); } } printf("\n"); } Map2['#'] = ++Map2_num ; s2[ Map2_num ] = '#' ; memset(follow,0,sizeof(follow)); memset(acc,0,sizeof(acc)); for(i = 1 ; i <= Map1_num ; i++) { int value[20] ; memset(vis,0,sizeof(vis)) ; memset(value,0,sizeof(value)); if( s1[i] == 'S' ) { value[ Map2['#'] ] = 1 ; } dfs2(s1[i],value); for(j = 1 ; j <= Map2_num; j++) { follow[i][j] = value[j] ; } acc[i] = 1 ; printf("follow[%c] = ", s1[i]); for(j = 1 ; j <= Map2_num ; j++) { if( follow[i][j] ) { printf("%c ", s2[j]); } } printf("\n"); } return 0; }