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        }