#include "semcheck.h" /* File Name : FOLLOWSET.c */ Cd_graph *Cd_graph::FOLLOWSET() { followsetEqGraph = new Cd_graph(); followsetEqGraph->rset_adjacencies(new Adjacency_Nlist()); adjacencies->FOLLOWSET(); followsetEqGraph->SolveEQs(this); return (this); } void Adjacency_Nlist::FOLLOWSET() { TEndOfFile *ieof = new TEndOfFile(); Ll1SetElement *eofll1 = new Ll1SetElement(NULL,NULL,NULL,ieof); Adjacency_list_iterator next(*this); Adjacency_ each,first; first = each = next(); while (each) { this->FOLLOWSET(each); each = next(); } first->get_followset()->insert(eofll1); } void Adjacency_Nlist::FOLLOWSET(Adjacency* adj) { Ll1SetElement_Comma_list *result = new Ll1SetElement_Comma_list(); Adjacency_list_iterator next(*this); Adjacency_ each; while (each = next()) each->FOLLOWSET(this,adj->get_source(),result); adj->rset_followset(result); } void Adjacency::FOLLOWSET(Adjacency_Nlist*adj_Nlist,Vertex *owner,Ll1SetElement_Comma_list* result) { ns->FOLLOWSET(adj_Nlist,owner,result,source); } void Neighbors::FOLLOWSET(Adjacency_Nlist*adj_Nlist,Vertex *owner,Ll1SetElement_Comma_list* result,Vertex *borrower) { } void Alternat_ns::FOLLOWSET(Adjacency_Nlist*adj_Nlist,Vertex *owner,Ll1SetElement_Comma_list* result,Vertex *borrower) { static DemNumber* markempty = new DemNumber(0); static DemNumber* marknonempty = new DemNumber(1); static TEpsilon*iepsi = new TEpsilon(); static Ll1SetElement*epsill1=new Ll1SetElement(NULL, iepsi, NULL, NULL); this->get_construct_ns()->FOLLOWSET(adj_Nlist,owner,result,borrower); Term_list_iterator next(*this->get_alternat_ns()); Term_ each; while (each = next()) if (each->get_vertex()->g_equal(owner)) break; if (each!=NULL) { Ll1SetElement_Comma_list* forcommon; forcommon = this->get_construct_ns()->FIRSTSET(adj_Nlist); Ll1SetElement_list_iterator next_common (*forcommon->remove(epsill1)); Ll1SetElement_ each_common; while (each_common = next_common()) result->insert(each_common); if (this->get_emptycommon()==NULL) if (forcommon->contain(epsill1)) this->set_emptycommon(markempty); else this->set_emptycommon(marknonempty); if (this->get_emptycommon()->g_equal(markempty)) followsetEqGraph->AddOneEdge(owner,borrower); } } void Repetit_n::FOLLOWSET(Adjacency_Nlist*adj_Nlist,Vertex *owner,Ll1SetElement_Comma_list* result,Vertex *borrower) { sandwiched->FOLLOWSET(adj_Nlist,owner,result,borrower); } void Kernel_Sandwich::FOLLOWSET(Adjacency_Nlist*adj_Nlist,Vertex *owner,Ll1SetElement_Comma_list* result,Vertex *borrower) { inner->FOLLOWSET(adj_Nlist,owner,result,borrower,second); } void Kernel::FOLLOWSET(Adjacency_Nlist*adj_Nlist,Vertex *owner,Ll1SetElement_Comma_list* result,Vertex *borrower,Syntax_vertex_List *second) { repeated->FOLLOWSET(adj_Nlist,owner,result,borrower,second,nonempty); } void Term_Sandwich::FOLLOWSET(Adjacency_Nlist*adj_Nlist,Vertex *owner,Ll1SetElement_Comma_list* result,Vertex *borrower,Syntax_vertex_List *scnd,Term* nonempty) { static TEpsilon *iepsi = new TEpsilon(); static Ll1SetElement *epsill1 =new Ll1SetElement(NULL,iepsi,NULL,NULL); Ll1SetElement_Comma_list*forsecond= second->FIRSTSET()->remove(epsill1); Ll1SetElement_Comma_list*forfirst= first->FIRSTSET(); Ll1SetElement_Comma_list*forscnd= scnd->FIRSTSET(); if (!owner->g_equal(inner->get_vertex())) return; Ll1SetElement_list_iterator next_second (*forsecond); Ll1SetElement_ each_second; while (each_second = next_second()) result->insert(each_second); if (nonempty) { if (forscnd->contain(epsill1)) followsetEqGraph->AddOneEdge(owner,borrower); else { Ll1SetElement_list_iterator next_scnd(*forscnd); Ll1SetElement_ each_scnd; while (each_scnd = next_scnd()) result->insert(each_scnd); } if (forfirst->contain(epsill1)) { Ll1SetElement_list_iterator next_first (*adj_Nlist->FIRSTSET(inner->get_vertex())->remove(epsill1)); Ll1SetElement_ each_first; while (each_first = next_first()) result->insert(each_first); } else result->insert((Ll1SetElement_)forfirst->car()); } else if (forsecond->list_length()==0) { Ll1SetElement_list_iterator next_scnd (*forscnd); Ll1SetElement_ each_scnd; while (each_scnd = next_scnd()) if (!epsill1->g_equal(each_scnd)) result->insert(each_scnd); if (forscnd->contain(epsill1)) followsetEqGraph->AddOneEdge(owner,borrower); if (forfirst->contain(epsill1)) { Ll1SetElement_list_iterator next_first2 (*adj_Nlist->FIRSTSET(inner->get_vertex())->remove(epsill1)); Ll1SetElement_ each_first2; while (each_first2 = next_first2()) result->insert(each_first2); } else result->insert((Ll1SetElement_)first->FIRSTSET()->car()); } else result->insert((Ll1SetElement_)second->FIRSTSET()->car()); } void Construct_ns::FOLLOWSET(Adjacency_Nlist*adj_Nlist,Vertex *owner,Ll1SetElement_Comma_list* result,Vertex *borrower) { this->get_construct_ns()->FOLLOWSET(adj_Nlist,owner,result,borrower); } void Any_vertex_List::FOLLOWSET(Adjacency_Nlist*adj_Nlist,Vertex *owner,Ll1SetElement_Comma_list* result,Vertex *borrower) { static TEpsilon*iepsi = new TEpsilon(); static Ll1SetElement*epsill1=new Ll1SetElement(NULL, iepsi, NULL, NULL); Ll1SetElement_Comma_list *firstset_for_second; Ll1SetElement_Comma_list *firstsetfortail; Any_vertex_List *tailofit; int needaddtoFCG = 0; Any_vertex_list_iterator nextpart(*this); Any_vertex_ part; while ((part=nextpart())&&(!owner->g_equal(part->LL1_CLASS()))) continue; while (part) { firstset_for_second = part->get_firstset_for_second(); if (firstset_for_second==NULL) { tailofit = part->tail(this); firstsetfortail = tailofit->FIRSTSET(adj_Nlist); if (firstsetfortail->contain(epsill1)) needaddtoFCG = 1; Ll1SetElement_list_iterator next_e(*firstsetfortail->remove(epsill1)); Ll1SetElement_ each_e; while (each_e = next_e()) result->insert(each_e); } else result->append((Ll1SetElement_)firstset_for_second->car()); while ((part=nextpart())&&(!owner->g_equal(part->LL1_CLASS()))) continue; } if (needaddtoFCG) followsetEqGraph->AddOneEdge(owner,borrower); } Ll1SetElement_Comma_list* Adjacency_Nlist::FIRSTSET(Vertex* alt) { Adjacency_list_iterator next_arg(*this); Adjacency_ each_arg; while (each_arg = next_arg()) if (alt->g_equal(each_arg->get_source())) return each_arg->get_firstset(); cerr << toolname << ": error: on line " << alt->get_vertex_name()->get_line_number() << " undefined class: '"; alt->pp(cerr); cerr << "'\n" << endl; exit(-1); return NULL; } Ll1SetElement_Comma_list* Adjacency_Nlist::FOLLOWSET(Vertex * alt) { Adjacency_list_iterator next_arg(*this); Adjacency_ each_arg; while (each_arg = next_arg()) if (each_arg->get_source()->g_equal(alt)) return each_arg->get_followset(); cerr << toolname << ": error: on line " << alt->get_vertex_name()->get_line_number() << " undefined class: '"; alt->pp(cerr); cerr << "'\n" << endl; exit(-1); return NULL; } Ll1SetElement_Comma_list * Ll1SetElement_Comma_list::insert(Ll1SetElement *newmember) { if (!newmember) return this; Ll1SetElement_list_iterator next_one(*this); Ll1SetElement_ each_one; while (each_one = next_one()) { if (each_one->g_equal(newmember)) return this; } this->append((Ll1SetElement *)newmember->g_copy()); return this; } Ll1SetElement_Comma_list *Ll1SetElement_Comma_list::remove(Ll1SetElement *qelt) { if (!qelt) return (Ll1SetElement_Comma_list *)this->g_copy(); Ll1SetElement_list_iterator nextelt(*this); Ll1SetElement_ elt; Ll1SetElement_Comma_list *tmp = new Ll1SetElement_Comma_list(); if (this->number_of_parts()==0) return tmp; while (elt = nextelt()) if (!elt->g_equal(qelt)) tmp->append(elt); return tmp; } Ll1SetElement_Comma_list *Ll1SetElement_Comma_list::join(Ll1SetElement_Comma_list *newlist) { if (!newlist) return (Ll1SetElement_Comma_list *)this->g_copy(); Ll1SetElement_list_iterator nextnewelt1(*newlist); Ll1SetElement_ newelt1; Ll1SetElement_list_iterator nextnewelt2(*this); Ll1SetElement_ newelt2; Ll1SetElement_Comma_list *result = new Ll1SetElement_Comma_list(); while (newelt1 = nextnewelt1()) { Ll1SetElement_list_iterator nextnewelt3(*result); Ll1SetElement_ newelt3; while (newelt3 = nextnewelt3()) if (newelt1->g_equal(newelt3)) break; if (!newelt3) result->insert(newelt1); } while (newelt2 = nextnewelt2()) { Ll1SetElement_list_iterator nextnewelt4(*result); Ll1SetElement_ newelt4; while (newelt4 = nextnewelt4()) if (newelt2->g_equal(newelt4)) break; if (!newelt4) result->insert(newelt2); } return result; } Vertex *Opt_labeled_term::LL1_CLASS() { return this->get_vertex()->LL1_CLASS(); } Vertex *Term::LL1_CLASS() { return this->get_vertex(); } Vertex *Opt_labeled_term_Sandwich::LL1_CLASS() { return inner->LL1_CLASS(); } Vertex *Term_Sandwich::LL1_CLASS() { return inner->LL1_CLASS(); } Vertex *Optional_term::LL1_CLASS() { return opt->LL1_CLASS(); } Vertex *Any_vertex::LL1_CLASS() { return NULL; } int Adjacency::LL1_SUPERCLASS(Adjacency_Nlist *adj_Nlist,Vertex *subclass) { return ns->LL1_SUPERCLASS(adj_Nlist,subclass); } int Neighbors::LL1_SUPERCLASS(Adjacency_Nlist *adj_Nlist,Vertex *subclass) { return 0; } int Alternat_ns::LL1_SUPERCLASS(Adjacency_Nlist *adj_Nlist,Vertex *subclass) { return alternat_ns->LL1_SUPERCLASS(adj_Nlist,subclass); } int Term_Bar_list::LL1_SUPERCLASS(Adjacency_Nlist *adj_Nlist,Vertex *qvertex) { Adjacency *idrule; Term_list_iterator nextalt(*this); Term_ alt; while (alt = nextalt()) if (alt->get_vertex()->g_equal(qvertex)) return 1; else if (idrule = adj_Nlist->LL1_FIND_RULE(alt->get_vertex())) { if (idrule->LL1_SUPERCLASS(adj_Nlist,qvertex)) return 1; } else { cerr << toolname << ": error: on line " << alt->get_vertex()-> get_vertex_name()->get_line_number() << " undefined class: '"; alt->pp(cerr); cerr << "'\n" << endl; exit(-1); } return 0; }