source: src/dgp/grammar.cc @ abd28d1

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

new version of dgp
added dgc, tre and compdic components
compiledic renamed to compdic_utf8
./configure updated

  • Property mode set to 100644
File size: 14.7 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
190  //<<< TU?
191
192
193  int lineno=0;
194  char line[MAXLINE]; // line has the structure: key [arg1 [arg2 [arg3]]]
195  char key[MAXLINE];
196  char arg1[MAXLINE];
197  char arg2[MAXLINE];
198  char arg3[MAXLINE];
199  char arg4[MAXLINE];
200
201  while(fgets(line,MAXLINE,f))
202    {
203      lineno++;
204      int fields=sscanf(line,"%s %s %s %s %s",key,arg1,arg2,arg3,arg4);
205     
206       if(fields<1 || key[0]=='#') continue; // skip empty lines and comments
207
208      if(fields>1 && arg1[0] == '#') fields=1;
209      if(fields>2 && arg2[0] == '#') fields=2;
210      if(fields>3 && arg3[0] == '#') fields=3;
211      if(fields>4 && arg4[0] == '#') fields=4;
212     
213      if     (strcmp(key,"CAT")==0 && fields==2)
214        {
215          add_category(arg1);
216        }
217      else if(strcmp(key,"ROLE")==0 && fields==2)
218        {
219          add_type(arg1);
220        }
221      else if(strcmp(key,"SGL")==0 && fields==2)
222        { 
223          if(chk_type(arg1))
224            set_sgl(arg1);
225          else
226            grammar_error(lineno);
227        }
228      else if(strcmp(key,"LEFT")==0 && fields==2)
229        { 
230          if(chk_type(arg1))
231            set_left(arg1);
232          else
233            grammar_error(lineno);
234        }
235      else if(strcmp(key,"RIGHT")==0 && fields==2)
236        {
237          if(chk_type(arg1))
238            set_right(arg1);
239          else
240            grammar_error(lineno);
241        }
242      else if(strcmp(key,"INITR")==0 && fields==2)
243        {
244          if(chk_type(arg1))
245            set_init(arg1);
246          else
247            grammar_error(lineno);
248        }
249      else if(strcmp(key,"FINR")==0 && fields==2)
250        {
251          if(chk_type(arg1))
252            set_fin(arg1);
253          else
254            grammar_error(lineno);
255        }
256      else if(strcmp(key,"INITF")==0 && fields==2)
257        {
258          if(chk_flag(arg1))
259            set_initf(arg1);
260          else
261            grammar_error(lineno);
262        }
263      else if(strcmp(key,"FINF")==0 && fields==2)
264        {
265          if(chk_flag(arg1))
266            set_finf(arg1);
267          else
268            grammar_error(lineno);
269        }
270      else if(strcmp(key,"REQ")==0 && fields==3)
271        {
272          if( chk_cat(arg1) && chk_type(arg2) )
273            set_obl(arg1,arg2);
274          else
275            grammar_error(lineno);
276        }
277      else if(strcmp(key,"CONSTRE")==0 && fields==3)
278        {
279          if( chk_type(arg1) && chk_type(arg2) )
280            set_exclude(arg1,arg2);
281          else
282            grammar_error(lineno);
283        }
284      else if(strcmp(key,"CONSTRI")==0 && fields==3)
285        {
286          if( chk_type(arg1) && chk_type(arg2) )
287            set_include(arg1,arg2);
288          else
289            grammar_error(lineno);
290        }
291      else if(strcmp(key,"LONG")==0 &&  fields ==3)
292        {
293            add_long(arg1,arg2);
294        }
295      else if(strcmp(key,"LINK")==0 && fields==4)
296        { 
297          char cat1[MAXLINE],flags1[MAXLINE],cat2[MAXLINE],flags2[MAXLINE],type[MAXLINE],props[MAXLINE];
298
299          if(sscanf(arg1,"%[^;];%s",cat1,flags1)==1) *flags1='\0'; 
300          if(sscanf(arg2,"%[^;];%s",cat2,flags2)==1) *flags2='\0'; 
301          if(sscanf(arg3,"%[^&]%s",type,props)==1) *props='\0';
302         
303          //      printf("line=%s\n\tcat1=%s flags1=%s cat2=%s flags2=%s type=%s props=%s\n",line,cat1,flags1,cat2,flags2,type,props);
304
305          if( chk_cat(cat1) && chk_cat(cat2) && chk_type(type) )
306            set_connect(cat1,parse_flags(flags1,"+"),parse_flags(flags1,"-"),cat2,parse_flags(flags2,"+"),parse_flags(flags2,"-"),type,parse_props(props));
307          else if( chk_cat(cat1) && chk_cat(cat2) && chk_long(type) )
308            {
309              set_longrel(cat1,cat2,type);
310              add_triggers(cat1,cat2,type);
311            }
312          else
313              grammar_error(lineno);
314        }
315      // else if(strcmp(key,"LINK")==0 && fields==5)
316      //        {
317      //          if( chk_cat(arg1) && chk_cat(arg2) && chk_type(arg4) )
318      //            set_connect(arg1,arg2,arg3,arg4);
319      //          else
320      //              grammar_error(lineno);
321      //        }
322      // FLAG DECLARATION
323      else if(strcmp(key,"FLAG")==0 && fields==2)
324        { 
325          add_flag(arg1);
326        }
327      else if(strcmp(key,"SET")==0 && fields==3)
328        {
329          if( chk_cat(arg1) && chk_flag(arg2) )
330            set_set(arg1,arg2);
331          else
332            grammar_error(lineno);
333        }
334      else if(strcmp(key,"PASS")==0 && fields==3)
335        {
336          if( chk_type(arg1) && chk_flag(arg2) )
337            set_pass(arg1,arg2);
338          else
339            grammar_error(lineno);
340        }
341     
342      else fprintf(stderr,"Statement not recognized in line %d. Ignored.\n", lineno);
343    }
344 
345  //   compute_gt();
346 
347  return true;
348 
349}
350
351
352void Grammar::write(ostream& os)
353{
354  for(Cat i=1; i<Cat::count(); ++i)
355    os << "CAT\t" << i.str() << endl;
356
357  for(Role i=1; i<Role::count(); ++i)
358    os << "ROLE\t" << i.str() << endl;
359
360  for(Role i=1; i<Role::count(); ++i)
361    if(sgl.test(i))
362      os << "SGL\t" << i.str() << endl;
363 
364  for(Role i=1; i<Role::count(); ++i)
365    if(left.test(i))
366      os << "LEFT\t" << i.str() << endl;
367
368  for(Role i=1; i<Role::count(); ++i)
369    if(right.test(i))
370      os << "RIGHT\t" << i.str() << endl;
371
372  for(Cat c=1; c<Cat::count(); ++c)
373    for(Role r=1; r<Role::count(); ++r)
374      if(obl[c].test(r))
375        os << "REQ\t" << c.str() << "\t" << r.str() << endl;
376 
377  for(Cat c=1; c<Cat::count(); ++c)
378    for(Cat d=1; d<Cat::count(); ++d)
379      for(Links::const_iterator l = connect1[c][d].begin(); l != connect1[c][d].end(); l++)
380        {
381          os << "LINK\t" << c.str();
382          if(l->hflagplus||l->hflagminus)
383            {
384              os << ";";
385              if(l->hflagplus) os << (l->hflagplus).str() << "+";
386              if(l->hflagminus) os << (l->hflagminus).str() << "-"; 
387            }
388          os << "\t" << d.str();
389          if(l->dflagplus||l->dflagminus)
390            {
391              os << ";";
392              if(l->dflagplus) os << (l->dflagplus).str() << "+";
393              if(l->dflagminus) os << (l->dflagminus).str() << "-"; 
394            }
395          os << "\t" << (l->role).str();
396          for(Prop p=0; p<Prop::count(); ++p)
397            if(l->props[p])
398              os << "&" << p.str();
399          os << endl;
400        }
401
402  for(LongRel i=1; i<LongRel::count(); ++i)
403    os << "LONG\t" << i.str() << endl;
404
405  for(list<Boubble*>::const_iterator b = boubbles.begin(); b != boubbles.end(); b++)
406    os << "BOUBBLE\t" << **b << endl;
407
408  for(Cat c=1; c<Cat::count(); ++c)
409    for(Cat d=1; d<Cat::count(); ++d)
410      for(LongRel l=1; l<LongRel::count(); ++l)
411        if(longrel[c][d].count(l))
412          os << "LLINK\t" << c.str() << "\t" << d.str() << "\t" << l.str() << endl;
413
414  for(Cat c=1; c<Cat::count(); ++c)
415    for(Flag f=1; f<Flag::count(); ++f)
416      if(set[c].test(f))
417        os << "SET\t" << c.str() << "\t" << f.str() << endl;
418
419  for(Role r=1; r<Role::count(); ++r)
420    for(Flag f=1; f<Flag::count(); ++f)
421      if(pass[r].test(f))
422        os << "PASS\t" << r.str() << "\t" << f.str() << endl;
423 
424  for(Role r=1; r<Role::count(); ++r)
425    for(Role t=1; t<Role::count(); ++t)
426      if(include[r].test(t))
427        os << "CONSTRI\t" << r.str() << "\t" << t.str() << endl;
428 
429  for(Role r=1; r<Role::count(); ++r)
430    for(Role t=1; t<Role::count(); ++t)
431      if(exclude[r].test(t))
432        os << "CONSTRE\t" << r.str() << "\t" << t.str() << endl;
433 
434  for(Cat c=1; c<Cat::count(); ++c)
435    for(Role r=1; r<Role::count(); ++r)
436      for(list<Boubble*>::const_iterator b=uptrigger[c][r].begin(); b!=uptrigger[c][r].end(); b++)
437        os << "TRIGGER-UP\t" << c.str() << "\t" << r.str() << "\t" << (*b)->rel().str() << endl;
438
439  for(Cat c=1; c<Cat::count(); ++c)
440    for(Role r=1; r<Role::count(); ++r)
441      for(list<Boubble*>::const_iterator b=dntrigger[c][r].begin(); b!=dntrigger[c][r].end(); b++)
442        os << "TRIGGER-DN\t" << c.str() << "\t" << r.str() << "\t" << (*b)->rel().str() << endl;
443
444  for(Flag i=1; i<Flag::count(); ++i)
445    os << "FLAG\t" << i.str() << endl;
446}
447
448
449
450
451
452
453
454
455
456//================================= OLD
457
458void Grammar::write(FILE* f)
459{
460  for(Cat i=1; i<Cat::count(); ++i)
461    fprintf(f,"CAT\t%s\n",i.str());
462
463  for(Role i=1; i<Role::count(); ++i)
464    fprintf(f,"ROLE\t%s (%d)(%d)\n",i.str(),Role::index(i.str()),chk_type(i.str()));
465
466  for(Role i=1; i<Role::count(); ++i)
467    if(sgl.test(i)) fprintf(f,"SGL\t%s\n",i.str());
468 
469  for(Role i=1; i<Role::count(); ++i)
470    if(left.test(i)) fprintf(f,"LEFT\t%s\n",i.str());
471
472  for(Role i=1; i<Role::count(); ++i)
473    if(right.test(i)) fprintf(f,"RIGHT\t%s\n",i.str());
474
475  for(Cat c=1; c<Cat::count(); ++c)
476    for(Role r=1; r<Role::count(); ++r)
477      if(obl[c].test(r)) fprintf(f,"REQ\t%s\t%s\n",c.str(),r.str());
478 
479  for(Cat c=1; c<Cat::count(); ++c)
480    for(Cat d=1; d<Cat::count(); ++d)
481      for(Role t=1; t<Role::count(); ++t)
482        if(connect[c][d].count(t))
483          fprintf(f,"LINK\t%s\t%s\t%s\n",c.str(),d.str(),t.str());
484
485  for(LongRel i=1; i<LongRel::count(); ++i)
486    fprintf(f,"LONG\t%s\n",i.str());
487
488  for(Cat c=1; c<Cat::count(); ++c)
489    for(Cat d=1; d<Cat::count(); ++d)
490      for(LongRel l=1; l<LongRel::count(); ++l)
491        if(longrel[c][d].count(l))
492          fprintf(f,"LLINK\t%s\t%s\t%s\n",c.str(),d.str(),l.str());
493
494  for(Cat c=1; c<Cat::count(); ++c)
495    for(Role r=1; r<Role::count(); ++r)
496      for(list<Boubble*>::const_iterator b=uptrigger[c][r].begin(); b!=uptrigger[c][r].end(); b++)
497        fprintf(f,"#TRIGGER\t%s\t%s\t%s\n",c.str(),r.str(),(*b)->rel().str());
498
499  for(Cat c=1; c<Cat::count(); ++c)
500    for(Role r=1; r<Role::count(); ++r)
501      for(list<Boubble*>::const_iterator b=dntrigger[c][r].begin(); b!=dntrigger[c][r].end(); b++)
502        fprintf(f,"#TRIGGER\t%s\t%s\t%s\n",c.str(),r.str(),(*b)->rel().str());
503
504  for(Flag i=1; i<Flag::count(); ++i)
505    fprintf(f,"FLAG\t%s\n",i.str());
506}
Note: See TracBrowser for help on using the repository browser.