Você está na página 1de 5

#include <iostream>

#include<map>
#include<algorithm>
#include<set>
#include<vector>
#include<cstdio>
#include<cctype>
#define all(v,it) \
for(typeof(v.begin()) it = v.begin(); it != v.end(); ++it)
using namespace std;
set<string> first(string key);
set<string> follow(string key);
inline string str(char ch){ return string(1,ch);}
void tabulate();
// head set(body1,body2..)
* non terminal ( first) *
non terminal ( foll
ow)
map<string,vector<string> > k; map<string,set<string> > f; map<string,set<strin
g> > w;
map<string,int> flag_fs,flag_fl;
map<pair<string,string> ,set<string> > table;
int main()
{
freopen("input.txt","r",stdin);
int n; cin>>n;
while(n--){
string s; cin>>s;
string key= s.substr(0,1);
flag_fs[key]=0;flag_fl[key]=0;
int pos=3,tpos=s.find('|',pos);
while(tpos != -1){
k[key].push_back(s.substr(pos,tpos-pos));
pos = tpos+1;
tpos=s.find('|',pos);
}
int rpos = s.find_last_of('|');
if(rpos!=-1)
k[key].push_back(s.substr(rpos+1));
else
k[key].push_back(s.substr(3));
}
map<string,vector<string> >::iterator it;
for(it=k.begin();it!=k.end();++it){
first(it->first);
cout<< it->first <<" ";
for(unsigned int i=0;i<k[it->first].size();i++) cout<<k[it->first][i]<<"
";
cout<<endl;
}
w["E"].insert("$");
cout<<endl<<"first"<<endl<<endl;
map<string,set<string> >::iterator its;
for(its=f.begin();its!=f.end();++its){
cout<< its->first <<" ";
set<string>::iterator a = its->second.begin();
for(a;a!=its->second.end();a++)
{
cout<<*a<<" ";

}
follow(its->first);
cout<<endl;
}
cout<<endl<<" follow "<<endl<<endl;
for(its=w.begin();its!=w.end();++its){
cout<<its->first<<" ";
set<string>::iterator a = its->second.begin();
for(a;a!=its->second.end();a++)
{
cout<<*a<<" ";
}
cout<<endl;
}
tabulate();
cout<<"\n==========================================\n\n";
all(table,it){
cout<<it->first.first<<" "<<it->first.second<<" :";
all(it->second,jt){
cout<<*jt<<" ";
}
cout<<endl;
}
return 0;
}
set<string> first(string key)
{
if(flag_fs[key]==0){
for(unsigned int i=0;i<k[key].size();i++){
string y=k[key][i];
if(islower( y[0] ) ) f[key].insert(string(1,y[0]));
if(y[0]=='~') f[key].insert("~");
if(isupper(y[0])){
for(int j=0;j<y.length();j++){
set<string> m = first(string(1,y[j]));
set<string>::iterator it;int null_flag=0;
for(it=m.begin();it!=m.end();it++)
{
if(*it!="~")
f[key].insert(*it);
else
null_flag=1;
}
if(null_flag && islower(y[j+1]))
{
f[key].insert(string(1,y[j+1]));
break;
}
if(m.find("~") == m.end())
break;

}
}
}
flag_fs[key]=1;
return f[key];
}
else
return f[key];
}
set<string> follow ( string key){
map<string,vector<string> >::iterator it;
for(it=k.begin();it!=k.end();++it){
for(vector<string>::iterator i=(it->second).begin();i !=(it->second).end
();i++ ){
string body=*i;string head = it->first;
int index = body.find(key);
if(index == -1)
continue;
else if(index==(body.length()-1)){
if(string(1,body[index]) != head){
set<string> e = follow(head);
set<string>::iterator ie = e.begin();
for(ie;ie!=e.end();++ie){
w[key].insert(*ie);
}
}
}
else{
int null_flag =0;
for(int i=index+1;i<body.length();i++){
if(islower(body[i])){
w[key].insert(string(1,body[i]));
break;
}
if(isupper(body[i])){
set<string> m = first(string(1,body[i]));
set<string>::iterator dd = m.begin();
null_flag=0;
for(dd;dd!=m.end();++dd){
if(*dd !="~")
w[key].insert(*dd);
else
null_flag =1;
}
if(null_flag==0)
break;
if(null_flag==1 && (i+1)<( body.length()-1 ) ){
if( islower(body[i+1]) ){
w[key].insert(string(1,body[i+1]));

break;
}
}
if(null_flag==1 && (i+1)==body.length() ){
if(key == string(1,body[i]))
break;
else{
set<string> r = follow(head);
set<string>::iterator tt = r.begin();
for(tt;tt!=r.end();++tt)
w[key].insert(*tt);
}
}
}
}
}
}
}
return w[key];
}
void tabulate(){
// for all prodn find the first of the right hand side
//if null then
// else find first
// add to head symbol these prodn
all(k,it){
for(int i=0;i<it->second.size();i++){
string body = it->second[i]; string head = it->first;
if(str(body[0]) == "~" )
{
set<string> foll = follow(head);
all(foll,jt){
table[pair<string,string>(head,*jt)].insert(head);
table[pair<string,string>(head,*jt)].insert(body);
}
}
else{
for(int j=0;j<body.length();j++){
if(islower(body[j])){
//

cout<<head<<" "<<b

ody[j]<<" "<<body<<endl;
table[pair<string,string>(head,str(body[j]))].insert(hea
d);
table[pair<string,string>(head,str(body[j]))].insert(bod
y);
break;
}
if(isupper(body[j])){
bool flag = false;
set<string> fir = first(str(body[j]));
all(fir,kt){
if(*kt!="~"){
cout<<head<<" "<<body[j]<<" "<<body<<endl;
table[pair<string,string>(head,*kt)].insert(head
);

table[pair<string,string>(head,*kt)].insert(body
);
}
else flag=true;
}
if(flag==true && islower(body[j+1])){
table[pair<string,string>(head,str(body[j+1]))].insert(h
ead);
table[pair<string,string>(head,str(body[j+1]))].insert(b
ody);
break;
}
if(flag==false)
break;
}
}
}
}
}
}

Você também pode gostar