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