001// lexical analyzer for GSQLParser component java version 002 003/**************************************************** 004 Lexical analizer for GSQLParser Java component 005 Copyright (c) 2004-2024 by Gudu software 006****************************************************/ 007 008package gudusoft.gsqlparser; 009 010import java.util.HashMap; 011import java.io.InputStreamReader; 012 013import java.util.Locale; 014import java.io.BufferedReader; 015import java.io.IOException; 016 017 018public class TLexerSnowflake extends TCustomLexer{ 019 static int yynmarks = 0 ; 020 static int yynmatches ; 021 static int yyntrans ; 022 static int yynstates ; 023 static int[] yyk,yym ; // 1 based 024 static int[] yytint; // 1 based 025 static TYytRec[] yyt ; // 1 based 026 static int[] yykl,yykh,yyml,yymh,yytl,yyth ; // 0 based 027 private static String[] keywordlist; 028 static String table_file; 029 static HashMap<String, Integer> keywordValueList; 030 static HashMap<Integer, Integer> keywordTypeList; 031 static int[][] yystateTable; 032 033 static { 034 keywordValueList = new HashMap<String, Integer>(); 035 keywordTypeList = new HashMap<Integer, Integer>(); 036 table_file = "/gudusoft/gsqlparser/parser/snowflake/snowflake_lex_table.txt"; 037 if (TBaseType.enterprise_edition||TBaseType.snowflake_edition){ 038 inittable(); 039 } 040 } 041 042 public TLexerSnowflake(){ 043 super(); 044 dbvendor = EDbVendor.dbvsnowflake; 045 } 046 047public boolean canBeColumnName(int tokencode){ 048 //http://blog.csdn.net/superbeck/article/details/5387476 049 boolean ret = false; 050 int modifiers = keyword_type_identifier | keyword_type_column ; 051 Integer s = keywordTypeList.get(tokencode); 052 if (s != null){ 053 int modifier = s; 054 ret = (modifiers & modifier) == modifier; 055 } 056 057 return ret; 058} 059 060 public int iskeyword(String str){ 061 int ret = -1; 062 Integer s = keywordValueList.get(str.toUpperCase(Locale.ENGLISH)); 063 if( s != null){ 064 ret = s; 065 } 066 return ret;// -1 means not a keyword 067 } 068 069 public int getkeywordvalue(String keyword){ 070 int ret = 0; 071 Integer s = keywordValueList.get(keyword.toUpperCase(Locale.ENGLISH)); 072 if( s != null){ 073 ret = s; 074 } 075 return ret;// 0 means not a keyword 076 } 077 078 public static EKeywordType getKeywordType(String keyword){ 079 return TCustomLexer.getKeywordType(keyword,keywordValueList,keywordTypeList); 080 } 081 082 static void yystateLookupConfigure() { 083 int yystates = yytl.length; 084 yystateTable = new int[257][yystates]; 085 086 // initialize to empty 087 for(int i = 0; i < yystates; i++) { 088 for (int j = 0; j < 257; j++) 089 yystateTable[j][i] = -1; 090 } 091 092 for(int i = 0; i < yystates; i++) { 093 int low = yytl[i]; 094 int high = yyth[i]; 095 for (int j = low; j <= high; j++) { 096 for (char c: yyt[j].cc) { 097 yystateTable[c][i] = j; 098 } 099 } 100 } 101 } 102 103 int yylex(){ 104 int yyn; 105 while (true) { // top level while 106 yynew(); 107 while (true){ //scan 108 for(yyn = yykl[yystate]; yyn <= yykh[yystate]; yyn++){ 109 yymark(yyk[yyn]); 110 } 111 112 for(yyn=yymh[yystate]; yyn>= yyml[yystate]; yyn--){ 113 yymatch(yym[yyn]); 114 } 115 116 if(yytl[yystate] > yyth[yystate]){ 117 break; 118 } 119 120 yyscan(); 121// yyn = yytl[yystate]; 122 totablechar(); 123// while( (yyn <= yyth[yystate]) && (!(charinarray(yytablechar,yyt[yyn].cc))) ){ 124// yyn++; 125// } 126// if (yyn > yyth[yystate]){ 127// break; 128// } 129 130 yyn = yystateTable[yytablechar][yystate]; 131 if (yyn == -1) 132 break; 133 134 yystate = yyt[yyn].s; 135 } //scan 136 137 while (true){ //action 138 int yyrule; 139 if ( (yyrule = yyfind()) != -1 ){ 140 yyaction(yyrule); 141 if (yyreject){ 142 continue; 143 } 144 }else if( (!yydefault() ) && (yywrap()) ){ 145 yyclear(); 146 returni(0); 147 } 148 break; 149 } 150 151 if (!yydone) { 152 continue; 153 } 154 break; 155 } // top level while 156 157 return yyretval; 158 } 159 160 static void inittable(){ 161 162 //if (yynmarks > 0) return; //init table already 163 164 String line; 165 boolean inyyk=false,inyym=false,inyykl=false,inyykh=false,inyyml=false,inyymh=false,inyytl=false,inyyth=false,inyytint=false,inyyt=false,inkeyword=false; 166 int yyk_count=0,yym_count=0,yykl_count=0,yykh_count=0,yyml_count=0,yymh_count=0,yytl_count=0,yyth_count=0,yytint_count=0,yyt_count=0; 167 int c=0; 168 keywordValueList.clear(); 169 keywordTypeList.clear(); 170 171 BufferedReader br = new BufferedReader(new InputStreamReader(TLexerSnowflake.class.getResourceAsStream(table_file))); 172 173 try{ 174 while( (line = br.readLine()) != null){ 175 if (line.trim().startsWith("yynmarks=")){ 176 String[] ss = line.split("[=;]"); 177 yynmarks=Integer.parseInt(ss[1].trim()); 178 yyk = new int[yynmarks+1]; 179 }else if (line.trim().startsWith("yynmatches=")){ 180 String[] ss = line.split("[=;]"); 181 yynmatches=Integer.parseInt(ss[1].trim()); 182 yym = new int[yynmatches+1]; 183 }else if (line.trim().startsWith("yyntrans=")){ 184 String[] ss = line.split("[=;]"); 185 yyntrans=Integer.parseInt(ss[1].trim()); 186 yytint = new int[yyntrans+1]; 187 yyt = new TYytRec[yyntrans+1]; 188 }else if (line.trim().startsWith("yynstates=")){ 189 String[] ss = line.split("[=;]"); 190 yynstates=Integer.parseInt(ss[1].trim()); 191 yykl = new int[yynstates]; 192 yykh = new int[yynstates]; 193 yyml = new int[yynstates]; 194 yymh = new int[yynstates]; 195 yytl = new int[yynstates]; 196 yyth = new int[yynstates]; 197 }else if (line.trim().startsWith("<end>")){ 198 if (inyyk){ 199 inyyk = false; 200 if (yynmarks+1 != yyk_count ){ 201 System.out.println("required1:"+(yynmarks)+" actually:"+(yyk_count-1)); 202 } 203 } 204 else if(inyym){ 205 inyym = false; 206 if (yynmatches+1 != yym_count ){ 207 System.out.println("required2:"+(yynmatches)+" actually:"+(yym_count-1)); 208 } 209 } 210 else if(inyykl){ 211 inyykl = false; 212 if (yynstates != yykl_count ){ 213 System.out.println("required3:"+(yynstates)+" actually:"+(yykl_count)); 214 } 215 } 216 else if(inyykh){ 217 inyykh = false; 218 if (yynstates != yykh_count ){ 219 System.out.println("required4:"+(yynstates)+" actually:"+(yykh_count)); 220 } 221 } 222 else if(inyyml){ 223 inyyml = false; 224 if (yynstates != yyml_count ){ 225 System.out.println("required5:"+(yynstates)+" actually:"+(yyml_count)); 226 } 227 } 228 else if(inyymh){ 229 inyymh = false; 230 if (yynstates != yymh_count ){ 231 System.out.println("required:"+(yynstates)+" actually:"+(yymh_count)); 232 } 233 } 234 else if(inyytl){ 235 inyytl = false; 236 if (yynstates != yytl_count ){ 237 System.out.println("required6:"+(yynstates)+" actually:"+(yytl_count)); 238 } 239 } 240 else if(inyyth){ 241 inyyth = false; 242 if (yynstates != yyth_count ){ 243 System.out.println("required7:"+(yynstates)+" actually:"+(yyth_count)); 244 } 245 } 246 else if(inyytint){ 247 inyytint = false; 248 if (yyntrans + 1 != yytint_count ){ 249 System.out.println("required8:"+(yyntrans)+" actually:"+(yytint_count-1)); 250 } 251 } 252 else if(inyyt){ 253 inyyt = false; 254 if (yyntrans+1 != yyt_count ){ 255 System.out.println("required9:"+(yyntrans)+" actually:"+(yyt_count-1)); 256 } 257 } 258 else if(inkeyword){ 259 inkeyword = false; 260 } 261 }else if(line.trim().startsWith("yyk =")){ 262 inyyk = true; 263 }else if(line.trim().startsWith("yym =")){ 264 inyym = true; 265 }else if(line.trim().startsWith("yykl =")){ 266 inyykl = true; 267 }else if(line.trim().startsWith("yykh =")){ 268 inyykh = true; 269 }else if(line.trim().startsWith("yyml =")){ 270 inyyml = true; 271 }else if(line.trim().startsWith("yymh =")){ 272 inyymh = true; 273 }else if(line.trim().startsWith("yytl =")){ 274 inyytl = true; 275 }else if(line.trim().startsWith("yyth =")){ 276 inyyth = true; 277 }else if(line.trim().startsWith("yytint =")){ 278 inyytint = true; 279 }else if(line.trim().startsWith("yyt =")){ 280 inyyt = true; 281 }else if(line.trim().startsWith("keywordsvalue =")){ 282 inkeyword = true; 283 }else if(inyyk){ 284 String[] ss = line.split("[,]"); 285 for(int j=0;j<ss.length;j++){ 286 // System.out.println(ss[j].trim()); 287 yyk[yyk_count++] = Integer.parseInt(ss[j].trim()); 288 } 289 }else if(inyym){ 290 String[] ss = line.split("[,]"); 291 for(int j=0;j<ss.length;j++){ 292 // System.out.println(ss[j].trim()); 293 yym[yym_count++] = Integer.parseInt(ss[j].trim()); 294 } 295 }else if(inyykl){ 296 String[] ss = line.split("[,]"); 297 for(int j=0;j<ss.length;j++){ 298 // System.out.println(ss[j].trim()); 299 yykl[yykl_count++] = Integer.parseInt(ss[j].trim()); 300 } 301 }else if(inyykh){ 302 String[] ss = line.split("[,]"); 303 for(int j=0;j<ss.length;j++){ 304 // System.out.println(ss[j].trim()); 305 yykh[yykh_count++] = Integer.parseInt(ss[j].trim()); 306 } 307 }else if(inyyml){ 308 String[] ss = line.split("[,]"); 309 for(int j=0;j<ss.length;j++){ 310 // System.out.println(ss[j].trim()); 311 yyml[yyml_count++] = Integer.parseInt(ss[j].trim()); 312 } 313 }else if(inyymh){ 314 String[] ss = line.split("[,]"); 315 for(int j=0;j<ss.length;j++){ 316 // System.out.println(ss[j].trim()); 317 yymh[yymh_count++] = Integer.parseInt(ss[j].trim()); 318 } 319 }else if(inyytl){ 320 String[] ss = line.split("[,]"); 321 for(int j=0;j<ss.length;j++){ 322 // System.out.println(ss[j].trim()); 323 yytl[yytl_count++] = Integer.parseInt(ss[j].trim()); 324 } 325 }else if(inyyth){ 326 String[] ss = line.split("[,]"); 327 for(int j=0;j<ss.length;j++){ 328 // System.out.println(ss[j].trim()); 329 yyth[yyth_count++] = Integer.parseInt(ss[j].trim()); 330 } 331 }else if(inyytint){ 332 String[] ss = line.split("[,]"); 333 for(int j=0;j<ss.length;j++){ 334 // System.out.println(ss[j].trim()); 335 yytint[yytint_count++] = Integer.parseInt(ss[j].trim()); 336 } 337 }else if(inyyt){ 338 //System.out.println(line.trim()); 339 340 c = 0; 341 String[] st = line.trim().split(",,"); 342 char[] tmp = new char[st.length]; 343 for(int i=0;i<st.length;i++){ 344 345 if(st[i].startsWith("\'")) { 346 if(st[i].length() == 3){ // 'a' 347 tmp[c++] = st[i].charAt(1); 348 }else if(st[i].length() == 4) { // '\\' 349 tmp[c++] = st[i].charAt(2); 350 }else{ 351 System.out.println(" read yytstr error, error string is "+st[i]+ "line: "+ yyt_count); 352 } 353 }else{ 354 try{ 355 tmp[c++] = (char)Integer.parseInt(st[i]); // char in number like 32 that represent space 356 } catch (NumberFormatException nfe) { 357 System.out.println("NumberFormatException: " + nfe.getMessage()); 358 } 359 } 360 } //while hasmoreTokens 361 362 //yyt[lineno] = new YYTrec(tmp,yytint[lineno]); 363 yyt[yyt_count] = new TYytRec(tmp,yytint[yyt_count]); 364 yyt_count++; 365 366 }else if(inkeyword){ 367 String[] ss =line.split("[=]"); 368 369 int val1 = -1; 370 int val2 = -1; 371 try { 372 val1 = Integer.parseInt(ss[1]); 373 val2 = Integer.parseInt(ss[2]); 374 } 375 catch (NumberFormatException nfe) { 376 System.out.println("NumberFormatException: " + nfe.getMessage()); 377 } 378 keywordValueList.put(ss[0].toUpperCase(),val1); 379 keywordTypeList.put(val1,val2); 380 } 381 } 382 }catch(IOException e){ 383 System.out.println(e.toString()); 384 } 385 386 yystateLookupConfigure(); 387 388 } 389 390 391 void yyaction(int yyruleno){ 392 393 394 int ic; 395 char[] tmparray = {'=','+','-','*','/','>','<'}; 396 397 yylvalstr = getyytext(); 398 /* actions: */ 399 switch(yyruleno){ 400 case 1: 401 402 { 403 returni (filepath_sign); 404 break; 405 } 406 407 case 2: 408 409 { 410 if (yylvalstr.equalsIgnoreCase(dolqstart)) 411 { 412 //dolqstart = ""; 413 start(init); 414 addlit(yylvalstr,yytextlen); 415 yylvalstr = litbufdup(); 416 returni(sconst); 417 } 418 else 419 { 420 //nchars = yytextlen; 421 addlit(yylvalstr, yytextlen-1); 422 yyless(yytextlen-1); 423 return; 424 } 425 //System.out.println("<xdolq>{dolqdelim}: "+dolqstart); 426 break; 427 } 428 429 case 3: 430 431 { 432 if (isReadyForFunctionBody) { // meet the first $$ 433 //isInFunctionBody = true; 434 isReadyForFunctionBody = false; 435 functionBodyDelimiterIndex++; 436 functionBodyDelimiter.add(yylvalstr); 437 // System.out.println("start function body:"+functionBodyDelimiter.get(functionBodyDelimiterIndex)); 438 returni(snowflake_function_delimiter); 439 }else if ((functionBodyDelimiterIndex>=0)&&(functionBodyDelimiter.get(functionBodyDelimiterIndex).equalsIgnoreCase(yylvalstr))){ // meet the second $$ 440 //isInFunctionBody = false; 441 //System.out.println("end function body:"+functionBodyDelimiter.get(functionBodyDelimiterIndex)); 442 functionBodyDelimiter.remove(functionBodyDelimiterIndex); 443 functionBodyDelimiterIndex--; 444 445 returni(snowflake_function_delimiter); 446 }else { 447 if (getyysstate() == xq){ 448 nchars = yytextlen; 449 addlit(yylvalstr, yytextlen-1); 450 yyless(nchars-1); 451 return;//exit; 452 }else{ 453 start(xdolq); 454 startlit(); 455 dolqstart = yylvalstr; 456 addlit(yylvalstr,yytextlen); 457 } 458 } 459 460 break; 461 } 462 463 case 4: 464 465 { 466 addlit(yylvalstr, yytextlen); 467 //System.out.println("<xdolq>{dolqinside}: "+yylvalstr); 468 break; 469 } 470 471 case 5: 472 473 { 474 addlit(yylvalstr, yytextlen); 475 break; 476 } 477 478 case 6: 479 480 { 481 addlitchar(yylvalstr.charAt(0)); 482 break; 483 } 484 485 486 case 7: 487 488 { 489 if (getyysstate() == xq) 490 { 491 nchars = yytextlen; 492 addlit(yylvalstr, yytextlen-1); 493 yyless(nchars-1); 494 return;//exit; 495 } 496 497 start(xq); 498 startlit(); 499 addlit(yylvalstr,yytextlen); 500 break; 501 } 502 503 case 8: 504 505 { 506 if (getyysstate() == xq) 507 { 508 nchars = yytextlen; 509 addlit(yylvalstr, yytextlen-1); 510 yyless(nchars-1); 511 return;//exit; 512 } 513 514 start(xq); 515 startlit(); 516 addlit(yylvalstr,yytextlen); 517 break; 518 } 519 520 case 9: 521 522 { 523 if (getyysstate() == xq) 524 { 525 nchars = yytextlen; 526 addlit(yylvalstr, yytextlen-1); 527 yyless(nchars-1); 528 return;//exit; 529 } 530 531 start(xq); 532 startlit(); 533 addlit(yylvalstr,yytextlen); 534 break; 535 } 536 537 case 10: 538 539 { 540 addlit(yylvalstr,yytextlen); 541 if (xcdepth <= 0) 542 { 543 start(init); 544 yylvalstr = litbufdup(); 545 returni(cmtslashstar); 546 } 547 else 548 xcdepth--; 549 550 break; 551 } 552 553 554 case 11: 555 556 { 557 if (yylvalstr.equalsIgnoreCase("/*+")){ 558 xcdepth++; 559 yyless(2); 560 addlit(yylvalstr,yytextlen); 561 }else{ 562 yyless(1); 563 addlit(yylvalstr,1); 564 } 565 566 break; 567 568 } 569 570 case 12: 571 572 { 573 574 if (getyysstate() == xq) 575 { 576 nchars = yytextlen; 577 addlit(yylvalstr, yytextlen-1); 578 yyless(nchars-1); 579 return;//exit; 580 } 581 582 xcdepth = 0; 583 start(xc); 584 startlit(); 585 yyless(2); 586 addlit(yylvalstr,yytextlen); 587 588 break; 589 } 590 591 case 13: 592 593 { 594 addlit(yylvalstr,yytextlen); 595 596 break; 597 } 598 599 case 14: 600 601 { 602 addlitchar(yylvalstr.charAt(0)); 603 604 break; 605 } 606 607 case 15: 608 609 { 610 start(init); 611 addlit(yylvalstr, yytextlen); 612 yylvalstr = litbufdup(); 613 if( yylvalstr.startsWith("b")|| (yylvalstr.startsWith("B"))){ 614 returni(bconst); 615 }else if( yylvalstr.startsWith("x")|| (yylvalstr.startsWith("X"))){ 616 returni(xconst); 617 }else 618 { 619 returni(sconst); 620 } 621 break; 622 } 623 624 case 16: 625 626 { 627 if (insqlpluscmd){ 628 yyless(0); 629 yylvalstr = litbufdup(); 630 start(init); 631 returni(sconst); 632 }else{ 633 addlit(yylvalstr,yytextlen); 634 } 635 636 break; 637 } 638 case 17: 639 640 { 641 if (getyysstate() == xq) 642 { 643 nchars = yytextlen; 644 addlit(yylvalstr, yytextlen-1); 645 yyless(nchars-1); 646 return;//exit; 647 } 648 649 start(xq); 650 startlit(); 651 addlit(yylvalstr,yytextlen); 652 653 dummych1 = get_char(); 654 if (dummych1 == '\\') // recognize string like '\' 655 { 656 dummych2 = get_char(); 657 if (dummych2 == '\'') 658 { 659 // start(init); 660 addlit("\\", 1); 661 addlit("\'", 1); 662 //yylvalstr = litbufdup(); 663 //returni(sconst); 664 } 665 else 666 { 667 unget_char(dummych2); 668 unget_char(dummych1); 669 } 670 } 671 else 672 { unget_char(dummych1);} 673 674 break; 675 } 676 677 case 18: 678 679 { 680 start(xq); 681 startlit(); 682 addlit(yylvalstr, yytextlen); 683 dummych1 = get_char(); 684 if (dummych1 == '\\') // recognize string like '\' 685 { 686 dummych2 = get_char(); 687 if (dummych2 == '\'') 688 { 689 // start(init); 690 addlit("\\", 1); 691 addlit("\'", 1); 692 //yylvalstr = litbufdup(); 693 //returni(sconst); 694 } 695 else 696 { 697 unget_char(dummych2); 698 unget_char(dummych1); 699 } 700 } 701 else 702 { unget_char(dummych1);} 703 704 break; 705 } 706 707 case 19: 708 709 { 710 addlit(yylvalstr, yytextlen); 711 break; 712 } 713 714 case 20: 715 716 { 717 dummych1 = get_char(); 718 unget_char(dummych1); 719 if (dummych1 == (char)10) 720 { 721 if (insqlpluscmd){ 722 nchars = yytextlen; 723 if(yylvalstr.charAt(nchars-1) == (char)13){ 724 yyless(nchars - 1); 725 yylvalstr = yylvalstr.substring(0,nchars); 726 } 727 start(init); 728 addlit(yylvalstr, nchars-1); 729 yylvalstr = litbufdup(); 730 returni(sconst); //in sqlplus command, characters between ' and return is treated as a string 731 732 }else{ 733 dummych1 = get_char(); 734 addlit(yylvalstr+dummych1, yytextlen+1); 735 } 736 } else if (dummych1 == '\\') 737 { 738 // Handle backslash inside string literals 739 // Snowflake supports both \' (C-style escape) and '' (SQL standard escape) 740 // The pattern \'' is ambiguous: 741 // - Could be \' (escape) + ' (close) - e.g., 'text\'' means text' then close 742 // - Could be \ (literal) + '' (escape) - e.g., 'text\''more' means text\'more 743 // We distinguish by looking at what follows \'' : 744 // - \''' : \' (escape) + '' (leave for xqdouble) - two quote chars in value 745 // - \''<letter/digit>: \ + '' (backslash + escape, string continues) 746 // - \''<space><SQL keyword>: \' + close (string ends, keyword follows) 747 // - \''<space><other>: \ + '' (backslash + escape, string continues with space) 748 // - \''<EOF/control>: \' + close 749 // See mantisbt issue 4298 for details 750 dummych1 = get_char(); // Read the backslash 751 dummych2 = get_char(); // Read the next char 752 if (dummych2 == '\'') { 753 // Have \' - check if followed by another quote 754 char dummych3 = get_char(); 755 if (dummych3 == '\'') { 756 // \'' pattern - check what comes after 757 char dummych4 = get_char(); 758 if (dummych4 == '\'') { 759 // \''' : consume \' as escape, leave '' for xqdouble 760 unget_char(dummych4); 761 unget_char(dummych3); 762 addlit(yylvalstr+dummych1+dummych2, yytextlen+2); 763 } else if (Character.isLetterOrDigit(dummych4) || dummych4 == '_') { 764 // \''<letter/digit>: \ + '' (string continues) 765 unget_char(dummych4); 766 unget_char(dummych3); 767 unget_char(dummych2); 768 addlit(yylvalstr+dummych1, yytextlen+1); 769 } else if (dummych4 == ' ' || dummych4 == '\t') { 770 // \''<space> - check if followed by SQL keyword 771 char dummych5 = get_char(); 772 char dummych6 = get_char(); 773 // Check for SQL keywords that typically follow a column/value expression 774 // Only check keywords that wouldn't appear as regular words in strings 775 String twoChars = "" + Character.toLowerCase(dummych5) + Character.toLowerCase(dummych6); 776 if (twoChars.equals("as")) { // AS is the most reliable indicator of SQL context 777 // Likely SQL keyword follows - treat \'' as \' + close 778 unget_char(dummych6); 779 unget_char(dummych5); 780 unget_char(dummych4); 781 unget_char(dummych3); 782 addlit(yylvalstr+dummych1+dummych2, yytextlen+2); 783 } else { 784 // Not a SQL keyword - treat as \ + '' (string continues) 785 unget_char(dummych6); 786 unget_char(dummych5); 787 unget_char(dummych4); 788 unget_char(dummych3); 789 unget_char(dummych2); 790 addlit(yylvalstr+dummych1, yytextlen+1); 791 } 792 } else if (dummych4 >= ' ' && dummych4 != (char)0 && dummych4 != (char)-1) { 793 // Other printable: \ + '' (string continues) 794 unget_char(dummych4); 795 unget_char(dummych3); 796 unget_char(dummych2); 797 addlit(yylvalstr+dummych1, yytextlen+1); 798 } else { 799 // \'' at EOF or followed by control char: \' escape + ' closes string 800 unget_char(dummych4); 801 unget_char(dummych3); 802 addlit(yylvalstr+dummych1+dummych2, yytextlen+2); 803 } 804 } else { 805 // \' followed by non-quote: consume \' as C-style escape 806 unget_char(dummych3); 807 addlit(yylvalstr+dummych1+dummych2, yytextlen+2); 808 } 809 } else { 810 // \X where X is not quote: consume both 811 addlit(yylvalstr+dummych1+dummych2, yytextlen+2); 812 } 813 } 814 else 815 { addlit(yylvalstr, yytextlen);} 816 817 break; 818 } 819 820 case 21: 821 822 { 823 addlit(yylvalstr, yytextlen); 824 break; 825 } 826 827 828 829 case 22: 830 831 { 832 start(init); 833 addlit(yylvalstr, yytextlen); 834 if ((literallen == 0) && (!insqlpluscmd)) 835 {returni (error);} 836 if (literallen >= namedatalen) 837 { 838 setlengthofliteralbuf(namedatalen); 839 literallen = namedatalen; 840 } 841 yylvalstr = litbufdup(); 842 returni (ident); 843 844 break; 845 } 846 847 848 case 23: 849 850 { 851 if (insqlpluscmd){ 852 yyless(0); 853 yylvalstr = litbufdup(); 854 start(init); 855 returni(sconst); 856 }else{ 857 addlit(yylvalstr, yytextlen); 858 } 859 860 break; 861 } 862 863 case 24: 864 865 { 866 addlit(yylvalstr, yytextlen); 867 break; 868 } 869 870 case 25: 871 872 { 873 start(xd); 874 startlit(); 875 addlit(yylvalstr, yytextlen); 876 break; 877 } 878 879 case 26: 880 881 { 882 dummych1 = get_char(); 883 unget_char(dummych1); 884 if (dummych1 == (char)10) 885 { 886 if (insqlpluscmd){ 887 nchars = yytextlen; 888 if(yylvalstr.charAt(nchars-1) == (char)13){ 889 yyless(nchars - 1); 890 yylvalstr = yylvalstr.substring(0,nchars); 891 } 892 start(init); 893 addlit(yylvalstr, nchars-1); 894 yylvalstr = litbufdup(); 895 returni(sconst); //in sqlplus command, characters between ' and return is treated as a string 896 897 }else{ 898 dummych1 = get_char(); 899 addlit(yylvalstr+dummych1, yytextlen+1); 900 } 901 902 } else 903 addlit(yylvalstr, yytextlen); 904 905 break; 906 } 907 908 case 27: 909 910 { 911 returni(lexnewline); 912 break; 913 } 914 915 case 28: 916 917 { 918 returni(lexspace); 919 break; 920 } 921 922 case 29: 923 924 { 925 if ((getyysstate() == xq) 926 || (getyysstate() == xd) 927 || (getyysstate() == xc) 928 ) 929 { 930 addlit(yylvalstr, 1); 931 yyless(1); 932 return;//exit; 933 } 934 935 returni(cmtdoublehyphen); 936 break; 937 } 938 939 case 30: 940 941 { 942 returnc(yylvalstr.charAt(0)); 943 break; 944 } 945 946 case 31: 947 948 { 949 returni(cmpop); 950 break; 951 } 952 953 case 32: 954 955 { 956 957 if (getyysstate() == xc) 958 { 959 slashstar = yylvalstr.indexOf("*/"); 960 if (slashstar >= 0) 961 { 962 start(init); 963 addlit(yylvalstr,slashstar+2); 964 yylvalstr = litbufdup(); 965 yyless(slashstar+2); 966 returni(cmtslashstar); 967 } 968 else 969 { 970 addlit(yylvalstr,1); 971 yyless(1); 972 } 973 } 974 else if (getyysstate() == xq) 975 { 976 addlit(yylvalstr,1); 977 yyless(1); 978 } 979 else 980 { 981 nchars = yytextlen; 982 slashstar = yylvalstr.indexOf("/*"); 983 dashdash = yylvalstr.indexOf("--"); 984 if ((slashstar > 0) && (dashdash > 0)) 985 { 986 //if both appear, take the first one 987 if (slashstar > dashdash) 988 {slashstar = dashdash;} 989 } 990 else 991 { 992 // if slashstar=0 then slashstar := dashdash; 993 // add (getyysstate <> xc) to avoid something like this */--,here */ should be handled instead of -- 994 if ((slashstar > 0) && (getyysstate() != xc)) { 995 nchars = slashstar; 996 } 997 } 998 999 while ((nchars > 1) 1000 && ( (yylvalstr.charAt(nchars-1) == '+' ) 1001 || (yylvalstr.charAt(nchars-1) =='-')) 1002 && (getyysstate() != xc)) 1003 { 1004 for (ic = nchars - 1; ic>=1; ic--) 1005 { 1006 if (isopchar(yylvalstr.charAt(ic-1))) break; 1007 } 1008 if (ic >= 1) break; 1009 nchars--; 1010 } 1011 1012 if (nchars < yytextlen) 1013 { 1014 //Strip the unwanted chars from the token 1015 yyless(nchars); 1016 yylvalstr = yylvalstr.substring(0,nchars); 1017 } 1018 1019 ///* 1020 // * If what we have left is only one char, and it's 1021 // * one of the characters matching "self", then 1022 // * return it as a character token the same way 1023 // * that the "self" rule would have. 1024 // * make sure @ return as self char, by james wang 1025 // */ 1026 if ((nchars == 1) && (isselfchar(yylvalstr.charAt(0)) || (yylvalstr.charAt(0) == '@'))) 1027 { 1028 returnc(yylvalstr.charAt(0)); 1029 } 1030 else if ( 1031 (nchars >= 2) 1032 &&( 1033 charinarray(yylvalstr.charAt(nchars-1-1), tmparray) 1034 && ((yylvalstr.charAt(nchars-1) == ':') 1035 ||(yylvalstr.charAt(nchars-1) == '.') 1036 ) 1037 ) 1038 ) 1039 { 1040 yyless(nchars-1); 1041 yylvalstr = yylvalstr.substring(0,nchars-1); 1042 if (nchars == 2) 1043 returnc(yylvalstr.charAt(0)); 1044 else 1045 returni(op); 1046 } 1047 else if ( 1048 (nchars >= 2) 1049 && ( 1050 charinarray(yylvalstr.charAt(nchars-1-1),tmparray) 1051 && (yylvalstr.charAt(nchars-1) == '&') 1052 ) 1053 ) 1054 { 1055 yyless(nchars-1); 1056 yylvalstr = yylvalstr.substring(0,nchars-1); 1057 if (nchars == 2) 1058 returnc(yylvalstr.charAt(0)); 1059 else 1060 returni(op); 1061 } 1062 else if ( (nchars > 1) && (yylvalstr.charAt(0) == '~')) 1063 { 1064 yyless(1); 1065 returnc(yylvalstr.charAt(0)); 1066 } 1067 else if ( (nchars == 2) && (yylvalstr.charAt(0) == '.') && (yylvalstr.charAt(1) == '*')) 1068 { 1069 yyless(1); 1070 returnc(yylvalstr.charAt(0)); 1071 } 1072 else if ((nchars == 2) && ((yylvalstr.charAt(0) == '=') && ( (yylvalstr.charAt(1) == '?')||(yylvalstr.charAt(1) == '@')) )) 1073 { 1074 yyless(1); 1075 returnc(yylvalstr.charAt(0)); 1076 } 1077 else if ( (nchars >= 2) && ((yylvalstr.charAt(0) == '@')&&(yylvalstr.charAt(1) != '>'))) 1078 { 1079 yyless(1); 1080 returnc(yylvalstr.charAt(0)); 1081 } 1082 else if ( (nchars >= 2) && ((yylvalstr.charAt(0) == '/'))) 1083 { 1084 yyless(1); 1085 returnc(yylvalstr.charAt(0)); 1086 } 1087 else if (((nchars > 2) && (yylvalstr.charAt(0) == '*')) 1088 && (yylvalstr.charAt(1) == '/') 1089 && (getyysstate() == xc) 1090 ) 1091 { //in comment, and find */ , then it must the end of comment 1092 yyless(2); 1093 addlit(yylvalstr,yytextlen); 1094 if (xcdepth <= 0) 1095 { 1096 start(init); 1097 yylvalstr = litbufdup(); 1098 returni(cmtslashstar); 1099 } 1100 else 1101 xcdepth--; 1102 } 1103 else 1104 returni(op); 1105 } 1106 1107 break; 1108 } 1109 1110 case 33: 1111 1112 { 1113 returni(iconst); 1114 break; 1115 } 1116 1117 case 34: 1118 1119 { 1120 ///* for i in 1..5 loop, we can't recognize 1. as a decimal,but 1 as decimal 1121 nchars = yytextlen; 1122 if (yylvalstr.charAt(nchars-1) == '.') 1123 { 1124 dummych1 = get_char(); 1125 unget_char(dummych1); 1126 if (dummych1 == '.') 1127 { 1128 yyless(nchars-1); 1129 yylvalstr = yylvalstr.substring(0,nchars - 1); 1130 returni (iconst); 1131 return;//exit; 1132 } 1133 } 1134 returni (fconst); 1135 break; 1136 } 1137 1138 case 35: 1139 1140 { 1141 returni (fconst); 1142 break; 1143 } 1144 1145 case 36: 1146 1147 { 1148 boolean dollarConstant = false; 1149 if (getyysstate() == xdolq){ 1150 int p = yylvalstr.indexOf("$"); 1151 if (p > 0){ 1152 dollarConstant = true; 1153 addlit(yylvalstr, p); 1154 yyless(p); 1155 return; 1156 } 1157 } 1158 1159 if (!dollarConstant){ 1160 int rw; 1161 if ( (rw = iskeyword(yylvalstr)) != -1) { 1162 if (rw == TBaseType.rrw_as){ 1163 isReadyForFunctionBody = true; 1164 // check whether language is javascript, if yes, don't set isReadyForFunctionBody to true 1165 if ((TOKEN_TABLE[TBaseType.rrw_snowflake_language][COLUMN0_COUNT] > 0) 1166 &&(TOKEN_TABLE[TBaseType.rrw_snowflake_javascript][COLUMN0_COUNT] > 0)){ 1167 if (TOKEN_TABLE[TBaseType.rrw_snowflake_javascript][COLUMN5_FIRST_POS] - TOKEN_TABLE[TBaseType.rrw_snowflake_language][COLUMN5_FIRST_POS] <= 2){ 1168 // RETURNS STRING LANGUAGE JAVASCRIPT 1169 // 如果是 RETURNS STRING LANGUAGE JAVASCRIPT,那么不需要设置isReadyForFunctionBody = true,即把整个$$...$$当作字符串处理 1170 isReadyForFunctionBody = false; 1171 } 1172 } 1173 1174 }else{ 1175 isReadyForFunctionBody = false; 1176 } 1177 returni(rw); 1178 } 1179 else 1180 { 1181 isReadyForFunctionBody = false; 1182 returni(ident); 1183 } 1184 } 1185 1186 break; 1187 } 1188 1189 case 37: 1190 1191 { 1192 if (getyysstate() == xdolq){ 1193 addlit(yylvalstr, yytextlen); 1194 return; 1195 }else{ 1196 returni (param); 1197 } 1198 1199 break; 1200 } 1201 1202 case 38: 1203 1204 { 1205 returni (outer_join); 1206 break; 1207 } 1208 1209 case 39: 1210 1211 { 1212 returni (typecast); 1213 break; 1214 } 1215 1216 case 40: 1217 1218 { 1219 returni (double_dot); 1220 break; 1221 } 1222 1223 case 41: 1224 1225 { 1226 returni (assign_sign); 1227 break; 1228 } 1229 1230 case 42: 1231 1232 { 1233 returni (variable); 1234 break; 1235 } 1236 1237 case 43: 1238 1239 { 1240 returni (bind_v); 1241 break; 1242 } 1243 1244 1245 case 44: 1246 1247 { 1248 returni (error); 1249 break; 1250 } 1251 1252 default:{ 1253 System.out.println("fatal error in yyaction"); 1254 } 1255 }//switch 1256}/*yyaction*/; 1257 1258 1259 1260 }