00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "config.h"
00028 #include <stdio.h>
00029 #include <stdlib.h>
00030 #include <string.h>
00031 #ifdef HAVE_SYS_WAIT_H
00032 # include <sys/wait.h>
00033 #endif
00034 #include <unistd.h>
00035
00036 #include "dic.h"
00037 #include "regexp.h"
00038 #include "automaton.h"
00039
00040 #ifndef PDBG
00041 #ifdef DEBUG_RE2
00042 #define PDBG(x) x
00043 #else
00044 #define PDBG(x)
00045 #endif
00046 #endif
00047
00048 NODE* regexp_createNODE(int type,char v,NODE *fg,NODE *fd)
00049 {
00050 NODE *x;
00051 x=(NODE *)malloc(sizeof(NODE));
00052 x->type = type;
00053 x->var = v;
00054 x->fd = fd;
00055 x->fg = fg;
00056 x->numero = 0;
00057 x->position = 0;
00058 x->annulable = 0;
00059 x->PP = 0;
00060 x->DP = 0;
00061 return x;
00062 }
00063
00064 void regexp_delete_tree(NODE *root)
00065 {
00066 if (root == NULL)
00067 return;
00068 regexp_delete_tree(root->fg);
00069 regexp_delete_tree(root->fd);
00070 free(root);
00071 }
00072
00073 #ifdef DEBUG_RE
00074 static void print_node(FILE*, NODE *n, int detail);
00075 #endif
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 void regexp_parcours(NODE* r, int *p, int *n, int ptl[])
00086 {
00087 if (r == NULL)
00088 return;
00089
00090 regexp_parcours(r->fg,p,n,ptl);
00091 regexp_parcours(r->fd,p,n,ptl);
00092
00093 switch (r->type)
00094 {
00095 case NODE_VAR:
00096 r->position = *p;
00097 ptl[*p] = r->var;
00098 *p = *p + 1;
00099 r->annulable = 0;
00100 r->PP = 1 << (r->position - 1);
00101 r->DP = 1 << (r->position - 1);
00102 break;
00103 case NODE_OR:
00104 r->position = 0;
00105 r->annulable = r->fg->annulable || r->fd->annulable;
00106 r->PP = r->fg->PP | r->fd->PP;
00107 r->DP = r->fg->DP | r->fd->DP;
00108 break;
00109 case NODE_AND:
00110 r->position = 0;
00111 r->annulable = r->fg->annulable && r->fd->annulable;
00112 r->PP = (r->fg->annulable) ? (r->fg->PP | r->fd->PP) : r->fg->PP;
00113 r->DP = (r->fd->annulable) ? (r->fg->DP | r->fd->DP) : r->fd->DP;
00114 break;
00115 case NODE_PLUS:
00116 r->position = 0;
00117 r->annulable = 0;
00118 r->PP = r->fg->PP;
00119 r->DP = r->fg->DP;
00120 break;
00121 case NODE_STAR:
00122 r->position = 0;
00123 r->annulable = 1;
00124 r->PP = r->fg->PP;
00125 r->DP = r->fg->DP;
00126 break;
00127 }
00128
00129 r->numero = *n;
00130 *n = *n + 1;
00131 }
00132
00133
00134
00135
00136
00137
00138
00139 void regexp_possuivante(NODE* r, int PS[])
00140 {
00141 int pos;
00142 if (r == NULL)
00143 return;
00144
00145 regexp_possuivante(r->fg,PS);
00146 regexp_possuivante(r->fd,PS);
00147
00148 switch (r->type)
00149 {
00150 case NODE_AND:
00151
00152
00153
00154
00155 for(pos=1; pos <= PS[0]; pos++)
00156 {
00157 if (r->fg->DP & (1 << (pos-1)))
00158 PS[pos] |= r->fd->PP;
00159 }
00160 break;
00161 case NODE_PLUS:
00162
00163
00164
00165
00166
00167 for(pos=1; pos <= PS[0]; pos++)
00168 {
00169 if (r->DP & (1 << (pos-1)))
00170 PS[pos] |= r->PP;
00171 }
00172 break;
00173 case NODE_STAR:
00174
00175
00176
00177
00178 for(pos=1; pos <= PS[0]; pos++)
00179 {
00180 if (r->DP & (1 << (pos-1)))
00181 PS[pos] |= r->PP;
00182 }
00183 break;
00184 }
00185 }
00186
00187
00188
00189
00190
00191 #ifdef DEBUG_RE
00192 void regexp_print_PS(int PS[])
00193 {
00194 int i;
00195 printf("** positions suivantes **\n");
00196 for(i=1; i <= PS[0]; i++)
00197 {
00198 printf("%02d: 0x%08x\n", i, PS[i]);
00199 }
00200 }
00201 #endif
00202
00203 /*////////////////////////////////////////////////
00204
00205
00206 #ifdef DEBUG_RE
00207 void regexp_print_ptl(int ptl[])
00208 {
00209 int i;
00210 printf("** pos -> lettre: ");
00211 for(i=1; i <= ptl[0]; i++)
00212 {
00213 printf("%d=%c ",i,ptl[i]);
00214 }
00215 printf("\n");
00216 }
00217 #endif
00218
00219 /*////////////////////////////////////////////////
00220
00221
00222 void regexp_print_letter(FILE* f, char l)
00223 {
00224 switch (l)
00225 {
00226 case RE_EPSILON: fprintf(f,"( & [%d])",l); break;
00227 case RE_FINAL_TOK: fprintf(f,"( # [%d])",l); break;
00228 case RE_ALL_MATCH: fprintf(f,"( . [%d])",l); break;
00229 case RE_VOWL_MATCH: fprintf(f,"(:v: [%d])",l); break;
00230 case RE_CONS_MATCH: fprintf(f,"(:c: [%d])",l); break;
00231 case RE_USR1_MATCH: fprintf(f,"(:1: [%d])",l); break;
00232 case RE_USR2_MATCH: fprintf(f,"(:2: [%d])",l); break;
00233 default:
00234 if (l < RE_FINAL_TOK)
00235 fprintf(f," (%c [%d]) ",l + 'a' - 1, l);
00236 else
00237 fprintf(f," (liste %d)",l - RE_LIST_USER_END);
00238 break;
00239 }
00240 }
00241
00242 /*////////////////////////////////////////////////
00243
00244
00245 void regexp_print_letter2(FILE* f, char l)
00246 {
00247 switch (l)
00248 {
00249 case RE_EPSILON: fprintf(f,"&"); break;
00250 case RE_FINAL_TOK: fprintf(f,"#"); break;
00251 case RE_ALL_MATCH: fprintf(f,"."); break;
00252 case RE_VOWL_MATCH: fprintf(f,":v:"); break;
00253 case RE_CONS_MATCH: fprintf(f,":c:"); break;
00254 case RE_USR1_MATCH: fprintf(f,":1:"); break;
00255 case RE_USR2_MATCH: fprintf(f,":2:"); break;
00256 default:
00257 if (l < RE_FINAL_TOK)
00258 fprintf(f,"%c",l + 'a' - 1);
00259 else
00260 fprintf(f,"l%d",l - RE_LIST_USER_END);
00261 break;
00262 }
00263 }
00264
00265 /*////////////////////////////////////////////////
00266
00267
00268 #ifdef DEBUG_RE
00269 static void print_node(FILE* f, NODE *n, int detail)
00270 {
00271 if (n == NULL)
00272 return;
00273
00274 switch (n->type)
00275 {
00276 case NODE_VAR:
00277 regexp_print_letter(f,n->var);
00278 break;
00279 case NODE_OR:
00280 fprintf(f,"OR");
00281 break;
00282 case NODE_AND:
00283 fprintf(f,"AND");
00284 break;
00285 case NODE_PLUS:
00286 fprintf(f,"+");
00287 break;
00288 case NODE_STAR:
00289 fprintf(f,"*");
00290 break;
00291 }
00292 if (detail == 2)
00293 {
00294 fprintf(f,"\\n pos=%d\\n annul=%d\\n PP=0x%04x\\n DP=0x%04x",
00295 n->position,n->annulable,n->PP,n->DP);
00296 }
00297 }
00298 #endif
00299
00300 /*////////////////////////////////////////////////
00301
00302
00303 #ifdef DEBUG_RE
00304 static void print_tree_nodes(FILE* f, NODE* n, int detail)
00305 {
00306 if (n == NULL)
00307 return;
00308
00309 print_tree_nodes(f,n->fg,detail);
00310 print_tree_nodes(f,n->fd,detail);
00311
00312 fprintf(f,"%d [ label=\"",n->numero);
00313 print_node(f,n,detail);
00314 fprintf(f,"\"];\n");
00315 }
00316 #endif
00317
00318 /*////////////////////////////////////////////////
00319
00320
00321 #ifdef DEBUG_RE
00322 static void print_tree_edges(FILE* f, NODE* n)
00323 {
00324 if (n == NULL)
00325 return;
00326
00327 print_tree_edges(f,n->fg);
00328 print_tree_edges(f,n->fd);
00329
00330 switch (n->type)
00331 {
00332 case NODE_OR:
00333 fprintf(f,"%d -> %d;",n->numero,n->fg->numero);
00334 fprintf(f,"%d -> %d;",n->numero,n->fd->numero);
00335 break;
00336 case NODE_AND:
00337 fprintf(f,"%d -> %d;",n->numero,n->fg->numero);
00338 fprintf(f,"%d -> %d;",n->numero,n->fd->numero);
00339 break;
00340 case NODE_PLUS:
00341 case NODE_STAR:
00342 fprintf(f,"%d -> %d;",n->numero,n->fg->numero);
00343 break;
00344 }
00345 }
00346 #endif
00347
00348 /*////////////////////////////////////////////////
00349
00350
00351 #ifdef DEBUG_RE
00352 void regexp_print_tree(NODE* n, char* name, int detail)
00353 {
00354 FILE* f;
00355 pid_t pid;
00356
00357 f=fopen(name,"w");
00358 fprintf(f,"digraph %s {\n",name);
00359 print_tree_nodes(f,n,detail);
00360 print_tree_edges(f,n);
00361 fprintf(f,"fontsize=20;\n");
00362 fprintf(f,"}\n");
00363 fclose(f);
00364
00365 #ifdef HAVE_SYS_WAIT_H
00366 pid = fork ();
00367 if (pid > 0) {
00368 wait(NULL);
00369 } else if (pid == 0) {
00370 execlp("dotty","dotty",name,NULL);
00371 printf("exec dotty failed\n");
00372 exit(1);
00373 }
00374 #endif
00375 }
00376 #endif
00377
00378
00379
00380
00381
00382