#include "semcheck.h" /***************************************************************** ** File Name : cycle_free_inherit.c ** ** ** ** There is no alternation cycle. ** ** and Repetition classes can not be inherited. ** *****************************************************************/ extern Vertex_Comma_list * terminals; extern Term_Comma_list * foreignclasses; int Cd_graph::cycle_free_inherit() { terminals = terminal_sets; foreignclasses = foreign_classes; Adjacency_Nlist *adjacencies_copy =(Adjacency_Nlist *)adjacencies->g_copy(); if ((adjacencies_copy->process_inherit_terms()==TRUE)&& (adjacencies_copy->cycle_free_inherit()==TRUE)) return SUCCESS; else return (ERROR_CYCLE_INH); } int Adjacency_Nlist::process_inherit_terms() { int return_val = TRUE; Adjacency_list_iterator next_Adjacency(*this); Adjacency_ each_Adjacency; while (each_Adjacency = next_Adjacency()) if (!each_Adjacency->process_inherit_terms(this)) return_val = FALSE; return return_val; } int Adjacency::process_inherit_terms(Adjacency_Nlist *adjs) { return ns->process_inherit_terms(adjs,source); } int Neighbors::process_inherit_terms(Adjacency_Nlist *adjs,Vertex *avertex) { return TRUE; } int Neighbors_wc::process_inherit_terms(Adjacency_Nlist *adjs,Vertex *avertex) { return construct_ns->process_inherit_terms(adjs,avertex); } int Any_vertex_List::process_inherit_terms(Adjacency_Nlist *adjs,Vertex *avertex) { int return_val = TRUE; Any_vertex_list_iterator next(*this); Any_vertex_ each; while (each = next()) if (!each->process_inherit_terms(adjs,avertex)) return_val = FALSE; return return_val; } int Any_vertex::process_inherit_terms(Adjacency_Nlist *adjs,Vertex *avertex) { return TRUE; } int Inherit_term::process_inherit_terms(Adjacency_Nlist *adjs,Vertex *avertex) { return inherited->process_inherit_terms(adjs,avertex); } int Term_Comma_list::process_inherit_terms(Adjacency_Nlist *adjs,Vertex *avertex) { int return_val = TRUE; Term_list_iterator next(*this); Term_ each; while (each = next()) if (!each->process_inherit_terms(adjs,avertex)) return_val = FALSE; return return_val; } int Term::process_inherit_terms(Adjacency_Nlist *adjs,Vertex *avertex) { Adjacency *adj = adjs->find_adjacency(this->get_vertex()); if (!adj) { if (terminals) { Vertex_list_iterator next_terminal(*terminals); Vertex_ each_terminal; while (each_terminal = next_terminal()) if (this->get_vertex()->g_equal(each_terminal)) break; if (each_terminal) { cerr << toolname << ": error: on line " << avertex->get_vertex_name()->get_line_number() << " class: '"; avertex->pp(cerr); cerr << "' cannot inherit from the terminal class '"; this->pp(cerr); cerr << "'\n" << endl; return FALSE; } else if (foreignclasses) { /* sem_out << "\nWarning: class "; avertex->pp(sem_out); sem_out << " inherits from the foreign class "; this->pp(sem_out); sem_out << endl; */ //temporary return TRUE; } else { cerr << toolname << ": error: on line " << this->get_vertex()->get_vertex_name()->get_line_number() << " class: '"; this->pp(cerr); cerr << "' is undefined.\n" << endl; return FALSE; } } else if (foreignclasses) { /* sem_out << "\nWarning: class "; avertex->pp(sem_out); sem_out << " inherits from the terminal class "; this->pp(sem_out); sem_out << endl; */ return TRUE; } else { cerr << toolname << ": error: on line " << this->get_vertex()->get_vertex_name()->get_line_number() << " class: '"; this->pp(cerr); cerr << "' is undefined.\n" << endl; return FALSE; } } Term *aterm = (Term *) new Normal(); aterm->set_vertex(avertex); return adj->add_alternative(aterm); } int Adjacency::add_alternative(Term* aterm) { int return_val = TRUE; if (!(ns = ns->change_to_alternation(this,aterm))) return_val = FALSE; else ns->add_alternative(aterm); return return_val; } Neighbors* Neighbors::change_to_alternation(Adjacency *adj,Term *aterm) { return NULL; } Neighbors* Repetit_n::change_to_alternation(Adjacency *adj,Term *aterm) { cerr << toolname << ": error: on line " << aterm->get_vertex()->get_vertex_name()->get_line_number() << " repetition class: '"; adj->get_source()->pp(cerr); cerr << "' can not be inherited by '"; aterm->pp(cerr); cerr << "'\n" << endl; return NULL; } Neighbors* Neighbors_wc::change_to_alternation(Adjacency *adj,Term *aterm) { return NULL; } Neighbors* Alternat_ns::change_to_alternation(Adjacency *adj,Term *aterm) { return this; } Neighbors* Construct_ns::change_to_alternation(Adjacency *adj,Term *aterm) { Alternat_ns *altns = new Alternat_ns(); altns->set_construct_ns(this->get_construct_ns()); altns->set_alternat_ns(new Term_Bar_list()); return altns; } void Neighbors::add_alternative(Term *aterm) { } void Alternat_ns::add_alternative(Term *aterm) { this->get_alternat_ns()->append(aterm); } int Adjacency_Nlist::cycle_free_inherit() { int result = TRUE; Adjacency *adjacency; /*DFS traverse by selecting alt. edges.This is top level.*/ while (adjacency = this->find_untreated()) if (adjacency->cycle_free_inherit(this,(Vertex *)NULL)==FALSE) result = FALSE; return result; } Adjacency *Adjacency_Nlist::find_untreated() { Adjacency_list_iterator next_Adjacency(*this); Adjacency_ each_Adjacency; /* If an Adjacency has been traversed, treated would be not NULL */ while (each_Adjacency=next_Adjacency()) if (!each_Adjacency->get_treated()) return each_Adjacency; return (Adjacency *)NULL; } int Adjacency::cycle_free_inherit(Adjacency_Nlist *adj_Nlist,Vertex *caller) { static int count = 1; int result; if (treated) return TRUE; // this vertex has been treated. if ((!treated)&&imm_ancester)// this vertex is being treated. { cerr << toolname << ": error: on line " << source->get_vertex_name()->get_line_number() << " find inheritance cycle " << count++ << " :\n\n" << endl; cerr << "\tfrom "; this->cycle_free_inherit_print(adj_Nlist,caller,source); caller->pp(cerr); cerr << endl; return (FALSE); } /* in order to print a cycle. */ if (caller) imm_ancester = caller; result = ns->cycle_free_inherit(adj_Nlist,source); treated = new DemNumber(); return (result); } int Neighbors::cycle_free_inherit(Adjacency_Nlist *adj_Nlist,Vertex *caller) { return (TRUE); } int Alternat_ns::cycle_free_inherit(Adjacency_Nlist *adj_Nlist,Vertex *caller) { return alternat_ns->cycle_free_inherit(adj_Nlist,caller); } int Term_Bar_list::cycle_free_inherit(Adjacency_Nlist *adj_Nlist,Vertex *caller) { int result = TRUE; Term_list_iterator next_Term(*this); Term_ each_Term; while (each_Term=next_Term()) if (each_Term->cycle_free_inherit(adj_Nlist,caller)==FALSE) result = FALSE; return (result); } int Term::cycle_free_inherit(Adjacency_Nlist *adj_Nlist,Vertex *caller) { Vertex *a_vertex = this->get_vertex(); Adjacency *son = adj_Nlist->find_adjacency(a_vertex); if (son) return son->cycle_free_inherit(adj_Nlist,caller); else return TRUE; // Terminal class } Adjacency *Adjacency_Nlist::find_adjacency(Vertex *vertex) { Adjacency_list_iterator next_Adjacency(*this); Adjacency_ each_Adjacency; while (each_Adjacency=next_Adjacency()) if (vertex->g_equal(each_Adjacency->get_source())) return each_Adjacency; return ((Adjacency *)NULL); } void Adjacency::cycle_free_inherit_print(Adjacency_Nlist *adj_Nlist,Vertex *from,Vertex *stoppoint) { Adjacency *adjacency = adj_Nlist-> find_adjacency(from); Vertex *from_from = adjacency->get_imm_ancester(); if (stoppoint->g_equal(from)) { stoppoint->pp(cerr); cerr << endl; cerr << "\tto "; } else { from->pp(cerr); cerr << endl; cerr << "\tto "; adjacency-> cycle_free_inherit_print(adj_Nlist,from_from,stoppoint); } }