#include #include "grammar.hh" //bool (*constraint[MAXCONSTRS])(int head, int dep); //==================================================================================================== //inline !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! bool chk_type(const char* s) { return Role::index(s)>0; } // PRZENIEŚĆ DO Role //---------------------------------------------------------------------------------------------------- //inline !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! bool chk_long(const char* s) { return LongRel::index(s)>0; } // jw //---------------------------------------------------------------------------------------------------- //inline !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! bool chk_cat(const char* s) { return Cat::index(s)>0; } //jw //---------------------------------------------------------------------------------------------------- //inline !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! bool chk_flag(const char* s) { return Flag::index(s)>0; } //jw //==================================================================================================== void grammar_error(int lineno, string s="Grammar error.") { fprintf(stderr,"%8d: %s Line ignored.\n",lineno,s.c_str()); } //==================================================================================================== void Grammar::add_category(const char* s) { Cat::add(s); if(connect.size() <= Cat::count()) { connect.resize(Cat::count()+RESIZE_DELTA); for(int i=0; i boubble_list, Boubble* bp) const { for(list::const_iterator bi = boubble_list.begin(); bi != boubble_list.end(); bi++ ) if(**bi == *bp) return true; return false; } //---------------------------------------------------------------------------------------------------- void Grammar::add_triggers(Cat src, Cat dest, LongRel l) { for(list::const_iterator b=boubbles.begin(); b!=boubbles.end(); b++) if((*b)->rel() == l) { list& boubble_list = ((*b)->dir()==UP) ? uptrigger[src][(*b)->next()] : dntrigger[src][(*b)->next()] ; if(!contains_boubble(boubble_list,*b)) boubble_list.push_back(*b); } } //==================================================================================================== void Grammar::set_lt(Role s, Role t) { lt[s].set(t); gt[t].set(s); if(s==0||(int)t==0) return; else { for(int i=0; i::const_iterator b=boubbles.begin(); b!=boubbles.end; b++) // if(b->dir()==UP && ) } //==================================================================================================== list Grammar::trigger_boubbles(Cat c, Role r, Dir d) { list boubble_list = (d == UP) ? uptrigger[c][r] : dntrigger[c][r]; list ret; for(list::iterator b = boubble_list.begin(); b != boubble_list.end(); ++b) ret.push_back((*b)->step(r,d)); return ret; } //==================================================================================================== Flag parse_flags(const char* s, const char* v) { char buf[16][17]; int n=sscanf(s,"%[A-Z]%[+-]%[A-Z]%[+-]%[A-Z]%[+-]%[A-Z]%[+-]%[A-Z]%[+-]%[A-Z]%[+-]%[A-Z]%[+-]%[A-Z]%[+-]", buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7],buf[8],buf[9],buf[10],buf[11],buf[12],buf[13],buf[14],buf[15],buf[16]); for(int i=2; i<=n; i+=2) if(strcmp(buf[i-1],v)==0) return Flag(buf[i-2]); return Flag("NULL"); } PropSet parse_props(const char* s) { PropSet ret; char buf[8][17]; int n=sscanf(s,"&%[A-Z]&%[A-Z]&%[A-Z]&%[A-Z]&%[A-Z]&%[A-Z]&%[A-Z]&%[A-Z]",buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7]); for(int i=1; i<=n; i++) ret.set(Prop(buf[i-1])); return ret; } bool Grammar::read(FILE* f) { //>>> TU? Prop::add("INIT"); Prop::add("FIN"); //<<< TU? int lineno=0; char line[MAXLINE]; // line has the structure: key [arg1 [arg2 [arg3]]] char key[MAXLINE]; char arg1[MAXLINE]; char arg2[MAXLINE]; char arg3[MAXLINE]; char arg4[MAXLINE]; while(fgets(line,MAXLINE,f)) { lineno++; int fields=sscanf(line,"%s %s %s %s %s",key,arg1,arg2,arg3,arg4); if(fields<1 || key[0]=='#') continue; // skip empty lines and comments if(fields>1 && arg1[0] == '#') fields=1; if(fields>2 && arg2[0] == '#') fields=2; if(fields>3 && arg3[0] == '#') fields=3; if(fields>4 && arg4[0] == '#') fields=4; if (strcmp(key,"CAT")==0 && fields==2) { add_category(arg1); } else if(strcmp(key,"ROLE")==0 && fields==2) { add_type(arg1); } else if(strcmp(key,"SGL")==0 && fields==2) { if(chk_type(arg1)) set_sgl(arg1); else grammar_error(lineno); } else if(strcmp(key,"LEFT")==0 && fields==2) { if(chk_type(arg1)) set_left(arg1); else grammar_error(lineno); } else if(strcmp(key,"RIGHT")==0 && fields==2) { if(chk_type(arg1)) set_right(arg1); else grammar_error(lineno); } else if(strcmp(key,"INITR")==0 && fields==2) { if(chk_type(arg1)) set_init(arg1); else grammar_error(lineno); } else if(strcmp(key,"FINR")==0 && fields==2) { if(chk_type(arg1)) set_fin(arg1); else grammar_error(lineno); } else if(strcmp(key,"INITF")==0 && fields==2) { if(chk_flag(arg1)) set_initf(arg1); else grammar_error(lineno); } else if(strcmp(key,"FINF")==0 && fields==2) { if(chk_flag(arg1)) set_finf(arg1); else grammar_error(lineno); } else if(strcmp(key,"REQ")==0 && fields==3) { if( chk_cat(arg1) && chk_type(arg2) ) set_obl(arg1,arg2); else grammar_error(lineno); } else if(strcmp(key,"CONSTRE")==0 && fields==3) { if( chk_type(arg1) && chk_type(arg2) ) set_exclude(arg1,arg2); else grammar_error(lineno); } else if(strcmp(key,"CONSTRI")==0 && fields==3) { if( chk_type(arg1) && chk_type(arg2) ) set_include(arg1,arg2); else grammar_error(lineno); } else if(strcmp(key,"LONG")==0 && fields ==3) { add_long(arg1,arg2); } else if(strcmp(key,"LINK")==0 && fields==4) { char cat1[MAXLINE],flags1[MAXLINE],cat2[MAXLINE],flags2[MAXLINE],type[MAXLINE],props[MAXLINE]; if(sscanf(arg1,"%[^;];%s",cat1,flags1)==1) *flags1='\0'; if(sscanf(arg2,"%[^;];%s",cat2,flags2)==1) *flags2='\0'; if(sscanf(arg3,"%[^&]%s",type,props)==1) *props='\0'; // printf("line=%s\n\tcat1=%s flags1=%s cat2=%s flags2=%s type=%s props=%s\n",line,cat1,flags1,cat2,flags2,type,props); if( chk_cat(cat1) && chk_cat(cat2) && chk_type(type) ) set_connect(cat1,parse_flags(flags1,"+"),parse_flags(flags1,"-"),cat2,parse_flags(flags2,"+"),parse_flags(flags2,"-"),type,parse_props(props)); else if( chk_cat(cat1) && chk_cat(cat2) && chk_long(type) ) { set_longrel(cat1,cat2,type); add_triggers(cat1,cat2,type); } else grammar_error(lineno); } // else if(strcmp(key,"LINK")==0 && fields==5) // { // if( chk_cat(arg1) && chk_cat(arg2) && chk_type(arg4) ) // set_connect(arg1,arg2,arg3,arg4); // else // grammar_error(lineno); // } // FLAG DECLARATION else if(strcmp(key,"FLAG")==0 && fields==2) { add_flag(arg1); } else if(strcmp(key,"SET")==0 && fields==3) { if( chk_cat(arg1) && chk_flag(arg2) ) set_set(arg1,arg2); else grammar_error(lineno); } else if(strcmp(key,"PASS")==0 && fields==3) { if( chk_type(arg1) && chk_flag(arg2) ) set_pass(arg1,arg2); else grammar_error(lineno); } else fprintf(stderr,"Statement not recognized in line %d. Ignored.\n", lineno); } // compute_gt(); return true; } void Grammar::write(ostream& os) { for(Cat i=1; ihflagplus||l->hflagminus) { os << ";"; if(l->hflagplus) os << (l->hflagplus).str() << "+"; if(l->hflagminus) os << (l->hflagminus).str() << "-"; } os << "\t" << d.str(); if(l->dflagplus||l->dflagminus) { os << ";"; if(l->dflagplus) os << (l->dflagplus).str() << "+"; if(l->dflagminus) os << (l->dflagminus).str() << "-"; } os << "\t" << (l->role).str(); for(Prop p=0; pprops[p]) os << "&" << p.str(); os << endl; } for(LongRel i=1; i::const_iterator b = boubbles.begin(); b != boubbles.end(); b++) os << "BOUBBLE\t" << **b << endl; for(Cat c=1; c::const_iterator b=uptrigger[c][r].begin(); b!=uptrigger[c][r].end(); b++) os << "TRIGGER-UP\t" << c.str() << "\t" << r.str() << "\t" << (*b)->rel().str() << endl; for(Cat c=1; c::const_iterator b=dntrigger[c][r].begin(); b!=dntrigger[c][r].end(); b++) os << "TRIGGER-DN\t" << c.str() << "\t" << r.str() << "\t" << (*b)->rel().str() << endl; for(Flag i=1; i::const_iterator b=uptrigger[c][r].begin(); b!=uptrigger[c][r].end(); b++) fprintf(f,"#TRIGGER\t%s\t%s\t%s\n",c.str(),r.str(),(*b)->rel().str()); for(Cat c=1; c::const_iterator b=dntrigger[c][r].begin(); b!=dntrigger[c][r].end(); b++) fprintf(f,"#TRIGGER\t%s\t%s\t%s\n",c.str(),r.str(),(*b)->rel().str()); for(Flag i=1; i