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 <ctype.h>
00028 #include <stdlib.h>
00029 #include <string.h>
00030
00031 #include "dic_internals.h"
00032 #include "dic.h"
00033 #include "regexp.h"
00034 #include "dic_search.h"
00035 #include "libdic_a-er.h"
00036 #include "scanner.h"
00037 #include "automaton.h"
00038
00039
00040
00041
00042 static int yy_init_globals (yyscan_t yyscanner )
00043 {
00044 yy_init_globals(yyscanner);
00045 return 0;
00046 }
00047
00048
00049
00050
00051
00052
00053
00054
00055 static Dawg_edge*
00056 Dic_seek_edgeptr(const Dictionary dic, const char* s, Dawg_edge *eptr)
00057 {
00058 if (*s)
00059 {
00060 Dawg_edge *p = dic->dawg + eptr->ptr;
00061 do {
00062 if (p->chr == (unsigned)(*s & DIC_CHAR_MASK))
00063 return Dic_seek_edgeptr (dic,s + 1, p);
00064 } while (!(*p++).last);
00065 return dic->dawg;
00066 }
00067 else
00068 return eptr;
00069 }
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 int
00080 Dic_search_word(const Dictionary dic, const char* word)
00081 {
00082 Dawg_edge *e;
00083 e = Dic_seek_edgeptr(dic,word,dic->dawg + dic->root);
00084 return e->term;
00085 }
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 struct params_7plus1_t {
00098 Dictionary search_dic;
00099 int search_len;
00100 int search_wordlistlen;
00101 int search_wordlistlenmax;
00102 char search_wordtst[DIC_WORD_MAX];
00103 char search_letters[DIC_LETTERS];
00104 char (*search_wordlist)[RES_7PL1_MAX][DIC_WORD_MAX];
00105 };
00106
00107 static void
00108 Dic_search_word_by_len(struct params_7plus1_t *params, int i, Dawg_edge *edgeptr)
00109 {
00110
00111 do {
00112
00113
00114 if (params->search_wordlistlen >= params->search_wordlistlenmax)
00115 break;
00116
00117
00118 if (edgeptr->chr)
00119 {
00120
00121
00122 if (params->search_letters[edgeptr->chr])
00123 {
00124 params->search_wordtst[i] = edgeptr->chr + 'A' - 1;
00125 params->search_letters[edgeptr->chr] --;
00126 if (i == params->search_len)
00127 {
00128 if ((edgeptr->term)
00129 )
00130 strcpy((*params->search_wordlist)[params->search_wordlistlen++],params->search_wordtst);
00131 }
00132 else
00133 {
00134 Dic_search_word_by_len(params,i + 1, params->search_dic->dawg + edgeptr->ptr);
00135 }
00136 params->search_letters[edgeptr->chr] ++;
00137 params->search_wordtst[i] = '\0';
00138 }
00139
00140
00141 if (params->search_letters[0])
00142 {
00143 params->search_wordtst[i] = edgeptr->chr + 'a' - 1;
00144 params->search_letters[0] --;
00145 if (i == params->search_len)
00146 {
00147 if ((edgeptr->term)
00148 )
00149 strcpy((*(params->search_wordlist))[params->search_wordlistlen++],params->search_wordtst);
00150 }
00151 else
00152 {
00153 Dic_search_word_by_len(params,i + 1,params->search_dic->dawg + edgeptr->ptr);
00154 }
00155 params->search_letters[0] ++;
00156 params->search_wordtst[i] = '\0';
00157 }
00158 }
00159 } while (! (*edgeptr++).last);
00160 }
00161
00162 void
00163 Dic_search_7pl1(const Dictionary dic, const char* rack,
00164 char buff[DIC_LETTERS][RES_7PL1_MAX][DIC_WORD_MAX],
00165 int joker)
00166 {
00167 int i,j,wordlen;
00168 const char* r = rack;
00169 struct params_7plus1_t params;
00170 Dawg_edge *root_edge;
00171
00172 for(i=0; i < DIC_LETTERS; i++)
00173 for(j=0; j < RES_7PL1_MAX; j++)
00174 buff[i][j][0] = '\0';
00175
00176 for(i=0; i<DIC_LETTERS; i++)
00177 params.search_letters[i] = 0;
00178
00179 if (dic == NULL || rack == NULL)
00180 return;
00181
00182
00183
00184
00185
00186 for(wordlen=0; wordlen < DIC_WORD_MAX && *r; r++)
00187 {
00188 if (isalpha(*r))
00189 {
00190 params.search_letters[(int)*r & DIC_CHAR_MASK]++;
00191 wordlen++;
00192 }
00193 else if (*r == '?')
00194 {
00195 if (joker)
00196 {
00197 params.search_letters[0]++;
00198 wordlen++;
00199 }
00200 else
00201 {
00202 strncpy(buff[0][0],"** joker **",DIC_WORD_MAX);
00203 return;
00204 }
00205 }
00206 }
00207
00208 if (wordlen < 1)
00209 return;
00210
00211 root_edge = dic->dawg + (dic->dawg[dic->root].ptr);
00212
00213 params.search_dic = dic;
00214 params.search_wordlistlenmax = RES_7PL1_MAX;
00215
00216
00217 params.search_len = wordlen - 1;
00218 params.search_wordtst[wordlen]='\0';
00219 params.search_wordlist = & buff[0];
00220 params.search_wordlistlen = 0;
00221 Dic_search_word_by_len(¶ms,0,root_edge);
00222
00223
00224 params.search_len = wordlen;
00225 params.search_wordtst[wordlen + 1]='\0';
00226 for(i='a'; i <= 'z'; i++)
00227 {
00228 params.search_letters[i & DIC_CHAR_MASK]++;
00229
00230 params.search_wordlist = & buff[i & DIC_CHAR_MASK];
00231 params.search_wordlistlen = 0;
00232 Dic_search_word_by_len(¶ms,0,root_edge);
00233
00234 params.search_letters[i & DIC_CHAR_MASK]--;
00235 }
00236 }
00237
00238
00239
00240
00241 void
00242 Dic_search_Racc(const Dictionary dic, const char* word,
00243 char wordlist[RES_RACC_MAX][DIC_WORD_MAX])
00244 {
00245
00246
00247 int i,wordlistlen;
00248 Dawg_edge *edge;
00249 char wordtst[DIC_WORD_MAX];
00250
00251 for(i=0; i < RES_RACC_MAX; i++)
00252 wordlist[i][0] = 0;
00253
00254 if (dic == NULL || wordlist == NULL)
00255 return;
00256
00257
00258 wordlistlen = 0;
00259 strcpy(wordtst+1,word);
00260 for(i='a'; i <= 'z'; i++)
00261 {
00262 wordtst[0] = i;
00263 if (Dic_search_word(dic,wordtst) && wordlistlen < RES_RACC_MAX)
00264 strcpy(wordlist[wordlistlen++],wordtst);
00265 }
00266
00267
00268 for(i=0; word[i]; i++)
00269 wordtst[i] = word[i];
00270
00271 wordtst[i ] = '\0';
00272 wordtst[i+1] = '\0';
00273
00274 edge = Dic_seek_edgeptr(dic,word,dic->dawg + dic->root);
00275
00276
00277 edge = dic->dawg + edge->ptr;
00278
00279 if (edge != dic->dawg)
00280 {
00281 do {
00282 if (edge->term && wordlistlen < RES_RACC_MAX)
00283 {
00284 wordtst[i] = edge->chr + 'a' - 1;
00285 strcpy(wordlist[wordlistlen++],wordtst);
00286 }
00287 } while (!(*edge++).last);
00288 }
00289 }
00290
00291
00292
00293
00294
00295 void
00296 Dic_search_Benj(const Dictionary dic, const char* word,
00297 char wordlist[RES_BENJ_MAX][DIC_WORD_MAX])
00298 {
00299 int i,wordlistlen;
00300 char wordtst[DIC_WORD_MAX];
00301 Dawg_edge *edge0,*edge1,*edge2,*edgetst;
00302
00303 for(i=0; i < RES_BENJ_MAX; i++)
00304 wordlist[i][0] = 0;
00305
00306 if (dic == NULL || word == NULL)
00307 return;
00308
00309 wordlistlen = 0;
00310
00311 strcpy(wordtst+3,word);
00312 edge0 = dic->dawg + (dic->dawg[dic->root].ptr);
00313 do {
00314 wordtst[0] = edge0->chr + 'a' - 1;
00315 edge1 = dic->dawg + edge0->ptr;
00316 do {
00317 wordtst[1] = edge1->chr + 'a' - 1;
00318 edge2 = dic->dawg + edge1->ptr;
00319 do {
00320 wordtst[2] = edge2->chr + 'a' - 1;
00321 edgetst = Dic_seek_edgeptr(dic,word,edge2);
00322 if (edgetst->term && wordlistlen < RES_BENJ_MAX)
00323 strcpy(wordlist[wordlistlen++],wordtst);
00324 } while (!(*edge2++).last);
00325 } while (!(*edge1++).last);
00326 } while (!(*edge0++).last);
00327 }
00328
00329
00330
00331
00332
00333 struct params_cross_t {
00334 Dictionary dic;
00335 int wordlen;
00336 int wordlistlen;
00337 int wordlistlenmax;
00338 char mask[DIC_WORD_MAX];
00339 };
00340
00341
00342 void
00343 Dic_search_cross_rec(struct params_cross_t *params,
00344 char wordlist[RES_CROS_MAX][DIC_WORD_MAX],
00345 Dawg_edge *edgeptr)
00346 {
00347 Dawg_edge *current = params->dic->dawg + edgeptr->ptr;
00348
00349 if (params->mask[params->wordlen] == '\0' && edgeptr->term)
00350 {
00351 if (params->wordlistlen < params->wordlistlenmax)
00352 strcpy(wordlist[params->wordlistlen++],params->mask);
00353 }
00354 else if (params->mask[params->wordlen] == '.')
00355 {
00356 do
00357 {
00358 params->mask[params->wordlen] = current->chr + 'a' - 1;
00359 params->wordlen ++;
00360 Dic_search_cross_rec(params,wordlist,current);
00361 params->wordlen --;
00362 params->mask[params->wordlen] = '.';
00363 }
00364 while (!(*current++).last);
00365 }
00366 else
00367 {
00368 do
00369 {
00370 if (current->chr == (unsigned int)(params->mask[params->wordlen] & DIC_CHAR_MASK))
00371 {
00372 params->wordlen ++;
00373 Dic_search_cross_rec(params,wordlist,current);
00374 params->wordlen --;
00375 break;
00376 }
00377 }
00378 while (!(*current++).last);
00379 }
00380 }
00381
00382
00383
00384 void
00385 Dic_search_Cros(const Dictionary dic, const char* mask,
00386 char wordlist[RES_CROS_MAX][DIC_WORD_MAX])
00387 {
00388 int i;
00389 struct params_cross_t params;
00390
00391 for(i=0; i < RES_CROS_MAX; i++)
00392 wordlist[i][0] = 0;
00393
00394 if (dic == NULL || mask == NULL)
00395 return;
00396
00397 for(i=0; i < DIC_WORD_MAX && mask[i]; i++)
00398 {
00399 if (isalpha(mask[i]))
00400 params.mask[i] = (mask[i] & DIC_CHAR_MASK) + 'A' - 1;
00401 else
00402 params.mask[i] = '.';
00403 }
00404 params.mask[i] = '\0';
00405
00406 params.dic = dic;
00407 params.wordlen = 0;
00408 params.wordlistlen = 0;
00409 params.wordlistlenmax = RES_CROS_MAX;
00410 Dic_search_cross_rec(¶ms, wordlist, dic->dawg + dic->root);
00411 }
00412
00413
00414
00415
00416 struct params_regexp_t {
00417 Dictionary dic;
00418 int minlength;
00419 int maxlength;
00420 automaton automaton;
00421 struct search_RegE_list_t *charlist;
00422 char word[DIC_WORD_MAX];
00423 int wordlen;
00424 int wordlistlen;
00425 int wordlistlenmax;
00426 };
00427
00428 void
00429 Dic_search_regexp_rec(struct params_regexp_t *params,
00430 int state,
00431 Dawg_edge *edgeptr,
00432 char wordlist[RES_REGE_MAX][DIC_WORD_MAX])
00433 {
00434 int next_state;
00435 Dawg_edge *current;
00436
00437 if (automaton_get_accept(params->automaton,state) && edgeptr->term)
00438 {
00439 int l = strlen(params->word);
00440 if (params->wordlistlen < params->wordlistlenmax &&
00441 params->minlength <= l &&
00442 params->maxlength >= l)
00443 {
00444 strcpy(wordlist[params->wordlistlen++],params->word);
00445 }
00446 }
00447
00448 current = params->dic->dawg + edgeptr->ptr;
00449 do {
00450
00451 next_state = automaton_get_next_state(params->automaton,state,current->chr);
00452
00453 if (next_state)
00454 {
00455 params->word[params->wordlen] = current->chr + 'a' - 1;
00456 params->wordlen ++;
00457 Dic_search_regexp_rec(params,next_state,current,wordlist);
00458 params->wordlen --;
00459 params->word[params->wordlen] = '\0';
00460 }
00461 } while (!(*current++).last);
00462 }
00463
00464
00465
00466
00467
00468 int regexpparse(yyscan_t scanner, NODE** root,
00469 struct search_RegE_list_t *list,
00470 struct regexp_error_report_t *err);
00471
00472 void
00473 Dic_search_RegE(const Dictionary dic, const char* re,
00474 char wordlist[RES_REGE_MAX][DIC_WORD_MAX],
00475 struct search_RegE_list_t *list)
00476 {
00477 int i,p,n,value;
00478 int ptl[REGEXP_MAX+1];
00479 int PS [REGEXP_MAX+1];
00480 NODE* root;
00481 yyscan_t scanner;
00482 YY_BUFFER_STATE buf;
00483 automaton a;
00484 char stringbuf[250];
00485 struct params_regexp_t params;
00486 struct regexp_error_report_t report;
00487
00488
00489 for(i=0; i < RES_REGE_MAX; i++)
00490 wordlist[i][0] = 0;
00491
00492 if (dic == NULL || re == NULL)
00493 return;
00494
00495
00496 sprintf(stringbuf,"(%s)#",re);
00497 for(i=0; i < REGEXP_MAX; i++)
00498 {
00499 PS[i] = 0;
00500 ptl[i] = 0;
00501 }
00502
00503 report.pos1 = 0;
00504 report.pos2 = 0;
00505 report.msg[0] = '\0';
00506
00507
00508 regexplex_init( &scanner );
00509 buf = regexp_scan_string( stringbuf, scanner );
00510 root = NULL;
00511 value = regexpparse( scanner , &root, list, &report);
00512 regexp_delete_buffer(buf,scanner);
00513 regexplex_destroy( scanner );
00514
00515 if (value)
00516 {
00517 #ifdef DEBUG_FLEX_IS_BROKEN
00518 fprintf(stderr,"parser error at pos %d - %d : %s\n",
00519 report.pos1, report.pos2, report.msg);
00520 #endif
00521 regexp_delete_tree(root);
00522 return ;
00523 }
00524
00525 n = 1;
00526 p = 1;
00527 regexp_parcours(root, &p, &n, ptl);
00528 PS [0] = p - 1;
00529 ptl[0] = p - 1;
00530
00531 regexp_possuivante(root,PS);
00532
00533 if ((a = automaton_build(root->PP,ptl,PS,list)) != NULL)
00534 {
00535 params.dic = dic;
00536 params.minlength = list->minlength;
00537 params.maxlength = list->maxlength;
00538 params.automaton = a;
00539 params.charlist = list;
00540 memset(params.word,'\0',sizeof(params.word));
00541 params.wordlen = 0;
00542 params.wordlistlen = 0;
00543 params.wordlistlenmax = RES_REGE_MAX;
00544 Dic_search_regexp_rec(¶ms, automaton_get_init(a), dic->dawg + dic->root, wordlist);
00545
00546 automaton_delete(a);
00547 }
00548 regexp_delete_tree(root);
00549 }
00550
00551
00552
00553