source: _old/app/src/lib/tfti.h @ 1e121f4

Last change on this file since 1e121f4 was 1e121f4, checked in by Adam Kędziora <s301614@…>, 14 years ago

Replacing old implementation with working implementation

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