| 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 |