OLD | NEW |
1 /* | 1 /* |
2 ** Compile and run this standalone program in order to generate code that | 2 ** Compile and run this standalone program in order to generate code that |
3 ** implements a function that will translate alphabetic identifiers into | 3 ** implements a function that will translate alphabetic identifiers into |
4 ** parser token codes. | 4 ** parser token codes. |
5 */ | 5 */ |
6 #include <stdio.h> | 6 #include <stdio.h> |
7 #include <string.h> | 7 #include <string.h> |
8 #include <stdlib.h> | 8 #include <stdlib.h> |
9 #include <assert.h> | 9 #include <assert.h> |
10 | 10 |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
270 { "VIRTUAL", "TK_VIRTUAL", VTAB }, | 270 { "VIRTUAL", "TK_VIRTUAL", VTAB }, |
271 { "WITH", "TK_WITH", CTE }, | 271 { "WITH", "TK_WITH", CTE }, |
272 { "WITHOUT", "TK_WITHOUT", ALWAYS }, | 272 { "WITHOUT", "TK_WITHOUT", ALWAYS }, |
273 { "WHEN", "TK_WHEN", ALWAYS }, | 273 { "WHEN", "TK_WHEN", ALWAYS }, |
274 { "WHERE", "TK_WHERE", ALWAYS }, | 274 { "WHERE", "TK_WHERE", ALWAYS }, |
275 }; | 275 }; |
276 | 276 |
277 /* Number of keywords */ | 277 /* Number of keywords */ |
278 static int nKeyword = (sizeof(aKeywordTable)/sizeof(aKeywordTable[0])); | 278 static int nKeyword = (sizeof(aKeywordTable)/sizeof(aKeywordTable[0])); |
279 | 279 |
280 /* An array to map all upper-case characters into their corresponding | 280 /* Map all alphabetic characters into the same case */ |
281 ** lower-case character. | 281 #define charMap(X) (0x20|(X)) |
282 */ | |
283 const unsigned char sqlite3UpperToLower[] = { | |
284 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, | |
285 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, | |
286 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, | |
287 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99,100,101,102,103, | |
288 104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121, | |
289 122, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104,105,106,107, | |
290 108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125, | |
291 126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, | |
292 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161, | |
293 162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179, | |
294 180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197, | |
295 198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215, | |
296 216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233, | |
297 234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251, | |
298 252,253,254,255 | |
299 }; | |
300 #define UpperToLower sqlite3UpperToLower | |
301 | 282 |
302 /* | 283 /* |
303 ** Comparision function for two Keyword records | 284 ** Comparision function for two Keyword records |
304 */ | 285 */ |
305 static int keywordCompare1(const void *a, const void *b){ | 286 static int keywordCompare1(const void *a, const void *b){ |
306 const Keyword *pA = (Keyword*)a; | 287 const Keyword *pA = (Keyword*)a; |
307 const Keyword *pB = (Keyword*)b; | 288 const Keyword *pB = (Keyword*)b; |
308 int n = pA->len - pB->len; | 289 int n = pA->len - pB->len; |
309 if( n==0 ){ | 290 if( n==0 ){ |
310 n = strcmp(pA->zName, pB->zName); | 291 n = strcmp(pA->zName, pB->zName); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
365 } | 346 } |
366 nKeyword = j; | 347 nKeyword = j; |
367 | 348 |
368 /* Fill in the lengths of strings and hashes for all entries. */ | 349 /* Fill in the lengths of strings and hashes for all entries. */ |
369 for(i=0; i<nKeyword; i++){ | 350 for(i=0; i<nKeyword; i++){ |
370 Keyword *p = &aKeywordTable[i]; | 351 Keyword *p = &aKeywordTable[i]; |
371 p->len = (int)strlen(p->zName); | 352 p->len = (int)strlen(p->zName); |
372 assert( p->len<sizeof(p->zOrigName) ); | 353 assert( p->len<sizeof(p->zOrigName) ); |
373 memcpy(p->zOrigName, p->zName, p->len+1); | 354 memcpy(p->zOrigName, p->zName, p->len+1); |
374 totalLen += p->len; | 355 totalLen += p->len; |
375 p->hash = (UpperToLower[(int)p->zName[0]]*4) ^ | 356 p->hash = (charMap(p->zName[0])*4) ^ |
376 (UpperToLower[(int)p->zName[p->len-1]]*3) ^ p->len; | 357 (charMap(p->zName[p->len-1])*3) ^ (p->len*1); |
377 p->id = i+1; | 358 p->id = i+1; |
378 } | 359 } |
379 | 360 |
380 /* Sort the table from shortest to longest keyword */ | 361 /* Sort the table from shortest to longest keyword */ |
381 qsort(aKeywordTable, nKeyword, sizeof(aKeywordTable[0]), keywordCompare1); | 362 qsort(aKeywordTable, nKeyword, sizeof(aKeywordTable[0]), keywordCompare1); |
382 | 363 |
383 /* Look for short keywords embedded in longer keywords */ | 364 /* Look for short keywords embedded in longer keywords */ |
384 for(i=nKeyword-2; i>=0; i--){ | 365 for(i=nKeyword-2; i>=0; i--){ |
385 Keyword *p = &aKeywordTable[i]; | 366 Keyword *p = &aKeywordTable[i]; |
386 for(j=nKeyword-1; j>i && p->substrId==0; j--){ | 367 for(j=nKeyword-1; j>i && p->substrId==0; j--){ |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
474 for(i=0; i<bestSize; i++) aHash[i] = 0; | 455 for(i=0; i<bestSize; i++) aHash[i] = 0; |
475 for(i=0; i<nKeyword; i++){ | 456 for(i=0; i<nKeyword; i++){ |
476 h = aKeywordTable[i].hash % bestSize; | 457 h = aKeywordTable[i].hash % bestSize; |
477 aKeywordTable[i].iNext = aHash[h]; | 458 aKeywordTable[i].iNext = aHash[h]; |
478 aHash[h] = i+1; | 459 aHash[h] = i+1; |
479 } | 460 } |
480 | 461 |
481 /* Begin generating code */ | 462 /* Begin generating code */ |
482 printf("%s", zHdr); | 463 printf("%s", zHdr); |
483 printf("/* Hash score: %d */\n", bestCount); | 464 printf("/* Hash score: %d */\n", bestCount); |
484 printf("static int keywordCode(const char *z, int n){\n"); | 465 printf("static int keywordCode(const char *z, int n, int *pType){\n"); |
485 printf(" /* zText[] encodes %d bytes of keywords in %d bytes */\n", | 466 printf(" /* zText[] encodes %d bytes of keywords in %d bytes */\n", |
486 totalLen + nKeyword, nChar+1 ); | 467 totalLen + nKeyword, nChar+1 ); |
487 for(i=j=k=0; i<nKeyword; i++){ | 468 for(i=j=k=0; i<nKeyword; i++){ |
488 Keyword *p = &aKeywordTable[i]; | 469 Keyword *p = &aKeywordTable[i]; |
489 if( p->substrId ) continue; | 470 if( p->substrId ) continue; |
490 memcpy(&zText[k], p->zName, p->len); | 471 memcpy(&zText[k], p->zName, p->len); |
491 k += p->len; | 472 k += p->len; |
492 if( j+p->len>70 ){ | 473 if( j+p->len>70 ){ |
493 printf("%*s */\n", 74-j, ""); | 474 printf("%*s */\n", 74-j, ""); |
494 j = 0; | 475 j = 0; |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
578 printf("%s,%*s", zToken, (int)(14-strlen(zToken)), ""); | 559 printf("%s,%*s", zToken, (int)(14-strlen(zToken)), ""); |
579 j++; | 560 j++; |
580 if( j>=5 ){ | 561 if( j>=5 ){ |
581 printf("\n"); | 562 printf("\n"); |
582 j = 0; | 563 j = 0; |
583 } | 564 } |
584 } | 565 } |
585 printf("%s };\n", j==0 ? "" : "\n"); | 566 printf("%s };\n", j==0 ? "" : "\n"); |
586 | 567 |
587 printf(" int h, i;\n"); | 568 printf(" int h, i;\n"); |
588 printf(" if( n<2 ) return TK_ID;\n"); | 569 printf(" if( n>=2 ){\n"); |
589 printf(" h = ((charMap(z[0])*4) ^\n" | 570 printf(" h = ((charMap(z[0])*4) ^ (charMap(z[n-1])*3) ^ n) %% %d;\n", |
590 " (charMap(z[n-1])*3) ^\n" | 571 bestSize); |
591 " n) %% %d;\n", bestSize); | 572 printf(" for(i=((int)aHash[h])-1; i>=0; i=((int)aNext[i])-1){\n"); |
592 printf(" for(i=((int)aHash[h])-1; i>=0; i=((int)aNext[i])-1){\n"); | 573 printf(" if( aLen[i]==n &&" |
593 printf(" if( aLen[i]==n &&" | 574 " sqlite3StrNICmp(&zText[aOffset[i]],z,n)==0 ){\n"); |
594 " sqlite3StrNICmp(&zText[aOffset[i]],z,n)==0 ){\n"); | |
595 for(i=0; i<nKeyword; i++){ | 575 for(i=0; i<nKeyword; i++){ |
596 printf(" testcase( i==%d ); /* %s */\n", | 576 printf(" testcase( i==%d ); /* %s */\n", |
597 i, aKeywordTable[i].zOrigName); | 577 i, aKeywordTable[i].zOrigName); |
598 } | 578 } |
599 printf(" return aCode[i];\n"); | 579 printf(" *pType = aCode[i];\n"); |
| 580 printf(" break;\n"); |
| 581 printf(" }\n"); |
600 printf(" }\n"); | 582 printf(" }\n"); |
601 printf(" }\n"); | 583 printf(" }\n"); |
602 printf(" return TK_ID;\n"); | 584 printf(" return n;\n"); |
603 printf("}\n"); | 585 printf("}\n"); |
604 printf("int sqlite3KeywordCode(const unsigned char *z, int n){\n"); | 586 printf("int sqlite3KeywordCode(const unsigned char *z, int n){\n"); |
605 printf(" return keywordCode((char*)z, n);\n"); | 587 printf(" int id = TK_ID;\n"); |
| 588 printf(" keywordCode((char*)z, n, &id);\n"); |
| 589 printf(" return id;\n"); |
606 printf("}\n"); | 590 printf("}\n"); |
607 printf("#define SQLITE_N_KEYWORD %d\n", nKeyword); | 591 printf("#define SQLITE_N_KEYWORD %d\n", nKeyword); |
608 | 592 |
609 return 0; | 593 return 0; |
610 } | 594 } |
OLD | NEW |