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(java.util.Locale.ROOT),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                  // Only the current line counts: the line buffer is reused, and text
845                  // left after it by a longer earlier line must not change the verdict.
846                  if (checkExpressionContext(yylvalstr.trim(),currentLineText().trim())) {
847                    inExpressionContext = true;
848                  }
849
850                  if (isAtBeginOfLine() || !inExpressionContext) {
851                    // Treat as a comment if at start of line or not in expression
852                    returni(cmtdoublehyphen);
853                    break;
854                  } else {
855                    // We're in an expression context, treat as mathematical operator
856                    yyless(1);  // Only take the first '-'
857                    returnc('-');
858                  }                  
859                  break;
860              }
861              // For any other character, it's still a comment
862          }
863
864          returni(cmtdoublehyphen);
865          break;
866          }
867
868  case 25:
869            
870        {
871      returni(twocolons);
872      break;
873    }
874
875
876  case 26:
877      
878          {
879               returnc(yylvalstr.charAt(0));
880               break;
881          }
882
883  case 27:
884                       
885          {
886            returni(cmpop);
887            break;
888          }
889        
890  case 28:
891           
892          {
893
894          if (getyysstate() == xc)
895             {
896              slashstar = yylvalstr.indexOf("*/");
897                if (slashstar >= 0)
898                  {
899                      addlit(yylvalstr,slashstar+2);
900                      yylvalstr = litbufdup();
901                      yyless(slashstar+2);
902
903                        if (xcdepth <= 0){
904                      start(init);
905                      returni(cmtslashstar);
906                        }else{
907                                xcdepth--;
908                        }
909                  }
910                else
911                  {
912                      addlit(yylvalstr,1);
913                      yyless(1);
914                  }
915             }
916          else
917            {
918              nchars = yytextlen;
919              slashstar = yylvalstr.indexOf("/*");
920              dashdash = yylvalstr.indexOf("--");
921              if ((slashstar >= 0) && (dashdash >= 0))
922                {
923                  //if both appear, take the first one
924                   if (slashstar > dashdash)
925                    {slashstar = dashdash;}
926                }
927              else
928                {
929                  //   if slashstar=0 then slashstar := dashdash;
930                  // add (getyysstate <> xc) to avoid something like this */--,here */ should be handled instead of --
931                  if ((slashstar > 0) && (getyysstate() != xc)) {
932                    nchars = slashstar;
933                    }
934                }
935
936              while ((nchars > 1)
937                      && ( (yylvalstr.charAt(nchars-1) == '+' )
938                          || (yylvalstr.charAt(nchars-1) =='-'))
939                      && (getyysstate() != xc))
940                {
941                  for (ic = nchars - 1; ic>=1; ic--)
942                  {
943                    if (isopchar(yylvalstr.charAt(ic-1)))  break;
944                  }
945                  if (ic >= 1) break;
946                  nchars--;
947                }
948
949              if (nchars < yytextlen)
950                {
951                  //Strip the unwanted chars from the token
952                  yyless(nchars);
953                  yylvalstr = yylvalstr.substring(0,nchars);
954                }
955
956                  ///*
957                  // * If what we have left is only one char, and it's
958                  // * one of the characters matching "self", then
959                  // * return it as a character token the same way
960                  // * that the "self" rule would have.
961                  // * make sure @ return as self char, by james wang
962                  // */
963                  if ((nchars == 1) && (isselfchar(yylvalstr.charAt(0)) || (yylvalstr.charAt(0) == '@')))
964                    {
965                      returnc(yylvalstr.charAt(0));
966                    }
967                  else if ( (nchars >= 2) && (yylvalstr.charAt(nchars-1-1) == '.') )
968                    {
969                        yyless(1);
970                        returnc(yylvalstr.charAt(0));
971                    }
972                  else if ( (nchars >= 2) && (yylvalstr.charAt(0) == '?') )
973                    {
974                        yyless(1);
975                        returnc(yylvalstr.charAt(0));
976                    }
977                  else if ( ((yylvalstr.charAt(0) == '+')||(yylvalstr.charAt(0) == '-')||(yylvalstr.charAt(0) == '*')||(yylvalstr.charAt(0) == '/')||(yylvalstr.charAt(0) == '%') ))
978                    {
979                                          if (nchars >= 2){
980                                                if (yylvalstr.charAt(1) == '='){
981                                                        yyless(2);
982                                                        yylvalstr = yylvalstr.substring(0,2);
983                                                        returni(op);
984                                                }else{
985                                                        yyless(1);
986                                                        returnc(yylvalstr.charAt(0));
987                                                }
988                                          }else{
989                                                returnc(yylvalstr.charAt(0));
990                                          }
991                        
992                    }
993                  else if (
994                              (nchars >= 2)
995                                  &&(
996                                       charinarray(yylvalstr.charAt(nchars-1-1), tmparray)
997                                       && (yylvalstr.charAt(nchars-1) == ':')
998                                       )
999                           )
1000                      {
1001                        yyless(nchars-1);
1002                         yylvalstr = yylvalstr.substring(0,nchars-1);
1003                        if (nchars == 2)
1004                          returnc(yylvalstr.charAt(0));
1005                        else
1006                          returni(op);
1007                      }
1008                    else if (
1009                                (nchars >= 2)
1010                                    && (
1011                                          charinarray(yylvalstr.charAt(nchars-1-1),tmparray)
1012                                          && (yylvalstr.charAt(nchars-1) == '.')
1013                                         )
1014                               )
1015                        {
1016                          yyless(nchars-1);
1017                           yylvalstr = yylvalstr.substring(0,nchars-1);
1018                          if (nchars == 2)
1019                            returnc(yylvalstr.charAt(0));
1020                          else
1021                            returni(op);
1022                        }
1023                    else if (
1024                                (nchars > 2)
1025                                    && ((yylvalstr.charAt(nchars-1) == '-')
1026                                        ||(yylvalstr.charAt(nchars-1) == '+')
1027                                         )
1028                               )
1029                        {
1030                          yyless(nchars-1);
1031                           yylvalstr = yylvalstr.substring(0,nchars-1);
1032                           returni(op);
1033                        }
1034                    else if ( (nchars >= 2) && (yylvalstr.charAt(nchars-1) == '@') )
1035                      {
1036                        if (nchars == 2)
1037                          { // such as >@
1038                              yyless(nchars-1);
1039                            yylvalstr = yylvalstr.substring(0,nchars-1);
1040                             returnc(yylvalstr.charAt(0));
1041                          }
1042                        else
1043                          {
1044                            if ((yylvalstr.charAt(nchars-1-1) == '@')||(yylvalstr.charAt(nchars-1-1) == '-'))
1045                              { //such as >@@,>=@@, =-@
1046                                  yyless(nchars-2);
1047                                yylvalstr = yylvalstr.substring(0,nchars-2);
1048                                if (nchars == 3)
1049                                    returnc(yylvalstr.charAt(0));
1050                                else
1051                                    returni(cmpop);
1052                              }
1053                            else
1054                              { // >=@
1055                                                                yyless(nchars-1);
1056                                                                yylvalstr = yylvalstr.substring(0,nchars-1);
1057                                                                returni(cmpop);
1058                              }
1059                          }
1060                         }
1061                      else if ( (nchars >= 2) && (yylvalstr.charAt(0)== '|') && (yylvalstr.charAt(1) == '|'))
1062                        { //||--sss ,just get || only
1063                              yyless(2);
1064                              yylvalstr = yylvalstr.substring(0,2);
1065                              returni(concatenationop); //return as concatenationop, this is used in sybase only
1066                        }
1067                      else if ((nchars >= 2) && ((yylvalstr.charAt(0) =='.') && ( (yylvalstr.charAt(1)=='*') || (yylvalstr.charAt(1) =='#')) ))
1068                          {
1069                            yyless(1);
1070                            returnc(yylvalstr.charAt(0));
1071                          }
1072                      else if ((nchars == 2) && ((yylvalstr.charAt(0) == '=') && ( (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) == '#') && ( (yylvalstr.charAt(1) == '.')) ))
1083                          {
1084                            yyless(1);
1085                            returnc(yylvalstr.charAt(0));
1086                          }
1087                      else if ((nchars == 2) && (((yylvalstr.charAt(0) == '>')||(yylvalstr.charAt(0) == '<')) && ( (yylvalstr.charAt(1) == '#')) ))
1088                          {
1089                            yyless(1);
1090                            returnc(yylvalstr.charAt(0));
1091                          }
1092                      else if ((nchars == 3) && ((yylvalstr.charAt(1) == '#') && ( (yylvalstr.charAt(2) == '.')) ))
1093                          {
1094                            yyless(1);
1095                            returnc(yylvalstr.charAt(0));
1096                          }
1097                      else if ((nchars == 2) && ((yylvalstr.charAt(0) == '$') && ( (yylvalstr.charAt(1) == '-')) ))
1098                          {
1099                            yyless(1);
1100                            returnc(yylvalstr.charAt(0));
1101                          }
1102                                        else if ( (nchars >= 3) && (yylvalstr.charAt(nchars-1) == '$' ) && (yylvalstr.charAt(nchars-2) == '$' ))
1103                                        { // =$$abc
1104                                            if (nchars == 3){
1105                                                        yyless(1);
1106                                                        returnc(yylvalstr.charAt(0));
1107                                                }else{
1108                                                        yyless(nchars-2);
1109                                                        yylvalstr = yylvalstr.substring(0,nchars-2);
1110                                                        returni(cmpop);
1111                                                }
1112                                        }
1113                                          else if (((nchars > 2) && (yylvalstr.charAt(0) == '*'))
1114                              && (yylvalstr.charAt(1) == '/')
1115                              && (getyysstate() == xc)
1116                              )
1117                           { //in comment, and find */ , then it must the end of comment
1118                             yyless(2);
1119                                addlit(yylvalstr,yytextlen);
1120                             if (xcdepth <= 0)
1121                               {
1122                                 start(init);
1123                                 yylvalstr = litbufdup();
1124                                 returni(cmtslashstar);
1125                               }
1126                             else
1127                               xcdepth--;
1128                           }
1129                      else
1130                        returni(op);
1131               }
1132
1133          break;
1134          }
1135
1136  case 29:
1137                        
1138          {
1139               returni(iconst);
1140               break;
1141          }
1142
1143  case 30:
1144                        
1145          {
1146            ///*  for i in 1..5 loop, we can't recognize 1. as a decimal,but 1 as decimal
1147            nchars = yytextlen;
1148            if (yylvalstr.charAt(nchars-1) == '.')
1149              {
1150                dummych1 = get_char();
1151                unget_char(dummych1);
1152                if (dummych1 == '.')
1153                  {
1154                      yyless(nchars-1);
1155                    yylvalstr = yylvalstr.substring(0,nchars - 1);
1156                    returni (iconst);
1157                    return;//exit;
1158                  }
1159              }
1160            returni (fconst);
1161           break;
1162          }
1163
1164  case 31:
1165                        
1166          {
1167           returni (fconst);
1168           break;
1169          }
1170
1171  case 32:
1172              
1173          {
1174            int rw;
1175            if ( (rw = iskeyword(yylvalstr)) != -1)   { returni(rw);}
1176            else
1177               returni(ident);
1178            break;
1179          }
1180
1181  case 33:
1182           
1183          {
1184            int rw;
1185            if ( (rw = issystemvariable(yylvalstr)) != -1)  { returni(rw);}
1186            else if (yylvalstr.charAt(0) == '$'){
1187                returni(ident);
1188            }
1189            else
1190               returni(variable);
1191
1192            break;
1193          }
1194 
1195
1196
1197  case 34:
1198           
1199          {
1200            int rw;
1201            dummych1 = get_char();
1202            unget_char(dummych1);
1203
1204                        if (dummych1 == ':')
1205                        {
1206                                nchars = yytextlen;
1207                                yyless(nchars-1);
1208                                yylvalstr = yylvalstr.substring(0,nchars-1);
1209                                
1210                    if ( (rw = iskeyword(yylvalstr)) != -1)   { returni(rw);}
1211                    else
1212                       returni(ident);
1213                        }
1214                        else
1215                        {
1216                    returni(mslabel);
1217                        }
1218
1219            break;
1220          }
1221
1222      
1223  case 35:
1224         
1225          {
1226           returni(ident);
1227           break;
1228          }
1229    
1230  case 36:
1231          
1232          {
1233           returni(ident);
1234           break;
1235          }
1236                  
1237  case 37:
1238                        
1239          {
1240            returni( error);
1241                        //System.out.println("found error char");
1242            break;
1243          }
1244    default:{
1245     System.out.println("fatal error in yyaction");
1246    }
1247   }//switch
1248}/*yyaction*/;
1249
1250
1251
1252        }