| 1 |  | 
|---|
| 2 | #include <stdio.h> | 
|---|
| 3 |  | 
|---|
| 4 | #include "grammar.hh" | 
|---|
| 5 |  | 
|---|
| 6 | bool (*constraint[MAXCONSTRS])(int head, int dep); | 
|---|
| 7 |  | 
|---|
| 8 |  | 
|---|
| 9 | int chk_type(const char* s, int lineno) // SIDE EFECTS! | 
|---|
| 10 | { | 
|---|
| 11 |   if(Role::index(s)>0) return 1; | 
|---|
| 12 |  | 
|---|
| 13 |   fprintf(stderr,"%8d: Invalid type '%s'. Line ignored.\n",lineno,s); | 
|---|
| 14 |   return 0; | 
|---|
| 15 | } | 
|---|
| 16 |  | 
|---|
| 17 | int chk_cat(const char* s, int lineno) | 
|---|
| 18 | { | 
|---|
| 19 |   if(Cat::index(s)>0) return 1; | 
|---|
| 20 |  | 
|---|
| 21 |   fprintf(stderr,"%8d: Invalid category '%s'. Line ignored.\n",lineno,s); | 
|---|
| 22 |   return 0; | 
|---|
| 23 | } | 
|---|
| 24 |  | 
|---|
| 25 | void Grammar::add_category(const char* s) | 
|---|
| 26 | { | 
|---|
| 27 |   Cat::add(s); | 
|---|
| 28 |   if(Cat::count()>cats_sz) | 
|---|
| 29 |   { | 
|---|
| 30 |     cats_sz += 16; | 
|---|
| 31 |     connect.resize(cats_sz); | 
|---|
| 32 |     for(int i=0; i<cats_sz; ++i) | 
|---|
| 33 |       connect[i].resize(cats_sz); | 
|---|
| 34 |     obl.resize(cats_sz); | 
|---|
| 35 |   } | 
|---|
| 36 | } | 
|---|
| 37 |  | 
|---|
| 38 | void Grammar::add_type(const char* s) | 
|---|
| 39 | {   | 
|---|
| 40 |   Role::add(s); | 
|---|
| 41 |   if(Role::count()>types_sz) | 
|---|
| 42 |   { | 
|---|
| 43 |     types_sz += 16; | 
|---|
| 44 |     lt.resize(types_sz); | 
|---|
| 45 |     gt.resize(types_sz); | 
|---|
| 46 |   } | 
|---|
| 47 | } | 
|---|
| 48 |  | 
|---|
| 49 | void Grammar::add_flag(const char* s) | 
|---|
| 50 | {   | 
|---|
| 51 |   Flag::add(s); | 
|---|
| 52 |   if(Flag::count()>flags_sz) | 
|---|
| 53 |   { | 
|---|
| 54 |     flags_sz += 16; | 
|---|
| 55 |     pass.resize(flags_sz); | 
|---|
| 56 |   } | 
|---|
| 57 | } | 
|---|
| 58 |  | 
|---|
| 59 |  | 
|---|
| 60 | void Grammar::set_lt(Role s, Role t) | 
|---|
| 61 | { | 
|---|
| 62 |   lt[s].set(t); | 
|---|
| 63 |   gt[t].set(s); | 
|---|
| 64 |   if(s==0||(int)t==0) | 
|---|
| 65 |     return; | 
|---|
| 66 |   else | 
|---|
| 67 |   { | 
|---|
| 68 |     for(int i=0; i<Role::count(); ++i) | 
|---|
| 69 |       if(lt[i][s]) | 
|---|
| 70 |         set_lt(i,t); | 
|---|
| 71 |     for(int i=0; i<Role::count(); ++i) | 
|---|
| 72 |       if(lt[t][i]) | 
|---|
| 73 |         set_lt(s,i); | 
|---|
| 74 |   } | 
|---|
| 75 | }   | 
|---|
| 76 |  | 
|---|
| 77 |  | 
|---|
| 78 | void Grammar::compute_gt() | 
|---|
| 79 | { | 
|---|
| 80 |   for(Role s=0; s<Role::count(); ++s) | 
|---|
| 81 |     for(Role t=0; t<Role::count(); ++t) | 
|---|
| 82 |       if(lt[s][t]) | 
|---|
| 83 |         gt[t].set(s); | 
|---|
| 84 | } | 
|---|
| 85 |  | 
|---|
| 86 |  | 
|---|
| 87 | bool Grammar::read(FILE* f) | 
|---|
| 88 | { | 
|---|
| 89 |   int lineno=0; | 
|---|
| 90 |   char line[MAXLINE]; // line has the structure: key [arg1 [arg2 [arg3]]] | 
|---|
| 91 |   char key[MAXLINE]; | 
|---|
| 92 |   char arg1[MAXLINE]; | 
|---|
| 93 |   char arg2[MAXLINE]; | 
|---|
| 94 |   char arg3[MAXLINE]; | 
|---|
| 95 |  | 
|---|
| 96 |   while(fgets(line,MAXLINE,f)) | 
|---|
| 97 |   { | 
|---|
| 98 |     lineno++; | 
|---|
| 99 |     int fields=sscanf(line,"%s %s %s %s",key,arg1,arg2,arg3); | 
|---|
| 100 |  | 
|---|
| 101 |     if(fields<1 || key[0]=='#') continue; // skip empty lines and comments | 
|---|
| 102 |  | 
|---|
| 103 |     if     (strcmp(key,"CAT")==0 && fields>=2) | 
|---|
| 104 |     { | 
|---|
| 105 |       add_category(arg1); | 
|---|
| 106 |     } | 
|---|
| 107 |     else if(strcmp(key,"ROLE")==0 && fields>=2) | 
|---|
| 108 |     { | 
|---|
| 109 |       add_type(arg1); | 
|---|
| 110 |     } | 
|---|
| 111 |     else if(strcmp(key,"SGL")==0 && fields>=2) | 
|---|
| 112 |     {   | 
|---|
| 113 |       if(chk_type(arg1,lineno)) | 
|---|
| 114 |         set_sgl(arg1); | 
|---|
| 115 |     } | 
|---|
| 116 |     else if(strcmp(key,"LEFT")==0 && fields>=2) | 
|---|
| 117 |     {  | 
|---|
| 118 |       if(chk_type(arg1,lineno)) | 
|---|
| 119 |         set_left(arg1); | 
|---|
| 120 |     } | 
|---|
| 121 |     else if(strcmp(key,"RIGHT")==0 && fields>=2) | 
|---|
| 122 |     { | 
|---|
| 123 |       if(chk_type(arg1,lineno)) | 
|---|
| 124 |         set_right(arg1); | 
|---|
| 125 |     } | 
|---|
| 126 |     else if(strcmp(key,"REQ")==0 && fields>=3) | 
|---|
| 127 |     { | 
|---|
| 128 |       if(chk_cat(arg1,lineno) + chk_type(arg2,lineno) == 2) | 
|---|
| 129 |         set_obl(arg1,arg2); | 
|---|
| 130 |     } | 
|---|
| 131 |     else if(strcmp(key,"LINK")==0 && fields>=4) | 
|---|
| 132 |     {  | 
|---|
| 133 |       if(chk_cat(arg1,lineno) + chk_cat(arg2,lineno) + chk_type(arg3,lineno) == 3)     | 
|---|
| 134 |         set_connect(arg1,arg2,arg3); | 
|---|
| 135 |     } | 
|---|
| 136 |     // FLAG DECLARATION | 
|---|
| 137 |     else if(strcmp(key,"FLAG")==0 && fields>=2) | 
|---|
| 138 |     {  | 
|---|
| 139 |       add_flag(arg1); | 
|---|
| 140 |     } | 
|---|
| 141 |  | 
|---|
| 142 |     else fprintf(stderr,"Invalid line %d. Ignored.\n", lineno); | 
|---|
| 143 |   } | 
|---|
| 144 |  | 
|---|
| 145 | //   compute_gt(); | 
|---|
| 146 |  | 
|---|
| 147 |   return true; | 
|---|
| 148 |    | 
|---|
| 149 | } | 
|---|
| 150 |  | 
|---|
| 151 | void Grammar::write(FILE* f) | 
|---|
| 152 | { | 
|---|
| 153 |   for(Cat i=1; i<Cat::count(); ++i) | 
|---|
| 154 |     fprintf(f,"CAT\t%s\n",i.str()); | 
|---|
| 155 |  | 
|---|
| 156 |   for(Role i=1; i<Role::count(); ++i) | 
|---|
| 157 |     fprintf(f,"ROLE\t%s\n",i.str()); | 
|---|
| 158 |  | 
|---|
| 159 |   for(Role i=1; i<Role::count(); ++i) | 
|---|
| 160 |     if(sgl.test(i)) fprintf(f,"SGL\t%s\n",i.str()); | 
|---|
| 161 |    | 
|---|
| 162 |   for(Role i=1; i<Role::count(); ++i) | 
|---|
| 163 |     if(left.test(i)) fprintf(f,"LEFT\t%s\n",i.str()); | 
|---|
| 164 |  | 
|---|
| 165 |   for(Role i=1; i<Role::count(); ++i) | 
|---|
| 166 |     if(right.test(i)) fprintf(f,"RIGHT\t%s\n",i.str()); | 
|---|
| 167 |  | 
|---|
| 168 |   for(Cat c=1; c<Cat::count(); ++c) | 
|---|
| 169 |     for(Role r=1; r<Role::count(); ++r) | 
|---|
| 170 |       if(obl[c].test(r)) fprintf(f,"REQ\t%s\t%s\n",c.str(),r.str()); | 
|---|
| 171 |    | 
|---|
| 172 |   for(Cat c=1; c<Cat::count(); ++c) | 
|---|
| 173 |     for(Cat d=1; d<Cat::count(); ++d) | 
|---|
| 174 |       for(Role t=1; t<Role::count(); ++t) | 
|---|
| 175 |         if(connect[c][d].count(t)) | 
|---|
| 176 |           fprintf(f,"LINK\t%s\t%s\t%s\n",c.str(),d.str(),t.str()); | 
|---|
| 177 |  | 
|---|
| 178 |   for(Flag i=1; i<Flag::count(); ++i) | 
|---|
| 179 |     fprintf(f,"FLAG\t%s\n",i.str()); | 
|---|
| 180 | } | 
|---|
| 181 |  | 
|---|