source: src/lib/tfti.h @ 5f4d9c3

Last change on this file since 5f4d9c3 was 5f4d9c3, checked in by Maciej Prill <mprill@…>, 12 years ago

Rewritten the build system, added lem UTF-8 version.

  • Property mode set to 100644
File size: 15.6 KB
Line 
1#ifndef TFTiH
2#define TFTiH
3//---------------------------------------------------------------------------
4#include <fstream>
5#include <cmath>
6#include <iomanip>
7//#include <typeinfo.h>
8
9#include "tft.h"
10//---------------------------------------------------------------------------
11
12template<class I, class Ipass, class O, class Opass>
13class TFTi : public TFT<I,Ipass,O,Opass,TTrans_i<I,Ipass,O,Opass> >
14{
15public:
16  TFTi() : TFT<I,Ipass,O,Opass,TTrans_i<I,Ipass,O,Opass> >() {};
17  TFTi(const char* filename)
18  : TFT<I,Ipass,O,Opass,TTrans_i<I,Ipass,O,Opass> >() { load(filename); };
19
20  void read(const char* filename);
21  void read(istream& is=cin);
22  void write(const char* filename);
23  void write(ostream& os=cout);
24  void load(const char* filename);
25  void load(FILE* f=stdin);
26  void save(const char* filename);
27  void save(FILE* f=stdout);
28  void clear();
29  using TFT<I,Ipass,O,Opass,TTrans_i<I,Ipass,O,Opass> >::ttn;
30  using TFT<I,Ipass,O,Opass,TTrans_i<I,Ipass,O,Opass> >::states;
31  using TFT<I,Ipass,O,Opass,TTrans_i<I,Ipass,O,Opass> >::transitions;
32  using TFT<I,Ipass,O,Opass,TTrans_i<I,Ipass,O,Opass> >::itype;
33  using TFT<I,Ipass,O,Opass,TTrans_i<I,Ipass,O,Opass> >::ftTYPELEN;
34  using TFT<I,Ipass,O,Opass,TTrans_i<I,Ipass,O,Opass> >::otype;
35  using TFT<I,Ipass,O,Opass,TTrans_i<I,Ipass,O,Opass> >::tt;
36  using TFT<I,Ipass,O,Opass,TTrans_i<I,Ipass,O,Opass> >::copy_default;
37  using TFT<I,Ipass,O,Opass,TTrans_i<I,Ipass,O,Opass> >::print_mode;
38
39
40//  friend istream& operator>>(istream&, TFTi<I,Ipass,O,Opass>&);
41//  friend ostream& operator<<(ostream&, const TFTi<I,Ipass,O,Opass>&);
42};
43
44//---------------------------------------------------------------------------
45
46template<class I, class Ipass, class O, class Opass>
47void TFTi<I,Ipass,O,Opass>::read(const char* filename)
48{
49  ifstream is(filename);
50  if(!is) { fprintf(stderr,"Failed to open input file."); exit(1); }
51  read(is);
52}
53
54template<class I, class Ipass, class O, class Opass>
55void TFTi<I,Ipass,O,Opass>::read(istream& is)
56{
57  long *si;                             // state-index relation
58  long ci=0;                            // current index
59  char ch;                              // character read;
60  int empty=0;                          // no of states with 0 trans?
61  char intype[FT::ftTYPELEN];
62  char outtype[FT::ftTYPELEN];
63
64  clear();
65
66  is >> states >> transitions >> intype >> outtype;
67
68//  if(strcmp(intype,itype)!=0 ||
69//     strcmp(outtype,otype)!=0 && strcmp(outtype,"void")!=0)
70//    { is.clear(ios::badbit); goto end; };
71
72  while(is.peek()==' ' || is.peek()=='\t') is.get(ch);
73  while(is.peek()!='\n')
74  {
75    char s[20];
76    is >> s;
77    if(strcmp(s,"COPY")==0 && strcmp(intype,outtype)==0) copy_default=true;
78    else if(strcmp(s,"NOCOPY")==0) copy_default=false;
79    else if(strcmp(s,"II")==0) print_mode=FT::II;
80    else if(strcmp(s,"OO")==0) print_mode=FT::OO;
81    else if(strcmp(s,"IOIO")==0) print_mode=FT::IOIO;
82    else if(strcmp(s,"OIOI")==0) print_mode=FT::OIOI;
83    else if(strcmp(s,"IIOO")==0) print_mode=FT::IIOO;
84    else if(strcmp(s,"OIOI")==0) print_mode=FT::OIOI;
85    while(is.peek()==' ' || is.peek()=='\t') is.get(ch);
86  }
87
88  ttn=transitions+2;      // 1 state without trans., 1 additional
89  si=new long[states];
90  tt=new TTrans_i<I,Ipass,O,Opass>[ttn];
91
92  for(long cs=0;cs<states;cs++)
93  {
94    long tc;                             // transition counter
95    si[cs]=ci;
96    long cscheck;
97
98    if(!is) goto end;
99    while(is.peek()==' ' || is.peek()=='\t') is.get(ch);
100    is >> cscheck;
101    if(cs!=cscheck) goto end;
102
103    while(is.peek()==' ' || is.peek()=='\t') is.get(ch);
104
105    is.get(ch);
106    if(!is) goto end;
107    switch(ch)
108    {
109      case '-': tt[ci].final(false); break;
110      case '+': tt[ci].final(true); break;
111      default: goto end;
112    }
113    tc=0, tt[ci].continued(false);
114
115    while(is.peek()==' ' || is.peek()=='\t') is.get(ch);
116    while(is && is.peek()!='\n')
117    {
118      switch(is.peek())
119      {
120        case '~': tt[ci].epsi(true); tt[ci].defi(true); is.get(ch);
121                  break;
122        case '@': tt[ci].epsi(false); tt[ci].defi(true); is.get(ch);
123                  break;
124        default : tt[ci].geti(is);
125      }
126      if(!is) goto end;
127      if(is.peek()=='/')
128      {
129        is.get(ch);
130        switch(is.peek())
131        {
132          case '~': tt[ci].epso(true); tt[ci].defo(true); is.get(ch);
133                    break;
134          case '@': tt[ci].epso(false); tt[ci].defo(true); is.get(ch);
135                    break;
136          default : tt[ci].geto(is);
137        }
138      }
139      else
140      {
141        tt[ci].defo(true);
142        if(copy_default) tt[ci].epso(false); else tt[ci].epso(true);
143      }
144      if(!is) goto end;
145
146      unsigned long transition;
147      is >> transition;
148      tt[ci].next(transition);
149
150      tt[ci].continued(false);
151      tt[ci].empty(false);
152
153      if(tc>0) tt[ci-1].continued(true);
154      tc++,ci++;
155    }
156    if(tc==0)
157    {
158      if(++empty>2) { fprintf(stderr, "Nondeterministic automaton."); exit(1); }
159      tt[ci].empty(true);
160      ci++;
161    }
162    is.get(ch);
163    if(ch!='\n') { is.clear(ios::badbit); goto end; }
164  }
165
166  ttn=transitions+empty;
167  if(ttn!=ci) { is.clear(ios::badbit); goto end; };
168  for(long i=0;i<ttn;i++)
169    tt[i].next(si[tt[i].next()]);
170  delete[] si;
171  sort();
172
173end:
174  if(is.bad()) { fprintf(stderr,"Input error."); exit(1); }
175}
176
177//---------------------------------------------------------------------------
178
179template<class I, class Ipass, class O, class Opass>
180void TFTi<I,Ipass,O,Opass>::write(const char* filename)
181{
182  ofstream os(filename);
183  if(!os) err("Failed to open output file.");
184  write(os);
185}
186
187template<class I, class Ipass, class O, class Opass>
188void TFTi<I,Ipass,O,Opass>::write(ostream& os)
189{
190  os << states << ' ' << transitions << ' ';
191//  os << itype << ' ' << otype << ' ';
192  os << "char void";
193//  os << (copy_default ? "COPY" : "NOCOPY") << ' ';
194//  switch(print_mode)
195//  {
196//    case FT::II  : os << "II"; break;
197//    case FT::OO  : os << "OO"; break;
198//    case FT::IOIO: os << "IOIO"; break;
199//    case FT::OIOI: os << "OIOI"; break;
200//    case FT::IIOO: os << "IIOO"; break;
201//    case FT::OOII: os << "OOII";
202//  }
203  os << '\n';
204
205  long* si=new long[ttn];
206  long cs=0;
207  for(long i=0;i<ttn;i++)
208  {
209    si[i]=cs;
210    if(continued(i)==false) cs++;
211  }
212
213  int statefieldwidth=log10(cs+1);
214
215  bool first=true;
216  for(long i=0;i<ttn;i++)
217  {
218    if(first)
219    {
220      os << setw(statefieldwidth) << si[i] << " ";
221      if(final(i)) os << '+'; else os << '-';
222    }
223
224
225    if(!empty(i))
226    {
227      os << ' ';
228      if(epsi(i))
229        os << FT::ftEPSILON;
230      else
231      if(defi(i))
232        os << FT::ftDEFAULT;
233      else
234        os << input(i);
235
236      if(epso(i))
237      { if(copy_default) os << '/' << FT::ftEPSILON; }
238      else
239      if(defo(i))
240      { if(!copy_default) os << '/' << FT::ftDEFAULT; }
241      else
242      { os << '/' << output(i); }
243
244      if(strcmp(itype,"char")!=0 || strcmp(otype,"char")!=0)
245        os << ' ';
246      os << si[next(i)];
247    }
248    if(continued(i))
249      first=false;
250    else
251    { os << '\n'; first=true; }
252  }
253}
254
255//---------------------------------------------------------------------------
256
257template<class I, class Ipass, class O, class Opass>
258void TFTi<I,Ipass,O,Opass>::load(const char* filename)
259{
260  FILE* f;
261  if(*filename)
262    f=fopen(filename,"rb");
263  else
264    f=stdin;
265  if(!f) { fprintf(stderr, "Cannot open automaton file."); return; }
266  load(f);
267}
268
269template<class I, class Ipass, class O, class Opass>
270void TFTi<I,Ipass,O,Opass>::load(FILE* f)
271{
272
273  clear();
274
275  if(fread(&ttn,sizeof(ttn),1,f)!=1) { fprintf(stderr, "Binary input error."); return;}
276  if(fread(&states,sizeof(states),1,f)!=1) { fprintf(stderr, "Binary input error."); return;}
277  if(fread(&transitions,sizeof(transitions),1,f)!=1) { fprintf(stderr, "Binary input error."); return;}
278  if(fread(itype,sizeof(char),ftTYPELEN,f)!=ftTYPELEN) { fprintf(stderr, "Binary input error."); return;}
279  if(fread(otype,sizeof(char),ftTYPELEN,f)!=ftTYPELEN) { fprintf(stderr, "Binary input error."); return;}
280  if(fread(&copy_default,sizeof(copy_default),1,f)!=1) { fprintf(stderr, "Binary input error."); return;}
281  if(fread(&print_mode,sizeof(print_mode),1,f)!=1) { fprintf(stderr, "Binary input error."); return;}
282  if((tt=new TTrans_i<I,Ipass,O,Opass>[ttn])==NULL) { fprintf(stderr, "Cannot allocate memory for tt."); return;}
283  if(fread(tt,sizeof(TTrans_i<I,Ipass,O,Opass>),ttn,f)!=ttn) { fprintf(stderr, "Binary input error."); return; }
284  fclose(f);
285
286
287}
288
289//---------------------------------------------------------------------------
290
291template<class I, class Ipass, class O, class Opass>
292void TFTi<I,Ipass,O,Opass>::save(const char* filename)
293{
294  FILE* f;
295  if(*filename)
296    f=fopen(filename,"wb");
297  else
298    f=stdout;
299  if(!f) err("Cannot open file.");
300  save(f);
301}
302
303template<class I, class Ipass, class O, class Opass>
304void TFTi<I,Ipass,O,Opass>::save(FILE* f)
305{
306  if(fwrite(&ttn,sizeof(ttn),1,f)!=1) { fprintf(stderr,"Binary output error."); exit(1); }
307  if(fwrite(&states,sizeof(states),1,f)!=1) { fprintf(stderr,"Binary output error."); exit(1); }
308  if(fwrite(&transitions,sizeof(transitions),1,f)!=1) { fprintf(stderr,"Binary output error."); exit(1); }
309  if(fwrite(itype,sizeof(char),ftTYPELEN,f)!=ftTYPELEN) { fprintf(stderr,"Binary output error."); exit(1); }
310  if(fwrite(otype,sizeof(char),ftTYPELEN,f)!=ftTYPELEN) { fprintf(stderr,"Binary output error."); exit(1); }
311  if(fwrite(&copy_default,sizeof(copy_default),1,f)!=1) { fprintf(stderr,"Binary output error."); exit(1); }
312  if(fwrite(&print_mode,sizeof(print_mode),1,f)!=1) { fprintf(stderr,"Binary output error."); exit(1); }
313  if(fwrite(tt,sizeof(TTrans_i<I,Ipass,O,Opass>),ttn,f)!=ttn) { fprintf(stderr,"Binary output error."); exit(1); }
314  fclose(f);
315}
316
317//---------------------------------------------------------------------------
318
319template<class I, class Ipass, class O, class Opass>
320void TFTi<I,Ipass,O,Opass>::clear()
321{
322  if(tt) delete[] tt;
323  ttn=0;
324}
325
326//---------------------------------------------------------------------------
327/*
328template<class I, class Ipass, class O, class Opass>
329istream& operator>>(istream& is, TFTi<I,Ipass,O,Opass>& ft)
330{
331  long *si;                             // state-index relation
332  long ci=0;                            // current index
333  char ch;                              // character read;
334  int empty=0;                          // no of states with 0 trans?
335  char intype[FT::ftTYPELEN];
336  char outtype[FT::ftTYPELEN];
337
338  ft.clear();
339
340  is >> ft.states >> ft.transitions >> intype >> outtype;
341
342  if(strcmp(intype,ft.itype)!=0 ||
343     strcmp(outtype,ft.otype)!=0 && strcmp(outtype,"void")!=0)
344    { is.clear(ios::badbit); return is; };
345
346  while(is.peek()==' ' || is.peek()=='\t') is.get(ch);
347  while(is.peek()!='\n')
348  {
349    char s[20];
350    is >> s;
351    if(strcmp(s,"COPY")==0 && strcmp(intype,outtype)==0) ft.copy_default=true;
352    else if(strcmp(s,"NOCOPY")==0) ft.copy_default=false;
353    else if(strcmp(s,"II")==0) ft.print_mode=FT::II;
354    else if(strcmp(s,"OO")==0) ft.print_mode=FT::OO;
355    else if(strcmp(s,"IOIO")==0) ft.print_mode=FT::IOIO;
356    else if(strcmp(s,"OIOI")==0) ft.print_mode=FT::OIOI;
357    else if(strcmp(s,"IIOO")==0) ft.print_mode=FT::IIOO;
358    else if(strcmp(s,"OIOI")==0) ft.print_mode=FT::OIOI;
359    while(is.peek()==' ' || is.peek()=='\t') is.get(ch);
360  }
361
362  ft.ttn=ft.transitions+2;      // 1 state without trans., 1 additional
363  si=new long[ft.states];
364  ft.tt=new TTrans_i<I,Ipass,O,Opass>[ft.ttn];
365
366  for(long cs=0;cs<ft.states;cs++)
367  {
368    long tc;                             // transition counter
369    si[cs]=ci;
370    do is >> ch; while(ch!='+' && ch!='-');
371    switch(ch)
372    {
373      case '-': ft.tt[ci].final(false); break;
374      case '+': ft.tt[ci].final(true); break;
375      default: return is;
376    }
377    tc=0, ft.tt[ci].continued(false);
378    while((is.get(ch),ch==' '))
379    {
380      if(!is) return is;
381      switch(is.peek())
382      {
383        case '~': ft.tt[ci].epsi(true); ft.tt[ci].defi(true); is.get(ch);
384                  break;
385        case '@': ft.tt[ci].epsi(false); ft.tt[ci].defi(true); is.get(ch);
386                  break;
387        default : ft.tt[ci].geti(is);
388      }
389      if(!is) return is;
390      if(is.peek()=='/')
391      {
392        is.get(ch);
393        switch(is.peek())
394        {
395          case '~': ft.tt[ci].epso(true); ft.tt[ci].defo(true); is.get(ch);
396                    break;
397          case '@': ft.tt[ci].epso(false); ft.tt[ci].defo(true); is.get(ch);
398                    break;
399          default : ft.tt[ci].geto(is);
400        }
401      }
402      else
403      {
404        ft.tt[ci].defo(true);
405        if(ft.copy_default) ft.tt[ci].epso(false); else ft.tt[ci].epso(true);
406      }
407      if(!is) return is;
408
409      unsigned long transition;
410      is >> transition;
411      ft.tt[ci].next(transition);
412
413      ft.tt[ci].continued(false);
414
415      ft.tt[ci].empty(false);
416      if(tc>0) ft.tt[ci-1].continued(true);
417      tc++,ci++;
418    }
419    if(tc==0)
420    {
421      if(++empty>2) err("Nondeterministic automaton.");
422      ft.tt[ci].empty(true);
423      ci++;
424    }
425    if(ch!='\n') { is.clear(ios::badbit); return is; }
426  }
427
428  ft.ttn=ft.transitions+empty;
429  if(ft.ttn!=ci) { is.clear(ios::badbit); return is; };
430  for(long i=0;i<ft.ttn;i++)
431    ft.tt[i].next(si[ft.tt[i].next()]);
432  delete[] si;
433  ft.sort();
434  return is;
435}
436*/
437//---------------------------------------------------------------------------
438/*
439template<class I, class Ipass, class O, class Opass>
440ostream& operator<<(ostream& os, const TFTi<I,Ipass,O,Opass>& ft)
441{
442  os << ft.states << ' ' << ft.transitions << ' '
443     << ft.itype << ' ' << ft.otype << ' ';
444  os << (ft.copy_default ? "COPY" : "NOCOPY") << ' ';
445  switch(ft.print_mode)
446  {
447    case FT::II  : os << "II"; break;
448    case FT::OO  : os << "OO"; break;
449    case FT::IOIO: os << "IOIO"; break;
450    case FT::OIOI: os << "OIOI"; break;
451    case FT::IIOO: os << "IIOO"; break;
452    case FT::OOII: os << "OOII";
453  }
454  os << ' ' << '\n';
455
456  long* si=new long[ft.ttn];
457  long cs=0;
458  for(long i=0;i<ft.ttn;i++)
459  {
460    si[i]=cs;
461    if(ft.continued(i)==false) cs++;
462  }
463
464  bool first=true;
465  for(long i=0;i<ft.ttn;i++)
466  {
467    if(first)
468      if(ft.final(i)) os << '+'; else os << '-';
469
470    if(!ft.empty(i))
471    {
472      os << ' ';
473      if(ft.epsi(i))
474        os << FT::ftEPSILON;
475      else
476      if(ft.defi(i))
477        os << FT::ftDEFAULT;
478      else
479        os << ft.input(i);
480
481      if(ft.epso(i))
482      { if(ft.copy_default) os << '/' << FT::ftEPSILON; }
483      else
484      if(ft.defo(i))
485      { if(!ft.copy_default) os << '/' << FT::ftDEFAULT; }
486      else
487      { os << '/' << ft.output(i); }
488
489      if(strcmp(ft.itype,"char")!=0 || strcmp(ft.otype,"char")!=0)
490
491        os << ' ';
492      os << si[ft.next(i)];
493    }
494    if(ft.continued(i))
495      first=false;
496    else
497    { os << '\n'; first=true; }
498  }
499  return os;
500}
501*/
502//---------------------------------------------------------------------------
503//---------------------------------------------------------------------------
504
505template<class I, class O>
506class TFTiv : public TFTi<I,I,O,O>
507{
508public:
509  TFTiv() : TFTi<I,I,O,O>() {};
510  TFTiv(const char* filename) : TFTi<I,I,O,O>(filename) {};
511};
512
513//---------------------------------------------------------------------------
514
515template<class I, class O>
516class TFTir : public TFTi<I,I&,O,O&>
517{
518public:
519  TFTir() : TFTi<I,I,O,O>() {};
520};
521
522//---------------------------------------------------------------------------
523#endif
Note: See TracBrowser for help on using the repository browser.