1 #include <iostream>
2 #include <cstring>
3 #include <cstdio>
4 #include <algorithm>
5 #include <cstdlib>
6 #include <vector>
7 #include <string>
8 #include <cctype>
9 #include <map>
10 #include <set>
11 #define MAX 507
12
13 using namespace std;
14
15
16 //大写字母为非终止符(可以多一个'的标号做区分),小写字母为终止符,用~代替epsilon
17 class WF
18 {
19 public:
20 string left;
21 set<string> right;
22 WF ( char s[] )
23 {
24 left = s;
25 }
26 void print ( )
27 {
28 printf ( "%s->" , left.c_str() );
29 set<string>::iterator it = right.begin();
30 if ( right.begin()!= right.end() )
31 {
32 printf ( "%s" , it->c_str() );
33 it++;
34 }
35 for(; it != right.end() ; it++ )
36 printf ( "|%s" , it->c_str() );
37 puts("");
38 }
39 void insert ( char s[] )
40 {
41 right.insert ( s );
42 }
43 };
44
45 map<string,set<char> > first;
46 map<string,set<char> > follow;
47 map<string,int> VN_dic;
48 vector<WF> VN_set;
49 bool used[MAX];
50
51 void dfs ( int x )
52 {
53 if ( used[x] ) return;
54 used[x] = 1;
55 string& left = VN_set[x].left;
56 set<string>& right = VN_set[x].right;
57 set<string>::iterator it = right.begin();
58 for ( ; it!= right.end() ; it++ )
59 for ( int i = 0 ; i < it->length() ; i++ )
60 {
61 if ( !isupper( it->at(i) ) && it->at(i) != '\'' )
62 {
63 first[left].insert ( it->at(i) );
64 break;
65 }
66 if ( isupper( it->at(i) ) )
67 {
68 int y;
69 if ( i != it->length()-1 && it->at(i+1) == '\'' )
70 y = VN_dic[it->substr(i,2)]-1;
71 else y = VN_dic[it->substr(i,1)]-1;
72 string& tleft = VN_set[y].left;
73 dfs ( y );
74 set<char>& temp = first[tleft];
75 set<char>::iterator it1 = temp.begin();
76 bool flag = true;
77 for ( ; it1 != temp.end() ; it1++ )
78 {
79 if ( *it1 == '~' ) flag = false;
80 first[left].insert( *it1 );
81 }
82 if ( flag ) break;
83 }
84 else continue;
85 }
86 }
87
88 void make_first ( )
89 {
90 memset ( used , 0 , sizeof ( used ) );
91 for ( int i = 0 ; i < VN_set.size() ; i++ )
92 dfs ( i );
93 #define DEBUG
94 #ifdef DEBUG
95 map<string,set<char> >::iterator it = first.begin();
96 for ( ; it != first.end() ; it++ )
97 {
98 printf ( "FIRST(%s)={" , it->first.c_str() );
99 set<char> & temp = it->second;
100 set<char>::iterator it1 = temp.begin();
101 bool flag = false;
102 for ( ; it1 != temp.end() ; it1++ )
103 {
104 if ( flag ) printf ( "," );
105 printf ( "%c" , *it1 );
106 flag = true;
107 }
108 puts ("}");
109 }
110 #endif
111 }
112
113 int main ( )
114 {
115 int n;
116 char s[MAX];
117 while ( ~scanf ( "%d" , &n ) )
118 {
119 for ( int i = 0 ; i < n ; i++ )
120 {
121 scanf ( "%s" , s );
122 int len = strlen ( s ),j;
123 for ( j = 0 ; j < len ; j++ )
124 if ( s[j] == '-' ) break;
125 s[j] = 0;
126 if ( !VN_dic[s] )
127 {
128 VN_set.push_back ( s );
129 VN_dic[s] = VN_set.size();
130 }
131 int x = VN_dic[s]-1;
132 VN_set[x].insert ( s+j+2 );
133 }
134 make_first();
135 }
136 }