source: src/dgp/grammar.cc @ d6a59ca

Last change on this file since d6a59ca was 3b02b04, checked in by Tomasz Obrebski <to@…>, 12 years ago

prawie ca�kiem nowe dgc, du�e zmiany w dgp, pomniejsze poprawki

  • Property mode set to 100644
File size: 15.5 KB
Line 
1
2#include <cstdio>
3
4#include "grammar.hh"
5
6//bool (*constraint[MAXCONSTRS])(int head, int dep);
7
8//====================================================================================================
9//inline !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
10bool chk_type(const char* s) { return Role::index(s)>0; } // PRZENIEŠÆ DO Role
11//----------------------------------------------------------------------------------------------------
12//inline !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
13bool chk_long(const char* s) { return LongRel::index(s)>0; } // jw
14//----------------------------------------------------------------------------------------------------
15//inline !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
16bool chk_cat(const char* s) { return Cat::index(s)>0; } //jw
17//----------------------------------------------------------------------------------------------------
18//inline !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
19bool chk_flag(const char* s) { return Flag::index(s)>0; } //jw
20//====================================================================================================
21
22void grammar_error(int lineno, string s="Grammar error.")
23{
24  fprintf(stderr,"%8d: %s Line ignored.\n",lineno,s.c_str());
25}
26
27//====================================================================================================
28
29void Grammar::add_category(const char* s)
30{
31  Cat::add(s);
32
33  if(connect.size() <= Cat::count())
34  {
35    connect.resize(Cat::count()+RESIZE_DELTA);
36    for(int i=0; i<connect.size(); ++i)
37      if(connect[i].size() <= Cat::count()) connect[i].resize(Cat::count()+RESIZE_DELTA);
38  }
39  if(connect1.size() <= Cat::count())
40  {
41    connect1.resize(Cat::count()+RESIZE_DELTA);
42    for(int i=0; i<=connect1.size(); ++i)
43      if(connect1[i].size() <= Cat::count()) connect1[i].resize(Cat::count()+RESIZE_DELTA);
44  }
45
46  if(longrel.size() <= Cat::count())
47  {
48    longrel.resize(Cat::count()+RESIZE_DELTA);
49    for(int i=0; i<longrel.size(); ++i)
50      if(longrel[i].size() <= Cat::count()) longrel[i].resize(Cat::count()+RESIZE_DELTA);
51  }
52
53  if(uptrigger.size() <= Cat::count())
54    uptrigger.resize(Cat::count()+RESIZE_DELTA);
55  if(dntrigger.size() <= Cat::count())
56    dntrigger.resize(Cat::count()+RESIZE_DELTA);
57 
58  if(obl.size() <= Cat::count()) obl.resize(Cat::count()+RESIZE_DELTA);
59  if(set.size() <= Cat::count()) set.resize(Cat::count()+RESIZE_DELTA);
60}
61
62void Grammar::add_type(const char* s)
63{ 
64  Role::add(s);
65
66  if(lt.size() <= Role::count()) lt.resize(Role::count()+RESIZE_DELTA);
67  if(gt.size() <= Role::count()) gt.resize(Role::count()+RESIZE_DELTA);
68  if(pass.size() <= Role::count()) pass.resize(Role::count()+RESIZE_DELTA);
69  if(include.size() <= Role::count()) include.resize(Role::count()+RESIZE_DELTA);
70  if(exclude.size() <= Role::count()) exclude.resize(Role::count()+RESIZE_DELTA);
71  for(int i=0; i<uptrigger.size(); i++)
72    if(uptrigger[i].size() <= Role::count()) uptrigger[i].resize(Role::count()+RESIZE_DELTA);
73  for(int i=0; i<dntrigger.size(); i++)
74    if(dntrigger[i].size() <= Role::count()) dntrigger[i].resize(Role::count()+RESIZE_DELTA);
75}
76
77//====================================================================================================
78
79bool Grammar::contains_boubble(const list<Boubble*> boubble_list, Boubble* bp) const
80{
81  for(list<Boubble*>::const_iterator bi = boubble_list.begin(); bi != boubble_list.end(); bi++ )
82    if(**bi == *bp) return true;
83  return false;
84}
85
86//----------------------------------------------------------------------------------------------------
87
88void Grammar::add_triggers(Cat src, Cat dest, LongRel l)
89{
90  for(list<Boubble*>::const_iterator b=boubbles.begin(); b!=boubbles.end(); b++)
91    if((*b)->rel() == l)
92      {
93        list<Boubble*>& boubble_list = ((*b)->dir()==UP) ? uptrigger[src][(*b)->next()] : dntrigger[src][(*b)->next()] ;
94        if(!contains_boubble(boubble_list,*b))
95          boubble_list.push_back(*b);
96      }
97}
98
99//====================================================================================================
100
101void Grammar::set_lt(Role s, Role t)
102{
103  lt[s].set(t);
104  gt[t].set(s);
105  if(s==0||(int)t==0)
106    return;
107  else
108  {
109    for(int i=0; i<Role::count(); ++i)
110      if(lt[i][s])
111        set_lt(i,t);
112    for(int i=0; i<Role::count(); ++i)
113      if(lt[t][i])
114        set_lt(s,i);
115  }
116} 
117
118
119void Grammar::compute_gt()
120{
121  for(Role s=0; s<Role::count(); ++s)
122    for(Role t=0; t<Role::count(); ++t)
123      if(lt[s][t])
124        gt[t].set(s);
125}
126
127
128void Grammar::compute_triggers()
129{
130  //init uptrigger array
131  uptrigger.resize(Cat::count());
132  for(int i=0; i<uptrigger.size(); i++)
133    uptrigger[i].resize(Role::count());
134  //init dntrigger array
135  dntrigger.resize(Cat::count());
136  for(int i=0; i<dntrigger.size(); i++)
137    dntrigger[i].resize(Role::count());
138
139  // for(int c=0; c<Cat::count(); c++)
140  //   for(int r=0; r<Role::count(); r++)
141  //     for(list<Boubble>::const_iterator b=boubbles.begin(); b!=boubbles.end; b++)
142  //    if(b->dir()==UP && )
143}
144
145//====================================================================================================
146
147list<Boubble*> Grammar::trigger_boubbles(Cat c, Role r, Dir d)
148{
149  list<Boubble*> boubble_list = (d == UP) ? uptrigger[c][r] : dntrigger[c][r];
150  list<Boubble*> ret;
151  for(list<Boubble*>::iterator b = boubble_list.begin(); b != boubble_list.end(); ++b)
152    ret.push_back((*b)->step(r,d));
153  return ret; 
154}
155
156//====================================================================================================
157
158Flag parse_flags(const char* s, const char* v)
159{
160  char buf[16][17];
161  int n=sscanf(s,"%[A-Z]%[+-]%[A-Z]%[+-]%[A-Z]%[+-]%[A-Z]%[+-]%[A-Z]%[+-]%[A-Z]%[+-]%[A-Z]%[+-]%[A-Z]%[+-]",
162               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]);
163  for(int i=2; i<=n; i+=2)
164    if(strcmp(buf[i-1],v)==0)
165      return Flag(buf[i-2]);
166  return Flag("NULL");
167}
168
169
170PropSet parse_props(const char* s)
171{
172  PropSet ret;
173  char buf[8][17];
174  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]);
175  for(int i=1; i<=n; i++)
176    ret.set(Prop(buf[i-1]));
177  return ret; 
178 
179}
180
181
182bool Grammar::read(FILE* f)
183{
184
185  //>>> TU?
186
187  Prop::add("INIT");
188  Prop::add("FIN");
189  Prop::add("LEFT");
190  Prop::add("RIGHT");
191
192  //<<< TU?
193
194
195  int lineno=0;
196  char line[MAXLINE]; // line has the structure: key [arg1 [arg2 [arg3]]]
197  char key[MAXLINE];
198  char arg1[MAXLINE];
199  char arg2[MAXLINE];
200  char arg3[MAXLINE];
201  char arg4[MAXLINE];
202
203  while(fgets(line,MAXLINE,f))
204    {
205      lineno++;
206      int fields=sscanf(line,"%s %s %s %s %s",key,arg1,arg2,arg3,arg4);
207     
208       if(fields<1 || key[0]=='#') continue; // skip empty lines and comments
209
210      if(fields>1 && arg1[0] == '#') fields=1;
211      if(fields>2 && arg2[0] == '#') fields=2;
212      if(fields>3 && arg3[0] == '#') fields=3;
213      if(fields>4 && arg4[0] == '#') fields=4;
214     
215      if     (strcmp(key,"CAT")==0 && fields==2)
216        {
217          add_category(arg1);
218        }
219      else if(strcmp(key,"ROLE")==0 && fields==2)
220        {
221          add_type(arg1);
222        }
223      else if(strcmp(key,"SGL")==0 && fields==2)
224        { 
225          if(chk_type(arg1))
226            set_sgl(arg1);
227          else
228            grammar_error(lineno);
229        }
230      else if(strcmp(key,"LEFT")==0 && fields==2)
231        { 
232          if(chk_type(arg1))
233            set_left(arg1);
234          else
235            grammar_error(lineno);
236        }
237      else if(strcmp(key,"RIGHT")==0 && fields==2)
238        {
239          if(chk_type(arg1))
240            set_right(arg1);
241          else
242            grammar_error(lineno);
243        }
244      else if(strcmp(key,"INITR")==0 && fields==2)
245        {
246          if(chk_type(arg1))
247            set_init(arg1);
248          else
249            grammar_error(lineno);
250        }
251      else if(strcmp(key,"FINR")==0 && fields==2)
252        {
253          if(chk_type(arg1))
254            set_fin(arg1);
255          else
256            grammar_error(lineno);
257        }
258      else if(strcmp(key,"INITF")==0 && fields==2)
259        {
260          if(chk_flag(arg1))
261            set_initf(arg1);
262          else
263            grammar_error(lineno);
264        }
265      else if(strcmp(key,"FINF")==0 && fields==2)
266        {
267          if(chk_flag(arg1))
268            set_finf(arg1);
269          else
270            grammar_error(lineno);
271        }
272      else if(strcmp(key,"REQ")==0 && fields==3)
273        {
274          if( chk_cat(arg1) && chk_type(arg2) )
275            set_obl(arg1,arg2);
276          else
277            grammar_error(lineno);
278        }
279      else if(strcmp(key,"CONSTRE")==0 && fields==3)
280        {
281          if( chk_type(arg1) && chk_type(arg2) )
282            set_exclude(arg1,arg2);
283          else
284            grammar_error(lineno);
285        }
286      else if(strcmp(key,"CONSTRI")==0 && fields==3)
287        {
288          if( chk_type(arg1) && chk_type(arg2) )
289            set_include(arg1,arg2);
290          else
291            grammar_error(lineno);
292        }
293      else if(strcmp(key,"LONG")==0 &&  fields ==3)
294        {
295            add_long(arg1,arg2);
296        }
297      else if(strcmp(key,"LINK")==0 && fields==4)
298        { 
299          char cat1[MAXLINE],flags1[MAXLINE],cat2[MAXLINE],flags2[MAXLINE],type[MAXLINE],props[MAXLINE];
300          char* double_slash_position;
301          // pierwszy argument
302          // if(sscanf(arg1,"%[^;];%s",cat1,flags1)==1) *flags1='\0';
303          if((double_slash_position=strstr(arg1,"//")) != NULL) // czy s± flagi
304            {
305              int cat_length=double_slash_position-arg1;
306              strncpy(cat1, arg1, cat_length); cat1[cat_length]='\0';
307              strcpy(flags1, arg1+cat_length+2);
308            }
309          else
310            {
311              strcpy(cat1, arg1);
312              flags1[0]='\0';
313            }
314          // drugi argument
315          // if(sscanf(arg2,"%[^;];%s",cat2,flags2)==1) *flags2='\0';
316          if((double_slash_position=strstr(arg2,"//")) != NULL) // czy s± flagi
317            {
318              int cat_length=double_slash_position-arg2;
319              strncpy(cat2, arg2, cat_length); cat2[cat_length]='\0';
320              strcpy(flags2, arg2+cat_length+2);
321            }
322          else
323            {
324              strcpy(cat2,arg2);
325              flags2[0]='\0';
326            }
327          // trzeci argument
328          if(sscanf(arg3,"%[^&]%s",type,props)==1) props[0]='\0';
329         
330          // printf("line=%s\n\tcat1=<%s> flags1=%s cat2=<%s> flags2=%s type=<%s> props=%s\n",line,cat1,flags1,cat2,flags2,type,props);
331
332          if( chk_cat(cat1) && chk_cat(cat2) && chk_type(type) )
333            set_connect(cat1,parse_flags(flags1,"+"),parse_flags(flags1,"-"),cat2,parse_flags(flags2,"+"),parse_flags(flags2,"-"),type,parse_props(props));
334          else if( chk_cat(cat1) && chk_cat(cat2) && chk_long(type) )
335            {
336              set_longrel(cat1,cat2,type);
337              add_triggers(cat1,cat2,type);
338            }
339          else
340              grammar_error(lineno);
341        }
342      // else if(strcmp(key,"LINK")==0 && fields==5)
343      //        {
344      //          if( chk_cat(arg1) && chk_cat(arg2) && chk_type(arg4) )
345      //            set_connect(arg1,arg2,arg3,arg4);
346      //          else
347      //              grammar_error(lineno);
348      //        }
349      // FLAG DECLARATION
350      else if(strcmp(key,"FLAG")==0 && fields==2)
351        { 
352          add_flag(arg1);
353        }
354      else if(strcmp(key,"SET")==0 && fields==3)
355        {
356          if( chk_cat(arg1) && chk_flag(arg2) )
357            set_set(arg1,arg2);
358          else
359            grammar_error(lineno);
360        }
361      else if(strcmp(key,"PASS")==0 && fields==3)
362        {
363          if( chk_type(arg1) && chk_flag(arg2) )
364            set_pass(arg1,arg2);
365          else
366            grammar_error(lineno);
367        }
368     
369      else fprintf(stderr,"Statement not recognized in line %d. Ignored.\n", lineno);
370    }
371 
372  //   compute_gt();
373
374  return true;
375 
376}
377
378
379void Grammar::write(ostream& os)
380{
381  for(Cat i=1; i<Cat::count(); ++i)
382    os << "CAT\t" << i.str() << endl;
383
384  for(Role i=1; i<Role::count(); ++i)
385    os << "ROLE\t" << i.str() << endl;
386
387  for(Role i=1; i<Role::count(); ++i)
388    if(sgl.test(i))
389      os << "SGL\t" << i.str() << endl;
390 
391  for(Role i=1; i<Role::count(); ++i)
392    if(left.test(i))
393      os << "LEFT\t" << i.str() << endl;
394
395  for(Role i=1; i<Role::count(); ++i)
396    if(right.test(i))
397      os << "RIGHT\t" << i.str() << endl;
398
399  for(Cat c=1; c<Cat::count(); ++c)
400    for(Role r=1; r<Role::count(); ++r)
401      if(obl[c].test(r))
402        os << "REQ\t" << c.str() << "\t" << r.str() << endl;
403 
404  for(Cat c=1; c<Cat::count(); ++c)
405    for(Cat d=1; d<Cat::count(); ++d)
406      for(Links::const_iterator l = connect1[c][d].begin(); l != connect1[c][d].end(); l++)
407        {
408          os << "LINK\t" << c.str();
409          if(l->hflagplus||l->hflagminus)
410            {
411              os << ";";
412              if(l->hflagplus) os << (l->hflagplus).str() << "+";
413              if(l->hflagminus) os << (l->hflagminus).str() << "-"; 
414            }
415          os << "\t" << d.str();
416          if(l->dflagplus||l->dflagminus)
417            {
418              os << ";";
419              if(l->dflagplus) os << (l->dflagplus).str() << "+";
420              if(l->dflagminus) os << (l->dflagminus).str() << "-"; 
421            }
422          os << "\t" << (l->role).str();
423          for(Prop p=0; p<Prop::count(); ++p)
424            if(l->props[p])
425              os << "&" << p.str();
426          os << endl;
427        }
428
429  for(LongRel i=1; i<LongRel::count(); ++i)
430    os << "LONG\t" << i.str() << endl;
431
432  for(list<Boubble*>::const_iterator b = boubbles.begin(); b != boubbles.end(); b++)
433    os << "BOUBBLE\t" << **b << endl;
434
435  for(Cat c=1; c<Cat::count(); ++c)
436    for(Cat d=1; d<Cat::count(); ++d)
437      for(LongRel l=1; l<LongRel::count(); ++l)
438        if(longrel[c][d].count(l))
439          os << "LLINK\t" << c.str() << "\t" << d.str() << "\t" << l.str() << endl;
440
441  for(Cat c=1; c<Cat::count(); ++c)
442    for(Flag f=1; f<Flag::count(); ++f)
443      if(set[c].test(f))
444        os << "SET\t" << c.str() << "\t" << f.str() << endl;
445
446  for(Role r=1; r<Role::count(); ++r)
447    for(Flag f=1; f<Flag::count(); ++f)
448      if(pass[r].test(f))
449        os << "PASS\t" << r.str() << "\t" << f.str() << endl;
450 
451  for(Role r=1; r<Role::count(); ++r)
452    for(Role t=1; t<Role::count(); ++t)
453      if(include[r].test(t))
454        os << "CONSTRI\t" << r.str() << "\t" << t.str() << endl;
455 
456  for(Role r=1; r<Role::count(); ++r)
457    for(Role t=1; t<Role::count(); ++t)
458      if(exclude[r].test(t))
459        os << "CONSTRE\t" << r.str() << "\t" << t.str() << endl;
460 
461  for(Cat c=1; c<Cat::count(); ++c)
462    for(Role r=1; r<Role::count(); ++r)
463      for(list<Boubble*>::const_iterator b=uptrigger[c][r].begin(); b!=uptrigger[c][r].end(); b++)
464        os << "TRIGGER-UP\t" << c.str() << "\t" << r.str() << "\t" << (*b)->rel().str() << endl;
465
466  for(Cat c=1; c<Cat::count(); ++c)
467    for(Role r=1; r<Role::count(); ++r)
468      for(list<Boubble*>::const_iterator b=dntrigger[c][r].begin(); b!=dntrigger[c][r].end(); b++)
469        os << "TRIGGER-DN\t" << c.str() << "\t" << r.str() << "\t" << (*b)->rel().str() << endl;
470
471  for(Flag i=1; i<Flag::count(); ++i)
472    os << "FLAG\t" << i.str() << endl;
473}
474
475
476
477
478
479
480
481
482
483//================================= OLD
484
485void Grammar::write(FILE* f)
486{
487  for(Cat i=1; i<Cat::count(); ++i)
488    fprintf(f,"CAT\t%s\n",i.str());
489
490  for(Role i=1; i<Role::count(); ++i)
491    fprintf(f,"ROLE\t%s (%d)(%d)\n",i.str(),Role::index(i.str()),chk_type(i.str()));
492
493  for(Role i=1; i<Role::count(); ++i)
494    if(sgl.test(i)) fprintf(f,"SGL\t%s\n",i.str());
495 
496  for(Role i=1; i<Role::count(); ++i)
497    if(left.test(i)) fprintf(f,"LEFT\t%s\n",i.str());
498
499  for(Role i=1; i<Role::count(); ++i)
500    if(right.test(i)) fprintf(f,"RIGHT\t%s\n",i.str());
501
502  for(Cat c=1; c<Cat::count(); ++c)
503    for(Role r=1; r<Role::count(); ++r)
504      if(obl[c].test(r)) fprintf(f,"REQ\t%s\t%s\n",c.str(),r.str());
505 
506  for(Cat c=1; c<Cat::count(); ++c)
507    for(Cat d=1; d<Cat::count(); ++d)
508      for(Role t=1; t<Role::count(); ++t)
509        if(connect[c][d].count(t))
510          fprintf(f,"LINK\t%s\t%s\t%s\n",c.str(),d.str(),t.str());
511
512  for(LongRel i=1; i<LongRel::count(); ++i)
513    fprintf(f,"LONG\t%s\n",i.str());
514
515  for(Cat c=1; c<Cat::count(); ++c)
516    for(Cat d=1; d<Cat::count(); ++d)
517      for(LongRel l=1; l<LongRel::count(); ++l)
518        if(longrel[c][d].count(l))
519          fprintf(f,"LLINK\t%s\t%s\t%s\n",c.str(),d.str(),l.str());
520
521  for(Cat c=1; c<Cat::count(); ++c)
522    for(Role r=1; r<Role::count(); ++r)
523      for(list<Boubble*>::const_iterator b=uptrigger[c][r].begin(); b!=uptrigger[c][r].end(); b++)
524        fprintf(f,"#TRIGGER\t%s\t%s\t%s\n",c.str(),r.str(),(*b)->rel().str());
525
526  for(Cat c=1; c<Cat::count(); ++c)
527    for(Role r=1; r<Role::count(); ++r)
528      for(list<Boubble*>::const_iterator b=dntrigger[c][r].begin(); b!=dntrigger[c][r].end(); b++)
529        fprintf(f,"#TRIGGER\t%s\t%s\t%s\n",c.str(),r.str(),(*b)->rel().str());
530
531  for(Flag i=1; i<Flag::count(); ++i)
532    fprintf(f,"FLAG\t%s\n",i.str());
533}
Note: See TracBrowser for help on using the repository browser.