* Bug 15808 fixed: [5i] was parsed as [5,i]
[scilab.git] / scilab / modules / ast / src / cpp / parse / flex / scanscilab.ll
1 %{
2 /* -*- C++ -*- */
3 /*
4  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
5  *  Copyright (C) 2008-2012 - Scilab Enterprises - Bruno JOFRET
6  *
7  * Copyright (C) 2012 - 2016 - Scilab Enterprises
8  *
9  * This file is hereby licensed under the terms of the GNU GPL v2.0,
10  * pursuant to article 5.3.4 of the CeCILL v.2.1.
11  * This file was originally licensed under the terms of the CeCILL v2.1,
12  * and continues to be available under such terms.
13  * For more information, see the COPYING file which you should have received
14  * along with this program.
15  *
16  */
17
18 #include <stack>
19
20 #include "isatty.hxx"
21 #include "parse.hxx"
22 #include "parser_private.hxx"
23
24 #include "context.hxx"
25
26 extern "C"
27 {
28 #include "charEncoding.h"
29 #include "sci_malloc.h"
30 }
31
32 static std::stack<int> paren_levels;
33
34 static int comment_level = 0;
35 static int last_token = 0;
36 static int linebreak_stored_token = 0;
37 static bool linebreak_stored_space = FALSE;
38 static int exit_status = PARSE_ERROR;
39 static int str_opener_column = 0;
40 static std::string current_file;
41 static std::string program_name;
42
43 static std::string pstBuffer;
44
45 extern void yyerror(std::string);
46
47 #define YY_USER_ACTION                          \
48     yylloc.first_column = yylloc.last_column; yylloc.last_column += yyleng;
49 //yylloc.last_column += yyleng;
50
51 /* -*- Verbose Special Debug -*- */
52 //#define DEV
53 //#define TOKENDEV
54
55 #ifdef DEV
56 #define DEBUG(x) std::cout << "[DEBUG] " << x << std::endl;
57 #else
58 #define DEBUG(x) /* Nothing */
59 #endif
60
61 #ifdef DEV
62 std::string token_to_string(int);
63 #endif
64
65 %}
66
67 %option stack
68 %option noyywrap
69
70 %x SIMPLESTRING
71 %x DOUBLESTRING
72 %x REGIONCOMMENT
73 %x LINECOMMENT
74 %x LINEBREAK
75
76 %x MATRIX
77
78 %x SHELLMODE
79 %x BEGINID
80
81 spaces                  [ \t\v\f]+
82 integer                 [0-9]+
83 number                  [0-9]+[\.][0-9]*
84 little                  \.[0-9]+
85 bom             \xEF\xBB\xBF
86
87 floating_D              ({little}|{number}|{integer})[dD][+-]?{integer}
88 floating_E              ({little}|{number}|{integer})[eE][+-]?{integer}
89
90 hex             [0]x[0-9a-fA-F]+
91 oct             [0]o[0-7]+
92
93
94 utf2            ([\xC2-\xDF][\x80-\xBF])
95 utf31           ([\xE0][\xA0-\xBF][\x80-\xBF])
96 utf32           ([\xE1-\xEC][\x80-\xBF][\x80-\xBF])
97 utf33           ([\xED][\x80-\x9F][\x80-\xBF])
98 utf34           ([\xEE-\xEF][\x80-\xBF][\x80-\xBF])
99 utf41           ([\xF0][\x90-\xBF][\x80-\xBF][\x80-\xBF])
100 utf42           ([\xF1-\xF3][\x80-\xBF][\x80-\xBF][\x80-\xBF])
101 utf43           ([\xF4][\x80-\x8F][\x80-\xBF][\x80-\xBF])
102
103 utf3            ({utf31}|{utf32}|{utf33}|{utf34})
104 utf4            ({utf41}|{utf42}|{utf43})
105
106 utf             ({utf2}|{utf3}|{utf4})
107 id              ((([a-zA-Z_%#?]|{utf})([a-zA-Z_0-9#?$]|{utf})*)|([$]([a-zA-Z_0-9#?$]|{utf})+))
108
109 incorrect_number     ({integer}|{number}|{floating_D}|{floating_E}){id}
110
111 newline                 ("\r"|"\n"|"\r\n")
112 blankline               {spaces}+{newline}
113 emptyline       {newline}({spaces}|[,;])+{newline}
114 next                    \.\.+
115 char_in_line_comment    [^\r\n]*
116 char_in_comment         [^\r\n\/*]*
117
118 boolnot                 ("@"|"~")
119 booltrue                ("%t"|"%T")
120 boolfalse               ("%f"|"%F")
121 booland                 ("&")
122 boolandand              ("&&")
123 boolor                  ("|")
124 booloror                ("||")
125
126 lbrack                  "["
127 rbrack                  "]"
128
129 lparen                  "("
130 rparen                  ")"
131
132 lbrace                  "{"
133 rbrace                  "}"
134
135 dollar                  "$"
136
137 semicolon               ";"
138 comma                   ","
139 colon                   ":"
140
141 startcomment            "//"
142 startblockcomment       "/*"
143 endblockcomment         "*/"
144
145 dquote                  "\""
146 quote                   "'"
147 in_string               [^\"\'\r\n\.]*
148
149 dot             "."
150 dotquote                ".'"
151 dottimes                ".*"
152 dotrdivide              "./"
153 dotldivide              ".\\"
154 dotpower                (".^"|".**")
155
156 plus                    "+"
157 minus                   "-"
158 rdivide                 "/"
159 ldivide                 "\\"
160 times                   "*"
161 power                   ("^"|"**")
162
163 equal                   "="{spaces}*"="
164 notequal                ("~"{spaces}*"="|"@"{spaces}*"="|"<"{spaces}*">")
165 lowerthan               "<"
166 greaterthan             ">"
167 lowerequal              "<"{spaces}*"="
168 greaterequal            ">"{spaces}*"="
169
170 krontimes               ".*."
171 kronrdivide             "./."
172 kronldivide             ".\\."
173
174 controltimes    ("*."[^0-9])
175 controlrdivide  ("/."[^0-9])
176 controlldivide  ("\\."[^0-9])
177
178 assign                  "="
179
180 %%
181 <INITIAL>{bom}/.* {
182 // BOM found ==> ignored
183 }
184
185 <INITIAL,BEGINID>{booltrue}     {
186     BEGIN(INITIAL);
187     return scan_throw(BOOLTRUE);
188 }
189 <INITIAL,BEGINID>{boolfalse}    {
190     BEGIN(INITIAL);
191     return scan_throw(BOOLFALSE);
192 }
193
194 <INITIAL,BEGINID>"if"            {
195         if (last_token != DOT)
196     {
197         ParserSingleInstance::pushControlStatus(Parser::WithinIf);
198     }
199     DEBUG("BEGIN(INITIAL)");
200     BEGIN(INITIAL);
201     return scan_throw(IF);
202 }
203
204 <INITIAL,BEGINID>"then"          {
205     DEBUG("BEGIN(INITIAL)");
206     BEGIN(INITIAL);
207     return scan_throw(THEN);
208 }
209
210 <INITIAL,BEGINID>"else"          {
211         if (last_token != DOT)
212     {
213         // Pop to step out IF
214         ParserSingleInstance::popControlStatus();
215         ParserSingleInstance::pushControlStatus(Parser::WithinElse);
216     }
217     DEBUG("BEGIN(INITIAL)");
218     BEGIN(INITIAL);
219         return scan_throw(ELSE);
220 }
221
222 <INITIAL,BEGINID>"elseif" {
223         if (last_token != DOT)
224     {
225         ParserSingleInstance::popControlStatus();
226         ParserSingleInstance::pushControlStatus(Parser::WithinElseIf);
227     }
228     DEBUG("BEGIN(INITIAL)");
229     BEGIN(INITIAL);
230         return scan_throw(ELSEIF);
231 }
232
233 <INITIAL,BEGINID>"end"          {
234         if (last_token != DOT)
235     {
236         ParserSingleInstance::popControlStatus();
237     }
238     DEBUG("BEGIN(INITIAL)");
239     BEGIN(INITIAL);
240     return scan_throw(END);
241 }
242
243 <INITIAL,BEGINID>"select"       {
244         if (last_token != DOT)
245     {
246         ParserSingleInstance::pushControlStatus(Parser::WithinSelect);
247     }
248     DEBUG("BEGIN(INITIAL)");
249     BEGIN(INITIAL);
250     return scan_throw(SELECT);
251 }
252
253 <INITIAL,BEGINID>"switch"       {
254         if (last_token != DOT)
255     {
256         ParserSingleInstance::pushControlStatus(Parser::WithinSwitch);
257     }
258     DEBUG("BEGIN(INITIAL)");
259     BEGIN(INITIAL);
260     return scan_throw(SWITCH);
261 }
262
263 <INITIAL,BEGINID>"otherwise" {
264         if (last_token != DOT)
265     {
266         ParserSingleInstance::popControlStatus();
267         ParserSingleInstance::pushControlStatus(Parser::WithinOtherwise);
268     }
269     DEBUG("BEGIN(INITIAL)");
270     BEGIN(INITIAL);
271         return scan_throw(OTHERWISE);
272 }
273
274 <INITIAL,BEGINID>"case"         {
275         if (last_token != DOT)
276     {
277         ParserSingleInstance::popControlStatus();
278         ParserSingleInstance::pushControlStatus(Parser::WithinCase);
279     }
280     DEBUG("BEGIN(INITIAL)");
281     BEGIN(INITIAL);
282     return scan_throw(CASE);
283 }
284
285 <INITIAL,BEGINID>"function" {
286         if (last_token != DOT)
287     {
288         ParserSingleInstance::pushControlStatus(Parser::WithinFunction);
289     }
290     DEBUG("BEGIN(INITIAL)");
291     BEGIN(INITIAL);
292     return scan_throw(FUNCTION);
293 }
294
295 <INITIAL,BEGINID>"endfunction" {
296         if (last_token != DOT)
297     {
298         ParserSingleInstance::popControlStatus();
299     }
300     DEBUG("BEGIN(INITIAL)");
301     BEGIN(INITIAL);
302         return scan_throw(ENDFUNCTION);
303 }
304
305 <INITIAL,BEGINID>"for" {
306         if (last_token != DOT)
307     {
308         ParserSingleInstance::pushControlStatus(Parser::WithinFor);
309     }
310     BEGIN(INITIAL);
311     return scan_throw(FOR);
312 }
313
314 <INITIAL,BEGINID>"while"        {
315         if (last_token != DOT)
316     {
317         ParserSingleInstance::pushControlStatus(Parser::WithinWhile);
318     }
319         BEGIN(INITIAL);
320         return scan_throw(WHILE);
321 }
322
323 <INITIAL,BEGINID>"do"           {
324         BEGIN(INITIAL);
325     return scan_throw(DO);
326 }
327
328 <INITIAL,BEGINID>"break"                {
329         BEGIN(INITIAL);
330         return scan_throw(BREAK);
331 }
332
333 <INITIAL,BEGINID>"continue"             {
334         BEGIN(INITIAL);
335         return scan_throw(CONTINUE);
336 }
337
338 <INITIAL,BEGINID>"try" {
339         ParserSingleInstance::pushControlStatus(Parser::WithinTry);
340         BEGIN(INITIAL);
341         return scan_throw(TRY);
342 }
343
344 <INITIAL,BEGINID>"catch" {
345     // Pop to step out TRY
346         ParserSingleInstance::popControlStatus();
347         ParserSingleInstance::pushControlStatus(Parser::WithinCatch);
348         BEGIN(INITIAL);
349         return scan_throw(CATCH);
350 }
351
352 <INITIAL,BEGINID>"return"       {
353     BEGIN(INITIAL);
354     return scan_throw(RETURN);
355 }
356
357 <INITIAL,BEGINID>"resume"       {
358     BEGIN(INITIAL);
359     return scan_throw(RETURN);
360 }
361
362 ^{spaces}*/({id}){spaces}([^ \t\v\f(=<>~@,;]|([~@]{spaces}*[^=]?)) {
363         BEGIN(BEGINID);
364 }
365
366 <BEGINID>
367 {
368     {id}                        {
369         wchar_t *pwText = to_wide_string(yytext);
370         if (yytext != NULL && pwText == NULL)
371         {
372             std::string str = "Can\'t convert \'";
373             str += yytext;
374             str += "\' to UTF-8";
375             BEGIN(INITIAL);
376             yyerror(str);
377             return scan_throw(FLEX_ERROR);
378         }
379         yylval.str = new std::wstring(pwText);
380         FREE(pwText);
381         types::InternalType * pIT = symbol::Context::getInstance()->get(symbol::Symbol(*yylval.str));
382         if (pIT && pIT->isCallable())
383         {
384             BEGIN(SHELLMODE);
385         }
386         else
387         {
388             BEGIN(INITIAL);
389         }
390         return scan_throw(ID);
391     }
392
393 }
394
395 <INITIAL,MATRIX>{boolnot}               {
396   return scan_throw(NOT);
397 }
398 <INITIAL,MATRIX>{dollar}                {
399   return scan_throw(DOLLAR);
400 }
401 <INITIAL,MATRIX>{booltrue}              {
402   return scan_throw(BOOLTRUE);
403 }
404 <INITIAL,MATRIX>{boolfalse}             {
405   return scan_throw(BOOLFALSE);
406 }
407 <INITIAL,MATRIX>{booland}               {
408   return scan_throw(AND);
409 }
410 <INITIAL,MATRIX>{boolandand}    {
411   return scan_throw(ANDAND);
412 }
413 <INITIAL,MATRIX>{boolor}                {
414   return scan_throw(OR);
415 }
416 <INITIAL,MATRIX>{booloror}              {
417   return scan_throw(OROR);
418 }
419
420
421 <INITIAL>{lparen}                       {
422   return scan_throw(LPAREN);
423 }
424 <INITIAL>{rparen}                       {
425   return scan_throw(RPAREN);
426 }
427
428
429 <INITIAL,MATRIX>{semicolon}             {
430         scan_step();
431   return scan_throw(SEMI);
432 }
433
434 <INITIAL,MATRIX>{comma}                 {
435         scan_step();
436   return scan_throw(COMMA);
437 }
438
439 <INITIAL,MATRIX>{colon}                 {
440   return scan_throw(COLON);
441 }
442
443
444 <INITIAL,MATRIX>{lbrace}                {
445   yy_push_state(MATRIX);
446   paren_levels.push(0);
447   ParserSingleInstance::pushControlStatus(Parser::WithinCell);
448   return scan_throw(LBRACE);
449 }
450
451 {rbrace}                        {
452   return scan_throw(RBRACE);
453 }
454
455
456 <INITIAL,MATRIX>{dotquote}              {
457   return scan_throw(DOTQUOTE);
458 }
459 <INITIAL,MATRIX>{dottimes}              {
460   return scan_throw(DOTTIMES);
461 }
462 <INITIAL,MATRIX>{dotrdivide}            {
463   return scan_throw(DOTRDIVIDE);
464 }
465 <INITIAL,MATRIX>{dotldivide}            {
466   return scan_throw(DOTLDIVIDE);
467 }
468 <INITIAL,MATRIX>{dotpower}              {
469   return scan_throw(DOTPOWER);
470 }
471
472
473 {minus}                                 {
474   return scan_throw(MINUS);
475 }
476 {plus}                                  {
477   return scan_throw(PLUS);
478 }
479 <INITIAL,MATRIX>{times}                 {
480   return scan_throw(TIMES);
481 }
482 <INITIAL,MATRIX>{rdivide}               {
483   return scan_throw(RDIVIDE);
484 }
485 <INITIAL,MATRIX>{ldivide}               {
486   return scan_throw(LDIVIDE);
487 }
488 <INITIAL,MATRIX>{power}                 {
489   return scan_throw(POWER);
490 }
491
492 <INITIAL,MATRIX>{krontimes}             {
493   return scan_throw(KRONTIMES);
494 }
495 <INITIAL,MATRIX>{kronrdivide}           {
496   return scan_throw(KRONRDIVIDE);
497 }
498 <INITIAL,MATRIX>{kronldivide}           {
499   return scan_throw(KRONLDIVIDE);
500 }
501
502
503 <INITIAL,MATRIX>{controltimes}          {
504     unput(yytext[yyleng - 1]);
505     return scan_throw(CONTROLTIMES);
506 }
507 <INITIAL,MATRIX>{controlrdivide}                {
508     unput(yytext[yyleng - 1]);
509     return scan_throw(CONTROLRDIVIDE);
510 }
511 <INITIAL,MATRIX>{controlldivide}                {
512     unput(yytext[yyleng - 1]);
513     return scan_throw(CONTROLLDIVIDE);
514 }
515
516
517 <INITIAL,MATRIX>{equal}                 {
518   return scan_throw(EQ);
519 }
520 <INITIAL,MATRIX>{notequal}              {
521   return scan_throw(NE);
522 }
523 <INITIAL,MATRIX>{lowerthan}             {
524   return scan_throw(LT);
525 }
526 <INITIAL,MATRIX>{greaterthan}           {
527   return scan_throw(GT);
528 }
529 <INITIAL,MATRIX>{lowerequal}            {
530   return scan_throw(LE);
531 }
532 <INITIAL,MATRIX>{greaterequal}          {
533   return scan_throw(GE);
534 }
535
536
537 <INITIAL,MATRIX>{assign}                {
538   return scan_throw(ASSIGN);
539  }
540
541
542 <INITIAL,MATRIX>{lbrack}                {
543   DEBUG("yy_push_state(MATRIX)");
544   yy_push_state(MATRIX);
545   paren_levels.push(0);
546   ParserSingleInstance::pushControlStatus(Parser::WithinMatrix);
547   return scan_throw(LBRACK);
548 }
549
550 <INITIAL>{rbrack}                               {
551   return scan_throw(RBRACK);
552 }
553
554
555 <INITIAL,MATRIX>{dot}                   {
556   return scan_throw(DOT);
557 }
558
559 <INITIAL>{next}                 {
560     ParserSingleInstance::pushControlStatus(Parser::WithinDots);
561     yy_push_state(LINEBREAK);
562 }
563
564 <INITIAL,MATRIX>{integer}               {
565   yylval.number = atof(yytext);
566 #ifdef TOKENDEV
567   std::cout << "--> [DEBUG] INTEGER : " << yytext << std::endl;
568 #endif
569 //  scan_step();
570   return scan_throw(VARINT);
571 }
572
573
574 <INITIAL,MATRIX>{floating_D}            {
575   scan_exponent_convert(yytext);
576   yylval.number = atof(yytext);
577 #ifdef TOKENDEV
578   std::cout << "--> [DEBUG] FLOATING : " << yytext << std::endl;
579 #endif
580   //scan_step();
581   return scan_throw(VARFLOAT);
582 }
583
584 <INITIAL,MATRIX>{floating_E}            {
585   yylval.number = atof(yytext);
586 #ifdef TOKENDEV
587   std::cout << "--> [DEBUG] FLOATING : " << yytext << std::endl;
588 #endif
589   //scan_step();
590   return scan_throw(VARFLOAT);
591 }
592
593 <INITIAL,MATRIX>[0-9]+[\.]/[\*^\\\/]            {
594
595   yylval.number = atof(yytext);
596 #ifdef TOKENDEV
597   std::cout << "--> [DEBUG] NUMBER WITH DOT AS LAST CHARACTER : " << yytext << std::endl;
598 #endif
599 //  scan_step();
600   unput('.');
601   yylloc.last_column--;
602   return scan_throw(NUM);
603 }
604
605 <INITIAL,MATRIX>{number}                {
606   yylval.number = atof(yytext);
607 #ifdef TOKENDEV
608   std::cout << "--> [DEBUG] NUMBER : " << yytext << std::endl;
609 #endif
610 //  scan_step();
611   return scan_throw(NUM);
612 }
613
614
615 <INITIAL,MATRIX>{little}                {
616   yylval.number = atof(yytext);
617 #ifdef TOKENDEV
618   std::cout << "--> [DEBUG] LITTLE : " << yytext << std::endl;
619 #endif
620 //  scan_step();
621   return scan_throw(NUM);
622 }
623
624
625 <INITIAL,MATRIX>{id}                    {
626     wchar_t *pwText = to_wide_string(yytext);
627     if (yytext != NULL && pwText == NULL)
628     {
629         std::string str = "Can\'t convert \'";
630         str += yytext;
631         str += "\' to UTF-8";
632         BEGIN(INITIAL);
633         yyerror(str);
634         return scan_throw(FLEX_ERROR);
635     }
636     yylval.str = new std::wstring(pwText);
637     FREE(pwText);
638 #ifdef TOKENDEV
639   std::cout << "--> [DEBUG] ID : " << yytext << std::endl;
640 #endif
641 //  scan_step();
642   return scan_throw(ID);
643 }
644
645 <INITIAL,MATRIX>{incorrect_number}              {
646     yyerror("syntax error, unexpected identifier, expecting end of file");
647     return scan_throw(FLEX_ERROR);
648 }
649
650 <INITIAL,MATRIX,SHELLMODE,BEGINID>{startblockcomment}   {
651   yylval.comment = new std::wstring();
652   comment_level = 1;
653   ParserSingleInstance::pushControlStatus(Parser::WithinBlockComment);
654   yy_push_state(REGIONCOMMENT);
655 }
656
657
658 <INITIAL,MATRIX,SHELLMODE,BEGINID>{startcomment}                {
659   pstBuffer.clear();
660   yy_push_state(LINECOMMENT);
661 }
662
663
664 <INITIAL,MATRIX,SHELLMODE>{dquote}              {
665   pstBuffer.clear();
666   str_opener_column = yylloc.first_column;
667   yy_push_state(DOUBLESTRING);
668 }
669
670
671 <INITIAL,MATRIX,SHELLMODE>{quote}                       {
672   /*
673   ** Matrix Transposition special behaviour
674   ** ID' []' toto()' are transposition call
675   */
676   if (last_token == ID
677       || last_token == RBRACK
678       || last_token == RPAREN
679       || last_token == RBRACE
680       || last_token == VARINT
681       || last_token == VARFLOAT
682       || last_token == NUM
683       || last_token == BOOLTRUE
684       || last_token == BOOLFALSE)
685   {
686       return scan_throw(QUOTE);
687   }
688   else
689   {
690       pstBuffer.clear();
691       str_opener_column = yylloc.first_column;
692       yy_push_state(SIMPLESTRING);
693   }
694 }
695
696
697 <INITIAL,MATRIX>{spaces}                {
698         scan_step();
699 }
700
701
702 <INITIAL>{newline}              {
703   yylloc.last_line += 1;
704   yylloc.last_column = 1;
705   scan_step();
706   if (last_token != EOL) {
707       return scan_throw(EOL);
708   }
709
710 }
711
712
713 <INITIAL,MATRIX>{blankline}             {
714   yylloc.last_line += 1;
715   yylloc.last_column = 1;
716   scan_step();
717   if (last_token != EOL)
718   {
719       return scan_throw(EOL);
720   }
721   scan_throw(EOL);
722 }
723
724 <INITIAL,MATRIX>{emptyline}             {
725   yylloc.last_line += 2;
726   yylloc.last_column = 1;
727   scan_step();
728   if (last_token != EOL)
729   {
730       return scan_throw(EOL);
731   }
732   scan_throw(EOL);
733 }
734 .                                       {
735     std::string str = "Unexpected token \'";
736     str += yytext;
737     str += "\'";
738     BEGIN(INITIAL);
739     yyerror(str);
740     return scan_throw(FLEX_ERROR);
741 }
742
743
744 <MATRIX>
745 {
746   {lparen} {
747     ++paren_levels.top();
748     return scan_throw(LPAREN);
749   }
750
751   {rparen} {
752     --paren_levels.top();
753     return scan_throw(RPAREN);
754   }
755
756   {spaces}+{lparen} {
757       unput(yytext[yyleng - 1]);
758       --yylloc.last_column;
759       if (last_token == ID
760           || last_token == RPAREN
761           || last_token == QUOTE
762           || last_token == VARINT
763           || last_token == VARFLOAT
764           || last_token == NUM)
765       {
766           return scan_throw(COMMA);
767       }
768   }
769
770   {spaces}*{colon}{spaces}* {
771       return scan_throw(COLON);
772   }
773
774   {newline} {
775       yylloc.last_line += 1;
776       yylloc.last_column = 1;
777       if(last_token != DOTS && last_token != EOL)
778       {
779           return scan_throw(EOL);
780       }
781       scan_throw(EOL);
782   }
783
784   {spaces}+{quote} {
785       unput('\'');
786       yylloc.last_column--;
787       if (last_token == ID
788           || last_token == RPAREN
789           || last_token == QUOTE)
790       {
791           return scan_throw(COMMA);
792       }
793   }
794
795   {rbrack}                              {
796     DEBUG("yy_pop_state()");
797     yy_pop_state();
798     paren_levels.pop();
799     ParserSingleInstance::popControlStatus();
800     return scan_throw(RBRACK);
801   }
802
803   {rbrace}                              {
804     yy_pop_state();
805     paren_levels.pop();
806     ParserSingleInstance::popControlStatus();
807     return scan_throw(RBRACE);
808   }
809
810   {plus}                                |
811   {spaces}{plus}{spaces}                {
812     // _+_ is always meaning a PLUS token
813     // + alone is a plus if and only if it does not
814     // fall into the {spaces}{plus} rule (in matrices space is coding)
815     // as Flex is greedy the {plus} rule is only applied
816     // if no {spaces}{plus} is found
817     // Examples:
818     // ========
819     // [1 + 2 3] must be understood as [(1+2), 3]
820     // [1 +2 3] must be understood as [1, 2, 3]
821     // [1 +...
822     // 2] must be understood as [(1+2)]
823     return scan_throw(PLUS);
824   }
825
826   {minus}                               |
827   {spaces}{minus}{spaces}               {
828     // _-_ is always meaning a MINUS token
829     // - alone is a MINUS only if and only if it does not
830     // fall into the {spaces}{minus} rule (in matrices space is coding)
831     // as Flex is greedy the {minus} rule is only applied
832     // if no {spaces}{minus} is found
833     // Examples:
834     // ========
835     // [1 - 2 3] must be understood as [(1-2), 3]
836     // [1 -2 3] must be understood as [1, -2, 3]
837     // [1 -...
838     // 2] must be understood as [(1-2)]
839     return scan_throw(MINUS);
840   }
841
842   {spaces}{plus}                        {
843     // This rule is made to take into account the coding spaces in matrices.
844     // It is important to distinguish between a space coding a matrix column separator
845     // and a simple non coding space around the PLUS operator
846     // Examples
847     // ========
848     // [a + b] == [(a + b)]
849     // but [a +b] == [a, +b] and plus here is unary and is not removed, as unary plus
850     // is not necessary defined for all data types (http://bugzilla.scilab.org/show_bug.cgi?id=15850)
851     // A priori, the space *is* coding
852
853     unput('+');
854     yylloc.last_column--;
855     if (last_token != LBRACK
856        && last_token != EOL
857        && last_token != SEMI
858        && last_token != COMMA
859        && last_token != DOTTIMES
860        && last_token != DOTRDIVIDE
861        && last_token != DOTLDIVIDE
862        && last_token != DOTPOWER
863        && last_token != MINUS
864        && last_token != PLUS
865        && last_token != TIMES
866        && last_token != RDIVIDE
867        && last_token != LDIVIDE
868        && last_token != POWER
869        && last_token != KRONTIMES
870        && last_token != KRONRDIVIDE
871        && last_token != KRONLDIVIDE
872        && last_token != EQ
873        && last_token != NE
874        && last_token != LT
875        && last_token != GT
876        && last_token != LE
877        && last_token != GE
878       && paren_levels.top() == 0)
879    {
880        return scan_throw(COMMA);
881    }
882   }
883
884   {spaces}{minus}                       {
885     // See {spaces}{plus} rule for the rationale
886
887     unput('-');
888     yylloc.last_column--;
889     if (last_token != LBRACK
890        && last_token != EOL
891        && last_token != SEMI
892        && last_token != COMMA
893        && last_token != DOTTIMES
894        && last_token != DOTRDIVIDE
895        && last_token != DOTLDIVIDE
896        && last_token != DOTPOWER
897        && last_token != MINUS
898        && last_token != PLUS
899        && last_token != TIMES
900        && last_token != RDIVIDE
901        && last_token != LDIVIDE
902        && last_token != POWER
903        && last_token != KRONTIMES
904        && last_token != KRONRDIVIDE
905        && last_token != KRONLDIVIDE
906        && last_token != EQ
907        && last_token != NE
908        && last_token != LT
909        && last_token != GT
910        && last_token != LE
911        && last_token != GE
912        && paren_levels.top() == 0)
913    {
914        return scan_throw(COMMA);
915    }
916   }
917
918   .                                     {
919     std::string str = "Unexpected token \'";
920     str += yytext;
921     str += "\' within a matrix.";
922     BEGIN(INITIAL);
923     yyerror(str);
924     return scan_throw(FLEX_ERROR);
925   }
926
927   /* {next} rules
928    * ============
929    * Scilab can perform a line continuation with the ..
930    * In matrices as space may be coding extra care must be taken when parsing {next}
931    * Some states must be preserved to parse next line and to revert to a proper state
932    * after the ... // comments or ... \/* comments *\/
933    */
934
935   {spaces}*{plus}{next} {
936              // This rule is made to take into account a +... without spaces after plus
937              // if one simply ignores the next a situation like this could arise
938              // Example
939              // =======
940              // A = [1 +...
941              // 2] 
942              //
943              // what is meant by the user [1 +2] ? or [1 + 2]
944              // simply ignoring the ... would yield the 1st situation [1, 2]
945              // We consider this is NOT proper and instead that the user meant a binary plus
946              // split is two lines
947              // The same rationale applies to minus.
948
949              linebreak_stored_space = FALSE; // no spaces before ...
950              linebreak_stored_token = PLUS; // keep last token to restore
951              ParserSingleInstance::pushControlStatus(Parser::WithinDots);
952              yy_push_state(LINEBREAK);
953              return scan_throw(PLUS);
954          }
955
956   {spaces}*{minus}{next} {
957              // see {spaces}*{minus}{next} for the rationale
958
959              linebreak_stored_space = FALSE; // no spaces before ...
960              linebreak_stored_token = MINUS; // keep last token to restore
961              ParserSingleInstance::pushControlStatus(Parser::WithinDots);
962              yy_push_state(LINEBREAK);
963              return scan_throw(MINUS);
964          }
965
966   {next} {
967              // Store the state of the previously scanned token for next rule
968              // Only considerations of coding spaces is important for the parser
969
970              linebreak_stored_space = FALSE; // no spaces before ...
971              linebreak_stored_token = last_token; // keep last token to restore state
972              ParserSingleInstance::pushControlStatus(Parser::WithinDots);
973              yy_push_state(LINEBREAK);
974          }
975
976   {spaces}{next} {
977              // Store the state of the previously scanned token for next rule
978              // Only considerations of coding spaces is important for the parser
979
980              linebreak_stored_space = TRUE; // no spaces before ...
981              linebreak_stored_token = last_token; // keep last token to restore state
982              ParserSingleInstance::pushControlStatus(Parser::WithinDots);
983              yy_push_state(LINEBREAK);
984          }
985
986   <<EOF>>       {
987       yy_pop_state();
988       paren_levels.pop();
989   }
990 }
991
992 <LINEBREAK>
993 {
994   {newline}                             {
995     yylloc.last_line += 1;
996     yylloc.last_column = 1;
997     scan_step();
998     last_token = linebreak_stored_token;
999     if (linebreak_stored_space)
1000     {
1001         // This is important to restore coding spaces as if ... was not present
1002         unput(' ');
1003         linebreak_stored_space = FALSE;
1004     }
1005     yy_pop_state();
1006     ParserSingleInstance::popControlStatus();
1007   }
1008
1009   {startblockcomment}                   {
1010     yylval.comment = new std::wstring();
1011     comment_level = 1;
1012     ParserSingleInstance::pushControlStatus(Parser::WithinBlockComment);
1013     yy_push_state(REGIONCOMMENT);
1014   }
1015
1016   {startcomment}                        {
1017     scan_throw(DOTS);
1018     pstBuffer.clear();
1019     yy_push_state(LINECOMMENT);
1020   }
1021
1022   {spaces}                              {
1023       /* Do nothing... */
1024   }
1025
1026   <<EOF>>       {
1027       yy_pop_state();
1028   }
1029   .                                     {
1030     // The following case is not handled by the parser
1031     // a line of code ... /* some multiline
1032     // comments */ continued here;
1033     // without the special case telling we are after comments
1034     // will generate the error as follows:
1035
1036     // Any characters after ... yields to an error
1037     std::string str = "Unexpected token \'";
1038     str += yytext;
1039     str += "\' after line break with .. or ...";
1040     yy_pop_state();
1041     ParserSingleInstance::popControlStatus();
1042     BEGIN(INITIAL);
1043     yyerror(str);
1044     return scan_throw(FLEX_ERROR);
1045   }
1046 }
1047
1048
1049 <LINECOMMENT>
1050 {
1051   {newline}     {
1052     //yylloc.last_line += 1;
1053     //yylloc.last_column = 1;
1054     //scan_step();
1055     yy_pop_state();
1056     for (int i = yyleng - 1 ; i >= 0 ; --i)
1057     {
1058         //std::cerr << "Unputting i = {" << i << "}" << std::endl;
1059         //std::cerr << "Unputting {" << yytext[i] << "}" << std::endl;
1060         unput(yytext[i]);
1061         yylloc.last_column--;
1062     }
1063     /*
1064     ** To forgot comments after lines break
1065     */
1066     if (last_token != DOTS)
1067     {
1068         //std::cerr << "pstBuffer = {" << *pstBuffer << "}" << std::endl;
1069         //std::cerr << "pstBuffer->c_str() = {" << pstBuffer->c_str() << "}" << std::endl;
1070         wchar_t *pwstBuffer = to_wide_string(pstBuffer.c_str());
1071         //std::wcerr << L"pwstBuffer = W{" << pwstBuffer << L"}" << std::endl;
1072         if (pstBuffer.c_str() != NULL && pwstBuffer == NULL)
1073         {
1074             pstBuffer.clear();
1075             std::string str = "Can\'t convert \'";
1076             str += pstBuffer.c_str();
1077             str += "\' to UTF-8";
1078             BEGIN(INITIAL);
1079             yyerror(str);
1080             return scan_throw(FLEX_ERROR);
1081         }
1082         yylval.comment = new std::wstring(pwstBuffer);
1083         pstBuffer.clear();
1084         FREE (pwstBuffer);
1085         return scan_throw(COMMENT);
1086     }
1087     else
1088     {
1089         pstBuffer.clear();
1090     }
1091   }
1092
1093   <<EOF>>       {
1094     yy_pop_state();
1095     wchar_t *pwstBuffer = to_wide_string(pstBuffer.c_str());
1096     if (pstBuffer.c_str() != NULL && pwstBuffer == NULL)
1097     {
1098         pstBuffer.clear();
1099         std::string str = "Can\'t convert \'";
1100         str += pstBuffer.c_str();
1101         str += "\' to UTF-8";
1102         BEGIN(INITIAL);
1103         yyerror(str);
1104         return scan_throw(FLEX_ERROR);
1105     }
1106     yylval.comment = new std::wstring(pwstBuffer);
1107     pstBuffer.clear();
1108     FREE (pwstBuffer);
1109     return scan_throw(COMMENT);
1110   }
1111
1112   {char_in_line_comment}         {
1113       // Put the char in a temporary CHAR buffer to go through UTF-8 trouble
1114       // only translate to WCHAR_T when popping state.
1115       pstBuffer += yytext;
1116   }
1117 }
1118
1119
1120 <REGIONCOMMENT>
1121 {
1122   {endblockcomment}                             {
1123     --comment_level;
1124     if (comment_level == 0) {
1125       ParserSingleInstance::popControlStatus();
1126       yy_pop_state();
1127       //return scan_throw(BLOCKCOMMENT);
1128     }
1129   }
1130
1131   {startblockcomment}                           {
1132     ++comment_level;
1133     yy_push_state(REGIONCOMMENT);
1134   }
1135
1136   {newline}                                     {
1137     yylloc.last_line += 1;
1138     yylloc.last_column = 1;
1139     scan_step();
1140     *yylval.comment += L"\n//";
1141   }
1142
1143   {char_in_comment}                             |
1144   .                                             {
1145       wchar_t *pwText = to_wide_string(yytext);
1146       *yylval.comment += std::wstring(pwText);
1147       FREE(pwText);
1148   }
1149
1150  <<EOF>>                                        {
1151       yy_pop_state();
1152 //    std::string str = "unexpected end of file in a comment";
1153 //    scan_error(str);
1154   }
1155 }
1156
1157
1158 <SIMPLESTRING>
1159 {
1160   {dquote}{dquote}                              {
1161     pstBuffer += "\"";
1162   }
1163
1164   {dquote}{quote}                               {
1165     pstBuffer += "'";
1166   }
1167
1168   {quote}{dquote}                               {
1169     pstBuffer += "\"";
1170   }
1171
1172   {quote}{quote}                                {
1173     pstBuffer += "'";
1174   }
1175
1176   {quote}                                       {
1177     yy_pop_state();
1178     //scan_step();
1179     wchar_t *pwstBuffer = to_wide_string(pstBuffer.c_str());
1180     if (pstBuffer.c_str() != NULL && pwstBuffer == NULL)
1181     {
1182         pstBuffer.clear();
1183         std::string str = "Can\'t convert \'";
1184         str += pstBuffer.c_str();
1185         str += "\' to UTF-8";
1186         BEGIN(INITIAL);
1187         yyerror(str);
1188         return scan_throw(FLEX_ERROR);
1189     }
1190     yylval.str = new std::wstring(pwstBuffer);
1191     pstBuffer.clear();
1192     FREE(pwstBuffer);
1193     yylloc.first_column = str_opener_column;
1194     return scan_throw(STR);
1195   }
1196
1197   {dquote}                  {
1198     pstBuffer.clear();
1199     BEGIN(INITIAL);
1200     yyerror("Heterogeneous string detected, starting with \' and ending with \".");
1201     return scan_throw(FLEX_ERROR);
1202   }
1203
1204   {newline}                                     {
1205     pstBuffer.clear();
1206     yylloc.last_line += 1;
1207     yylloc.last_column = 1;
1208     BEGIN(INITIAL);
1209     ParserSingleInstance::popControlStatus();
1210     yyerror("Unexpected end of line in a string.");
1211     return scan_throw(FLEX_ERROR);
1212   }
1213
1214   <<EOF>>                                       {
1215     pstBuffer.clear();
1216     BEGIN(INITIAL);
1217     yyerror("Unexpected end of file in a string.");
1218     return scan_throw(FLEX_ERROR);
1219   }
1220
1221   {in_string}                                           |
1222   .                                                     {
1223     //scan_step();
1224     pstBuffer += yytext;
1225   }
1226 }
1227
1228
1229 <DOUBLESTRING>
1230 {
1231   {dquote}{dquote}                              {
1232     pstBuffer += "\"";
1233   }
1234
1235   {dquote}{quote}                               {
1236     pstBuffer += "'";
1237   }
1238
1239   {quote}{dquote}               {
1240     pstBuffer += "\"";
1241   }
1242
1243   {quote}{quote}                                {
1244     pstBuffer += "'";
1245   }
1246
1247   {dquote}                      {
1248     yy_pop_state();
1249     //scan_step();
1250     wchar_t *pwstBuffer = to_wide_string(pstBuffer.c_str());
1251     if (pstBuffer.c_str() != NULL && pwstBuffer == NULL)
1252     {
1253         pstBuffer.clear();
1254         std::string str = "Can\'t convert \'";
1255         str += pstBuffer.c_str();
1256         str += "\' to UTF-8";
1257         BEGIN(INITIAL);
1258         yyerror(str);
1259         return scan_throw(FLEX_ERROR);
1260     }
1261     yylval.str = new std::wstring(pwstBuffer);
1262     pstBuffer.clear();
1263     FREE(pwstBuffer);
1264     yylloc.first_column = str_opener_column;
1265     return scan_throw(STR);
1266   }
1267
1268   {quote}                  {
1269     pstBuffer.clear();
1270     BEGIN(INITIAL);
1271     yyerror("Heterogeneous string detected, starting with \" and ending with \'.");
1272     return scan_throw(FLEX_ERROR);
1273   }
1274
1275   {newline} {
1276     pstBuffer.clear();
1277     yylloc.last_line += 1;
1278     yylloc.last_column = 1;
1279     ParserSingleInstance::popControlStatus();
1280     BEGIN(INITIAL);
1281     yyerror("Unexpected end of line in a string.");
1282     return scan_throw(FLEX_ERROR);
1283   }
1284
1285   <<EOF>>   {
1286     pstBuffer.clear();
1287     BEGIN(INITIAL);
1288     yyerror("Unexpected end of file in a string.");
1289     return scan_throw(FLEX_ERROR);
1290   }
1291
1292   {in_string}         |
1293   .                   {
1294    //scan_step();
1295    pstBuffer += yytext;
1296   }
1297 }
1298
1299
1300 <SHELLMODE>
1301 {
1302     {spaces}                    {
1303         if (last_token == ID)
1304         {
1305             scan_throw(SPACES);
1306             //return ID;
1307         }
1308     }
1309
1310     {semicolon}                 {
1311         BEGIN(INITIAL);
1312         scan_step();
1313         return scan_throw(SEMI);
1314     }
1315
1316     {comma}                     {
1317         BEGIN(INITIAL);
1318         scan_step();
1319         return scan_throw(COMMA);
1320     }
1321
1322     {newline}                   {
1323         BEGIN(INITIAL);
1324         yylloc.last_line += 1;
1325         yylloc.last_column = 1;
1326         scan_step();
1327         return scan_throw(EOL);
1328     }
1329
1330     {assign} {
1331         if (last_token == STR || last_token == SPACES)
1332         {
1333             wchar_t *pwText = to_wide_string(yytext);
1334             yylval.str = new std::wstring(pwText);
1335             FREE(pwText);
1336             return scan_throw(STR);
1337         }
1338         else
1339         {
1340             BEGIN(INITIAL);
1341             return scan_throw(ASSIGN);
1342         }
1343     }
1344
1345     {lparen} {
1346         if (last_token == STR || last_token == SPACES)
1347         {
1348             wchar_t *pwText = to_wide_string(yytext);
1349             yylval.str = new std::wstring(pwText);
1350             FREE(pwText);
1351             return scan_throw(STR);
1352         }
1353         else
1354         {
1355             BEGIN(INITIAL);
1356             return scan_throw(LPAREN);
1357         }
1358     }
1359
1360     {lowerthan} {
1361         if (last_token == STR || last_token == SPACES)
1362         {
1363             wchar_t *pwText = to_wide_string(yytext);
1364             yylval.str = new std::wstring(pwText);
1365             FREE(pwText);
1366             return scan_throw(STR);
1367         }
1368         else
1369         {
1370             BEGIN(INITIAL);
1371             return scan_throw(LT);
1372         }
1373     }
1374
1375     {greaterthan} {
1376         if (last_token == STR || last_token == SPACES)
1377         {
1378             wchar_t *pwText = to_wide_string(yytext);
1379             yylval.str = new std::wstring(pwText);
1380             FREE(pwText);
1381             return scan_throw(STR);
1382         }
1383         else
1384         {
1385             BEGIN(INITIAL);
1386             return scan_throw(GT);
1387         }
1388     }
1389
1390     {boolnot} {
1391         if (last_token == STR || last_token == SPACES)
1392         {
1393             wchar_t *pwText = to_wide_string(yytext);
1394             yylval.str = new std::wstring(pwText);
1395             FREE(pwText);
1396             return scan_throw(STR);
1397         }
1398         else
1399         {
1400             BEGIN(INITIAL);
1401             return scan_throw(NOT);
1402         }
1403     }
1404
1405
1406     [^ \t\v\f\r\n,;'"]+               {
1407         wchar_t *pwText = to_wide_string(yytext);
1408         yylval.str = new std::wstring(pwText);
1409         FREE(pwText);
1410         return scan_throw(STR);
1411     }
1412
1413     <<EOF>>                     {
1414         BEGIN(INITIAL);
1415     }
1416
1417 }
1418
1419 %%
1420
1421 int scan_throw(int token) {
1422   last_token = token;
1423 #ifdef DEV
1424   std::cout << "--> [DEBUG] TOKEN : " << token << " - " << token_to_string(token) << std::endl;
1425 #endif
1426   return token;
1427 }
1428
1429 int get_last_token() {
1430     return last_token;
1431 }
1432
1433 void scan_step() {
1434   yylloc.first_line = yylloc.last_line;
1435   yylloc.first_column = yylloc.last_column;
1436 }
1437
1438 /*
1439 ** convert floating numbers to C standard
1440 ** 1.2d-3 -> 1.2e-3
1441 ** 1.2D-3 -> 1.2e-3
1442 */
1443 void scan_exponent_convert(char *in)
1444 {
1445   for (; *in != 'd' && *in != 'D'; ++in);
1446   *in = 'e';
1447 }
1448
1449 #ifdef _MSC_VER
1450 int isatty (int desc)
1451 {
1452   return 0;
1453 }
1454 #endif
1455
1456 #ifdef DEV
1457 std::string token_to_string(int token)
1458 {
1459     std::string str;
1460     switch(token)
1461     {
1462         case AND :                   str = "AND";
1463                                      break;
1464         case ASSIGN :                str = "ASSIGN";
1465                                      break;
1466         case BOOLFALSE :             str = "BOOLFALSE";
1467                                      break;
1468         case BOOLTRUE :              str = "BOOLTRUE";
1469                                      break;
1470         case BREAK :                 str = "BREAK";
1471                                      break;
1472         case CASE :                  str = "CASE";
1473                                      break;
1474         case CATCH :                 str = "CATCH";
1475                                      break;
1476         case COLON :                 str = "COLON";
1477                                      break;
1478         case COMMA :                 str = "COMMA";
1479                                      break;
1480         case COMMENT :               str = "COMMENT";
1481                                      break;
1482         case CONTINUE :              str = "CONTINUE";
1483                                      break;
1484         case CONTROLLDIVIDE :        str = "CONTROLLDIVIDE";
1485                                      break;
1486         case CONTROLRDIVIDE :        str = "CONTROLRDIVIDE";
1487                                      break;
1488         case CONTROLTIMES :          str = "CONTROLTIMES";
1489                                      break;
1490         case DO :                    str = "DO";
1491                                      break;
1492         case DOLLAR :                str = "DOLLAR";
1493                                      break;
1494         case DOT :                   str = "DOT";
1495                                      break;
1496         case DOTLDIVIDE :            str = "DOTLDIVIDE";
1497                                      break;
1498         case DOTPOWER :              str = "DOTPOWER";
1499                                      break;
1500         case DOTQUOTE :              str = "DOTQUOTE";
1501                                      break;
1502         case DOTRDIVIDE :            str = "DOTRDIVIDE";
1503                                      break;
1504         case DOTS :                  str = "DOTS";
1505                                      break;
1506         case DOTTIMES :              str = "DOTTIMES";
1507                                      break;
1508         case ELSE :                  str = "ELSE";
1509                                      break;
1510         case ELSEIF :                str = "ELSEIF";
1511                                      break;
1512         case END :                   str = "END";
1513                                      break;
1514         case ENDFUNCTION :           str = "ENDFUNCTION";
1515                                      break;
1516         case EOL :                   str = "EOL";
1517                                      break;
1518         case EQ :                    str = "EQ";
1519                                      break;
1520         case FLEX_ERROR :            str = "FLEX_ERROR";
1521                                      break;
1522         case FOR :                   str = "FOR";
1523                                      break;
1524         case FUNCTION :              str = "FUNCTION";
1525                                      break;
1526         case GE :                    str = "GE";
1527                                      break;
1528         case GT :                    str = "GT";
1529                                      break;
1530         case ID :                    str = "ID";
1531                                      break;
1532         case IF :                    str = "IF";
1533                                      break;
1534         case KRONLDIVIDE :           str = "KRONLDIVIDE";
1535                                      break;
1536         case KRONRDIVIDE :           str = "KRONRDIVIDE";
1537                                      break;
1538         case KRONTIMES :             str = "KRONTIMES";
1539                                      break;
1540         case LBRACE :                str = "LBRACE";
1541                                      break;
1542         case LBRACK :                str = "LBRACK";
1543                                      break;
1544         case LDIVIDE :               str = "LDIVIDE";
1545                                      break;
1546         case LE :                    str = "LE";
1547                                      break;
1548         case LPAREN :                str = "LPAREN";
1549                                      break;
1550         case LT :                    str = "LT";
1551                                      break;
1552         case MINUS :                 str = "MINUS";
1553                                      break;
1554         case NE :                    str = "NE";
1555                                      break;
1556         case NOT :                   str = "NOT";
1557                                      break;
1558         case NUM :                   str = "NUM";
1559                                      break;
1560         case OR :                    str = "OR";
1561                                      break;
1562         case OROR :                  str = "OROR";
1563                                      break;
1564         case OTHERWISE :             str = "OTHERWISE";
1565                                      break;
1566         case PLUS :                  str = "PLUS";
1567                                      break;
1568         case POWER :                 str = "POWER";
1569                                      break;
1570         case QUOTE :                 str = "QUOTE";
1571                                      break;
1572         case RBRACE :                str = "RBRACE";
1573                                      break;
1574         case RBRACK :                str = "RBRACK";
1575                                      break;
1576         case RDIVIDE :               str = "RDIVIDE";
1577                                      break;
1578         case RETURN :                str = "RETURN";
1579                                      break;
1580         case RPAREN :                str = "RPAREN";
1581                                      break;
1582         case SELECT :                str = "SELECT";
1583                                      break;
1584         case SEMI :                  str = "SEMI";
1585                                      break;
1586         case SPACES :                str = "SPACES";
1587                                      break;
1588         case STR :                   str = "STR";
1589                                      break;
1590         case SWITCH :                str = "SWITCH";
1591                                      break;
1592         case THEN :                  str = "THEN";
1593                                      break;
1594         case TIMES :                 str = "TIMES";
1595                                      break;
1596         case TRY :                   str = "TRY";
1597                                      break;
1598         case VARFLOAT :              str = "VARFLOAT";
1599                                      break;
1600         case VARINT :                str = "VARINT";
1601                                      break;
1602         case WHILE :                 str = "WHILE";
1603                                      break;
1604         default :                    str = "UNKNOWN";
1605                                      break;
1606     }
1607     return str;
1608
1609 }
1610 #endif