#ifndef TFTiH #define TFTiH //--------------------------------------------------------------------------- #include #include #include //#include #include "tft.h" //--------------------------------------------------------------------------- using namespace std; template class TFTi : public TFT > { public: TFTi() : TFT >() {}; TFTi(const char* filename) : TFT >() { load(filename); }; void read(const char* filename); void read(istream& is=cin); void write(const char* filename); void write(ostream& os=cout); void load(const char* filename); void load(FILE* f=stdin); void save(const char* filename); void save(FILE* f=stdout); void clear(); using TFT >::ttn; using TFT >::states; using TFT >::transitions; using TFT >::itype; using TFT >::ftTYPELEN; using TFT >::otype; using TFT >::tt; using TFT >::copy_default; using TFT >::print_mode; // friend istream& operator>>(istream&, TFTi&); // friend ostream& operator<<(ostream&, const TFTi&); }; //--------------------------------------------------------------------------- template void TFTi::read(const char* filename) { ifstream is(filename); if(!is) { fprintf(stderr,"Failed to open input file."); exit(1); } read(is); } template void TFTi::read(istream& is) { long *si; // state-index relation long ci=0; // current index char ch; // character read; int empty=0; // no of states with 0 trans? char intype[FT::ftTYPELEN]; char outtype[FT::ftTYPELEN]; clear(); is >> states >> transitions >> intype >> outtype; // if(strcmp(intype,itype)!=0 || // strcmp(outtype,otype)!=0 && strcmp(outtype,"void")!=0) // { is.clear(ios::badbit); goto end; }; while(is.peek()==' ' || is.peek()=='\t') is.get(ch); while(is.peek()!='\n') { char s[20]; is >> s; if(strcmp(s,"COPY")==0 && strcmp(intype,outtype)==0) copy_default=true; else if(strcmp(s,"NOCOPY")==0) copy_default=false; else if(strcmp(s,"II")==0) print_mode=FT::II; else if(strcmp(s,"OO")==0) print_mode=FT::OO; else if(strcmp(s,"IOIO")==0) print_mode=FT::IOIO; else if(strcmp(s,"OIOI")==0) print_mode=FT::OIOI; else if(strcmp(s,"IIOO")==0) print_mode=FT::IIOO; else if(strcmp(s,"OIOI")==0) print_mode=FT::OIOI; while(is.peek()==' ' || is.peek()=='\t') is.get(ch); } ttn=transitions+2; // 1 state without trans., 1 additional si=new long[states]; tt=new TTrans_i[ttn]; for(long cs=0;cs> cscheck; if(cs!=cscheck) goto end; while(is.peek()==' ' || is.peek()=='\t') is.get(ch); is.get(ch); if(!is) goto end; switch(ch) { case '-': tt[ci].final(false); break; case '+': tt[ci].final(true); break; default: goto end; } tc=0, tt[ci].continued(false); while(is.peek()==' ' || is.peek()=='\t') is.get(ch); while(is && is.peek()!='\n') { switch(is.peek()) { case '~': tt[ci].epsi(true); tt[ci].defi(true); is.get(ch); break; case '@': tt[ci].epsi(false); tt[ci].defi(true); is.get(ch); break; default : tt[ci].geti(is); } if(!is) goto end; if(is.peek()=='/') { is.get(ch); switch(is.peek()) { case '~': tt[ci].epso(true); tt[ci].defo(true); is.get(ch); break; case '@': tt[ci].epso(false); tt[ci].defo(true); is.get(ch); break; default : tt[ci].geto(is); } } else { tt[ci].defo(true); if(copy_default) tt[ci].epso(false); else tt[ci].epso(true); } if(!is) goto end; unsigned long transition; is >> transition; tt[ci].next(transition); tt[ci].continued(false); tt[ci].empty(false); if(tc>0) tt[ci-1].continued(true); tc++,ci++; } if(tc==0) { if(++empty>2) { fprintf(stderr, "Nondeterministic automaton."); exit(1); } tt[ci].empty(true); ci++; } is.get(ch); if(ch!='\n') { is.clear(ios::badbit); goto end; } } ttn=transitions+empty; if(ttn!=ci) { is.clear(ios::badbit); goto end; }; for(long i=0;i void TFTi::write(const char* filename) { ofstream os(filename); if(!os) err("Failed to open output file."); write(os); } template void TFTi::write(ostream& os) { os << states << ' ' << transitions << ' '; // os << itype << ' ' << otype << ' '; os << "char void"; // os << (copy_default ? "COPY" : "NOCOPY") << ' '; // switch(print_mode) // { // case FT::II : os << "II"; break; // case FT::OO : os << "OO"; break; // case FT::IOIO: os << "IOIO"; break; // case FT::OIOI: os << "OIOI"; break; // case FT::IIOO: os << "IIOO"; break; // case FT::OOII: os << "OOII"; // } os << '\n'; long* si=new long[ttn]; long cs=0; for(long i=0;i void TFTi::load(const char* filename) { FILE* f; if(*filename) f=fopen(filename,"rb"); else f=stdin; if(!f) { fprintf(stderr, "Cannot open automaton file."); return; } load(f); } template void TFTi::load(FILE* f) { clear(); if(fread(&ttn,sizeof(ttn),1,f)!=1) { fprintf(stderr, "Binary input error."); return;} if(fread(&states,sizeof(states),1,f)!=1) { fprintf(stderr, "Binary input error."); return;} if(fread(&transitions,sizeof(transitions),1,f)!=1) { fprintf(stderr, "Binary input error."); return;} if(fread(itype,sizeof(char),ftTYPELEN,f)!=ftTYPELEN) { fprintf(stderr, "Binary input error."); return;} if(fread(otype,sizeof(char),ftTYPELEN,f)!=ftTYPELEN) { fprintf(stderr, "Binary input error."); return;} if(fread(©_default,sizeof(copy_default),1,f)!=1) { fprintf(stderr, "Binary input error."); return;} if(fread(&print_mode,sizeof(print_mode),1,f)!=1) { fprintf(stderr, "Binary input error."); return;} if((tt=new TTrans_i[ttn])==NULL) { fprintf(stderr, "Cannot allocate memory for tt."); return;} if(fread(tt,sizeof(TTrans_i),ttn,f)!=ttn) { fprintf(stderr, "Binary input error."); return; } fclose(f); } //--------------------------------------------------------------------------- template void TFTi::save(const char* filename) { FILE* f; if(*filename) f=fopen(filename,"wb"); else f=stdout; if(!f) err("Cannot open file."); save(f); } template void TFTi::save(FILE* f) { if(fwrite(&ttn,sizeof(ttn),1,f)!=1) { fprintf(stderr,"Binary output error."); exit(1); } if(fwrite(&states,sizeof(states),1,f)!=1) { fprintf(stderr,"Binary output error."); exit(1); } if(fwrite(&transitions,sizeof(transitions),1,f)!=1) { fprintf(stderr,"Binary output error."); exit(1); } if(fwrite(itype,sizeof(char),ftTYPELEN,f)!=ftTYPELEN) { fprintf(stderr,"Binary output error."); exit(1); } if(fwrite(otype,sizeof(char),ftTYPELEN,f)!=ftTYPELEN) { fprintf(stderr,"Binary output error."); exit(1); } if(fwrite(©_default,sizeof(copy_default),1,f)!=1) { fprintf(stderr,"Binary output error."); exit(1); } if(fwrite(&print_mode,sizeof(print_mode),1,f)!=1) { fprintf(stderr,"Binary output error."); exit(1); } if(fwrite(tt,sizeof(TTrans_i),ttn,f)!=ttn) { fprintf(stderr,"Binary output error."); exit(1); } fclose(f); } //--------------------------------------------------------------------------- template void TFTi::clear() { if(tt) delete[] tt; ttn=0; } //--------------------------------------------------------------------------- /* template istream& operator>>(istream& is, TFTi& ft) { long *si; // state-index relation long ci=0; // current index char ch; // character read; int empty=0; // no of states with 0 trans? char intype[FT::ftTYPELEN]; char outtype[FT::ftTYPELEN]; ft.clear(); is >> ft.states >> ft.transitions >> intype >> outtype; if(strcmp(intype,ft.itype)!=0 || strcmp(outtype,ft.otype)!=0 && strcmp(outtype,"void")!=0) { is.clear(ios::badbit); return is; }; while(is.peek()==' ' || is.peek()=='\t') is.get(ch); while(is.peek()!='\n') { char s[20]; is >> s; if(strcmp(s,"COPY")==0 && strcmp(intype,outtype)==0) ft.copy_default=true; else if(strcmp(s,"NOCOPY")==0) ft.copy_default=false; else if(strcmp(s,"II")==0) ft.print_mode=FT::II; else if(strcmp(s,"OO")==0) ft.print_mode=FT::OO; else if(strcmp(s,"IOIO")==0) ft.print_mode=FT::IOIO; else if(strcmp(s,"OIOI")==0) ft.print_mode=FT::OIOI; else if(strcmp(s,"IIOO")==0) ft.print_mode=FT::IIOO; else if(strcmp(s,"OIOI")==0) ft.print_mode=FT::OIOI; while(is.peek()==' ' || is.peek()=='\t') is.get(ch); } ft.ttn=ft.transitions+2; // 1 state without trans., 1 additional si=new long[ft.states]; ft.tt=new TTrans_i[ft.ttn]; for(long cs=0;cs> ch; while(ch!='+' && ch!='-'); switch(ch) { case '-': ft.tt[ci].final(false); break; case '+': ft.tt[ci].final(true); break; default: return is; } tc=0, ft.tt[ci].continued(false); while((is.get(ch),ch==' ')) { if(!is) return is; switch(is.peek()) { case '~': ft.tt[ci].epsi(true); ft.tt[ci].defi(true); is.get(ch); break; case '@': ft.tt[ci].epsi(false); ft.tt[ci].defi(true); is.get(ch); break; default : ft.tt[ci].geti(is); } if(!is) return is; if(is.peek()=='/') { is.get(ch); switch(is.peek()) { case '~': ft.tt[ci].epso(true); ft.tt[ci].defo(true); is.get(ch); break; case '@': ft.tt[ci].epso(false); ft.tt[ci].defo(true); is.get(ch); break; default : ft.tt[ci].geto(is); } } else { ft.tt[ci].defo(true); if(ft.copy_default) ft.tt[ci].epso(false); else ft.tt[ci].epso(true); } if(!is) return is; unsigned long transition; is >> transition; ft.tt[ci].next(transition); ft.tt[ci].continued(false); ft.tt[ci].empty(false); if(tc>0) ft.tt[ci-1].continued(true); tc++,ci++; } if(tc==0) { if(++empty>2) err("Nondeterministic automaton."); ft.tt[ci].empty(true); ci++; } if(ch!='\n') { is.clear(ios::badbit); return is; } } ft.ttn=ft.transitions+empty; if(ft.ttn!=ci) { is.clear(ios::badbit); return is; }; for(long i=0;i ostream& operator<<(ostream& os, const TFTi& ft) { os << ft.states << ' ' << ft.transitions << ' ' << ft.itype << ' ' << ft.otype << ' '; os << (ft.copy_default ? "COPY" : "NOCOPY") << ' '; switch(ft.print_mode) { case FT::II : os << "II"; break; case FT::OO : os << "OO"; break; case FT::IOIO: os << "IOIO"; break; case FT::OIOI: os << "OIOI"; break; case FT::IIOO: os << "IIOO"; break; case FT::OOII: os << "OOII"; } os << ' ' << '\n'; long* si=new long[ft.ttn]; long cs=0; for(long i=0;i class TFTiv : public TFTi { public: TFTiv() : TFTi() {}; TFTiv(const char* filename) : TFTi(filename) {}; }; //--------------------------------------------------------------------------- template class TFTir : public TFTi { public: TFTir() : TFTi() {}; }; //--------------------------------------------------------------------------- #endif