fix 'some' memory leaks @startup
[scilab.git] / scilab / modules / ast / src / cpp / parse / flex / scanscilab.ll
1 %{                                                            /* -*- C++ -*- */
2 /*
3  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
4  *  Copyright (C) 2008-2012 - Scilab Enterprises - Bruno JOFRET
5  *
6  *  This file must be used under the terms of the CeCILL.
7  *  This source file is licensed as described in the file COPYING, which
8  *  you should have received as part of this distribution.  The terms
9  *  are also available at
10  *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
11  *
12  */
13 #include "isatty.hxx"
14 #include "parse.hxx"
15 #include "parser_private.hxx"
16
17 #include "context.hxx"
18
19 extern "C"
20 {
21 #include "charEncoding.h"
22 #include "sci_malloc.h"
23 }
24
25 static int comment_level = 0;
26 static int paren_level = 0;
27 static int last_token = 0;
28 static int exit_status = PARSE_ERROR;
29 static std::string current_file;
30 static std::string program_name;
31
32 static std::string *pstBuffer;
33
34 #define YY_USER_ACTION                          \
35  yylloc.last_column += yyleng;
36
37 /* -*- Verbose Special Debug -*- */
38 //#define DEV
39 //#define TOKENDEV
40
41 #ifdef DEV
42 #define DEBUG(x) std::cout << "[DEBUG] " << x << std::endl;
43 #else
44 #define DEBUG(x) /* Nothing */
45 #endif
46
47 %}
48
49 %option stack
50 %option noyywrap
51
52 %x SIMPLESTRING
53 %x DOUBLESTRING
54 %x REGIONCOMMENT
55 %x LINECOMMENT
56 %x LINEBREAK
57
58 %x MATRIX
59
60 %x SHELLMODE
61 %x BEGINID
62
63 spaces                  [ \t\v\f]+
64 integer                 [0-9]+
65 number                  [0-9]+[\.][0-9]*
66 little                  \.[0-9]+
67
68 floating                ({little}|{number}|{integer})[deDE][+-]?{integer}
69
70 hex             [0]x[0-9a-fA-F]+
71 oct             [0]o[0-7]+
72
73
74 utf2            ([\xC2-\xDF][\x80-\xBF])
75 utf31           ([\xE0][\xA0-\xBF][\x80-\xBF])
76 utf32           ([\xE1-\xEC][\x80-\xBF][\x80-\xBF])
77 utf33           ([\xED][\x80-\x9F][\x80-\xBF])
78 utf34           ([\xEE-\xEF][\x80-\xBF][\x80-\xBF])
79 utf41           ([\xF0][\x90-\xBF][\x80-\xBF][\x80-\xBF])
80 utf42           ([\xF1-\xF3][\x80-\xBF][\x80-\xBF][\x80-\xBF])
81 utf43           ([\xF4][\x80-\x8F][\x80-\xBF][\x80-\xBF])
82
83 utf3            ({utf31}|{utf32}|{utf33}|{utf34})
84 utf4            ({utf41}|{utf42}|{utf43})
85
86 utf             ({utf2}|{utf3}|{utf4})
87 id              ((([a-zA-Z_%#?]|{utf})([a-zA-Z_0-9#?$]|{utf})*)|([$]([a-zA-Z_0-9#?$]|{utf})+))
88
89
90 newline                 ("\r"|"\n"|"\r\n")
91 blankline               {spaces}+{newline}
92 emptyline       {newline}({spaces}|[,;])+{newline}
93 next                    \.\.+
94
95 boolnot                 ("@"|"~")
96 booltrue                ("%t"|"%T")
97 boolfalse               ("%f"|"%F")
98 booland                 ("&")
99 boolandand              ("&&")
100 boolor                  ("|")
101 booloror                ("||")
102
103 lbrack                  "["
104 rbrack                  "]"
105
106 lparen                  "("
107 rparen                  ")"
108
109 lbrace                  "{"
110 rbrace                  "}"
111
112 dollar                  "$"
113
114 semicolon               ";"
115 comma                   ","
116 colon                   ":"
117
118 startcomment            "//"
119 startblockcomment       "/*"
120 endblockcomment         "*/"
121
122 dquote                  "\""
123 quote                   "'"
124
125 dot             "."
126 dotquote                ".'"
127 dottimes                ".*"
128 dotrdivide              "./"
129 dotldivide              ".\\"
130 dotpower                (".^"|".**")
131
132 plus                    "+"
133 minus                   "-"
134 rdivide                 "/"
135 ldivide                 "\\"
136 times                   "*"
137 power                   ("^"|"**")
138
139 equal                   "="{spaces}*"="
140 notequal                ("~"{spaces}*"="|"@"{spaces}*"="|"<"{spaces}*">")
141 lowerthan               "<"
142 greaterthan             ">"
143 lowerequal              "<"{spaces}*"="
144 greaterequal            ">"{spaces}*"="
145
146 krontimes               ".*."
147 kronrdivide             "./."
148 kronldivide             ".\\."
149
150 controltimes    ("*."[^0-9])
151 controlrdivide  ("/."[^0-9])
152 controlldivide  ("\\."[^0-9])
153
154 assign                  "="
155
156 %%
157
158 <INITIAL,BEGINID>"if"            {
159         if (last_token != DOT)
160     {
161         ParserSingleInstance::pushControlStatus(Parser::WithinIf);
162     }
163     DEBUG("BEGIN(INITIAL)");
164     BEGIN(INITIAL);
165     return scan_throw(IF);
166 }
167
168 <INITIAL,BEGINID>"then"          {
169     DEBUG("BEGIN(INITIAL)");
170     BEGIN(INITIAL);
171     return scan_throw(THEN);
172 }
173
174 <INITIAL,BEGINID>"else"          {
175         if (last_token != DOT)
176     {
177         // Pop to step out IF
178         ParserSingleInstance::popControlStatus();
179         ParserSingleInstance::pushControlStatus(Parser::WithinElse);
180     }
181     DEBUG("BEGIN(INITIAL)");
182     BEGIN(INITIAL);
183         return scan_throw(ELSE);
184 }
185
186 <INITIAL,BEGINID>"elseif" {
187         if (last_token != DOT)
188     {
189         ParserSingleInstance::popControlStatus();
190         ParserSingleInstance::pushControlStatus(Parser::WithinElseIf);
191     }
192     DEBUG("BEGIN(INITIAL)");
193     BEGIN(INITIAL);
194         return scan_throw(ELSEIF);
195 }
196
197 <INITIAL,BEGINID>"end"          {
198         if (last_token != DOT)
199     {
200         ParserSingleInstance::popControlStatus();
201     }
202     DEBUG("BEGIN(INITIAL)");
203     BEGIN(INITIAL);
204     return scan_throw(END);
205 }
206
207 <INITIAL,BEGINID>"select"       {
208         if (last_token != DOT)
209     {
210         ParserSingleInstance::pushControlStatus(Parser::WithinSelect);
211     }
212     DEBUG("BEGIN(INITIAL)");
213     BEGIN(INITIAL);
214     return scan_throw(SELECT);
215 }
216
217 <INITIAL,BEGINID>"switch"       {
218         if (last_token != DOT)
219     {
220         ParserSingleInstance::pushControlStatus(Parser::WithinSwitch);
221     }
222     DEBUG("BEGIN(INITIAL)");
223     BEGIN(INITIAL);
224     return scan_throw(SWITCH);
225 }
226
227 <INITIAL,BEGINID>"otherwise" {
228         if (last_token != DOT)
229     {
230         ParserSingleInstance::popControlStatus();
231         ParserSingleInstance::pushControlStatus(Parser::WithinOtherwise);
232     }
233     DEBUG("BEGIN(INITIAL)");
234     BEGIN(INITIAL);
235         return scan_throw(OTHERWISE);
236 }
237
238 <INITIAL,BEGINID>"case"         {
239         if (last_token != DOT)
240     {
241         ParserSingleInstance::popControlStatus();
242         ParserSingleInstance::pushControlStatus(Parser::WithinCase);
243     }
244     DEBUG("BEGIN(INITIAL)");
245     BEGIN(INITIAL);
246     return scan_throw(CASE);
247 }
248
249 <INITIAL,BEGINID>"function" {
250         if (last_token != DOT)
251     {
252         ParserSingleInstance::pushControlStatus(Parser::WithinFunction);
253     }
254     DEBUG("BEGIN(INITIAL)");
255     BEGIN(INITIAL);
256     return scan_throw(FUNCTION);
257 }
258
259 <INITIAL,BEGINID>"endfunction" {
260         if (last_token != DOT)
261     {
262         ParserSingleInstance::popControlStatus();
263     }
264     DEBUG("BEGIN(INITIAL)");
265     BEGIN(INITIAL);
266         return scan_throw(ENDFUNCTION);
267 }
268
269 <INITIAL,BEGINID>"#function"    {
270         if (last_token != DOT)
271     {
272         ParserSingleInstance::pushControlStatus(Parser::WithinFunction);
273     }
274     DEBUG("BEGIN(INITIAL)");
275     BEGIN(INITIAL);
276         return scan_throw(HIDDENFUNCTION);
277 }
278
279 <INITIAL,BEGINID>"hidden"       {
280     DEBUG("BEGIN(INITIAL)");
281         BEGIN(INITIAL);
282     return scan_throw(HIDDEN);
283 }
284
285 <INITIAL,BEGINID>"for" {
286         if (last_token != DOT)
287     {
288         ParserSingleInstance::pushControlStatus(Parser::WithinFor);
289     }
290     BEGIN(INITIAL);
291     return scan_throw(FOR);
292 }
293
294 <INITIAL,BEGINID>"while"        {
295         if (last_token != DOT)
296     {
297         ParserSingleInstance::pushControlStatus(Parser::WithinWhile);
298     }
299         BEGIN(INITIAL);
300         return scan_throw(WHILE);
301 }
302
303 <INITIAL,BEGINID>"do"           {
304         BEGIN(INITIAL);
305     return scan_throw(DO);
306 }
307
308 <INITIAL,BEGINID>"break"                {
309         BEGIN(INITIAL);
310         return scan_throw(BREAK);
311 }
312
313 <INITIAL,BEGINID>"continue"             {
314         BEGIN(INITIAL);
315         return scan_throw(CONTINUE);
316 }
317
318 <INITIAL,BEGINID>"try" {
319         ParserSingleInstance::pushControlStatus(Parser::WithinTry);
320         BEGIN(INITIAL);
321         return scan_throw(TRY);
322 }
323
324 <INITIAL,BEGINID>"catch" {
325     // Pop to step out TRY
326         ParserSingleInstance::popControlStatus();
327         ParserSingleInstance::pushControlStatus(Parser::WithinCatch);
328         BEGIN(INITIAL);
329         return scan_throw(CATCH);
330 }
331
332 <INITIAL,BEGINID>"return"       {
333     BEGIN(INITIAL);
334     return scan_throw(RETURN);
335 }
336
337 <INITIAL,BEGINID>"resume"       {
338     BEGIN(INITIAL);
339     return scan_throw(RETURN);
340 }
341
342 ^{spaces}*/({id}){spaces}[^ \t\v\f(=<>~@] {
343         BEGIN(BEGINID);
344 }
345
346 <BEGINID>
347 {
348     {id}                        {
349         wchar_t *pwText = to_wide_string(yytext);
350         if (yytext != NULL && pwText == NULL)
351         {
352             std::string str = "can not convert'";
353             str += yytext;
354             str += "' to UTF-8";
355             exit_status = SCAN_ERROR;
356             scan_error("can not convert string to UTF-8");
357         }
358         yylval.str = new std::wstring(pwText);
359         FREE(pwText);
360         types::InternalType * pIT = symbol::Context::getInstance()->get(symbol::Symbol(*yylval.str));
361         if (pIT && pIT->isCallable())
362         {
363             scan_throw(ID);
364             BEGIN(SHELLMODE);
365         }
366         else
367         {
368             BEGIN(INITIAL);
369             return scan_throw(ID);
370         }
371     }
372
373 }
374
375 <INITIAL,MATRIX>{boolnot}               {
376   return scan_throw(NOT);
377 }
378 <INITIAL,MATRIX>{dollar}                {
379   return scan_throw(DOLLAR);
380 }
381 <INITIAL,MATRIX>{booltrue}              {
382   return scan_throw(BOOLTRUE);
383 }
384 <INITIAL,MATRIX>{boolfalse}             {
385   return scan_throw(BOOLFALSE);
386 }
387 <INITIAL,MATRIX>{booland}               {
388   return scan_throw(AND);
389 }
390 <INITIAL,MATRIX>{boolandand}    {
391   return scan_throw(ANDAND);
392 }
393 <INITIAL,MATRIX>{boolor}                {
394   return scan_throw(OR);
395 }
396 <INITIAL,MATRIX>{booloror}              {
397   return scan_throw(OROR);
398 }
399
400
401 <INITIAL>{lparen}                       {
402   return scan_throw(LPAREN);
403 }
404 <INITIAL>{rparen}                       {
405   return scan_throw(RPAREN);
406 }
407
408
409 <INITIAL,MATRIX>{semicolon}             {
410         scan_step();
411   return scan_throw(SEMI);
412 }
413
414 <INITIAL,MATRIX>{comma}                 {
415         scan_step();
416   return scan_throw(COMMA);
417 }
418
419 <INITIAL,MATRIX>{colon}                 {
420   return scan_throw(COLON);
421 }
422
423
424 <INITIAL,MATRIX>{lbrace}                {
425   yy_push_state(MATRIX);
426   ParserSingleInstance::pushControlStatus(Parser::WithinCell);
427   return scan_throw(LBRACE);
428 }
429
430 {rbrace}                        {
431   return scan_throw(RBRACE);
432 }
433
434
435 <INITIAL,MATRIX>{dotquote}              {
436   return scan_throw(DOTQUOTE);
437 }
438 <INITIAL,MATRIX>{dottimes}              {
439   return scan_throw(DOTTIMES);
440 }
441 <INITIAL,MATRIX>{dotrdivide}            {
442   return scan_throw(DOTRDIVIDE);
443 }
444 <INITIAL,MATRIX>{dotldivide}            {
445   return scan_throw(DOTLDIVIDE);
446 }
447 <INITIAL,MATRIX>{dotpower}              {
448   return scan_throw(DOTPOWER);
449 }
450
451
452 {minus}                                 {
453   return scan_throw(MINUS);
454 }
455 {plus}                                  {
456   return scan_throw(PLUS);
457 }
458 <INITIAL,MATRIX>{times}                 {
459   return scan_throw(TIMES);
460 }
461 <INITIAL,MATRIX>{rdivide}               {
462   return scan_throw(RDIVIDE);
463 }
464 <INITIAL,MATRIX>{ldivide}               {
465   return scan_throw(LDIVIDE);
466 }
467 <INITIAL,MATRIX>{power}                 {
468   return scan_throw(POWER);
469 }
470
471 <INITIAL,MATRIX>{krontimes}             {
472   return scan_throw(KRONTIMES);
473 }
474 <INITIAL,MATRIX>{kronrdivide}           {
475   return scan_throw(KRONRDIVIDE);
476 }
477 <INITIAL,MATRIX>{kronldivide}           {
478   return scan_throw(KRONLDIVIDE);
479 }
480
481
482 <INITIAL,MATRIX>{controltimes}          {
483     unput(yytext[yyleng - 1]);
484     return scan_throw(CONTROLTIMES);
485 }
486 <INITIAL,MATRIX>{controlrdivide}                {
487     unput(yytext[yyleng - 1]);
488     return scan_throw(CONTROLRDIVIDE);
489 }
490 <INITIAL,MATRIX>{controlldivide}                {
491     unput(yytext[yyleng - 1]);
492     return scan_throw(CONTROLLDIVIDE);
493 }
494
495
496 <INITIAL,MATRIX>{equal}                 {
497   return scan_throw(EQ);
498 }
499 <INITIAL,MATRIX>{notequal}              {
500   return scan_throw(NE);
501 }
502 <INITIAL,MATRIX>{lowerthan}             {
503   return scan_throw(LT);
504 }
505 <INITIAL,MATRIX>{greaterthan}           {
506   return scan_throw(GT);
507 }
508 <INITIAL,MATRIX>{lowerequal}            {
509   return scan_throw(LE);
510 }
511 <INITIAL,MATRIX>{greaterequal}          {
512   return scan_throw(GE);
513 }
514
515
516 <INITIAL,MATRIX>{assign}                {
517   return scan_throw(ASSIGN);
518  }
519
520
521 <INITIAL,MATRIX>{lbrack}                {
522   DEBUG("yy_push_state(MATRIX)");
523   yy_push_state(MATRIX);
524   ParserSingleInstance::pushControlStatus(Parser::WithinMatrix);
525   return scan_throw(LBRACK);
526 }
527
528 <INITIAL>{rbrack}                               {
529   return scan_throw(RBRACK);
530 }
531
532
533 <INITIAL,MATRIX>{dot}                   {
534   return scan_throw(DOT);
535 }
536
537 <INITIAL>{next}                 {
538     ParserSingleInstance::pushControlStatus(Parser::WithinDots);
539     yy_push_state(LINEBREAK);
540 }
541
542 <INITIAL,MATRIX>{integer}               {
543   yylval.number = atof(yytext);
544 #ifdef TOKENDEV
545   std::cout << "--> [DEBUG] INTEGER : " << yytext << std::endl;
546 #endif
547 //  scan_step();
548   return scan_throw(VARINT);
549 }
550
551
552 <INITIAL,MATRIX>{floating}              {
553   scan_exponent_convert(yytext);
554   yylval.number = atof(yytext);
555 #ifdef TOKENDEV
556   std::cout << "--> [DEBUG] FLOATING : " << yytext << std::endl;
557 #endif
558   scan_step();
559   return scan_throw(VARFLOAT);
560 }
561
562
563 <INITIAL,MATRIX>{number}                {
564   yylval.number = atof(yytext);
565 #ifdef TOKENDEV
566   std::cout << "--> [DEBUG] NUMBER : " << yytext << std::endl;
567 #endif
568 //  scan_step();
569   return scan_throw(NUM);
570 }
571
572
573 <INITIAL,MATRIX>{little}                {
574   yylval.number = atof(yytext);
575 #ifdef TOKENDEV
576   std::cout << "--> [DEBUG] LITTLE : " << yytext << std::endl;
577 #endif
578   scan_step();
579   return scan_throw(NUM);
580 }
581
582
583 <INITIAL,MATRIX>{id}                    {
584     wchar_t *pwText = to_wide_string(yytext);
585     if (yytext != NULL && pwText == NULL)
586     {
587         std::string str = "can not convert'";
588         str += yytext;
589         str += "' to UTF-8";
590         exit_status = SCAN_ERROR;
591         scan_error("can not convert string to UTF-8");
592     }
593     yylval.str = new std::wstring(pwText);
594     FREE(pwText);
595 #ifdef TOKENDEV
596   std::cout << "--> [DEBUG] ID : " << yytext << std::endl;
597 #endif
598 //  scan_step();
599   return scan_throw(ID);
600 }
601
602
603 <INITIAL,MATRIX>{startblockcomment}     {
604   yylval.comment = new std::wstring();
605   comment_level = 1;
606   ParserSingleInstance::pushControlStatus(Parser::WithinBlockComment);
607   yy_push_state(REGIONCOMMENT);
608 }
609
610
611 <INITIAL,MATRIX>{startcomment}          {
612   pstBuffer = new std::string();
613   yy_push_state(LINECOMMENT);
614 }
615
616
617 <INITIAL,MATRIX,SHELLMODE>{dquote}              {
618   pstBuffer = new std::string();
619   yy_push_state(DOUBLESTRING);
620 }
621
622
623 <INITIAL,MATRIX,SHELLMODE>{quote}                       {
624   /*
625   ** Matrix Transposition special behaviour
626   ** ID' []' toto()' are transposition call
627   */
628   if (last_token == ID
629       || last_token == RBRACK
630       || last_token == RPAREN
631       || last_token == RBRACE
632       || last_token == VARINT
633       || last_token == VARFLOAT
634       || last_token == NUM
635       || last_token == BOOLTRUE
636       || last_token == BOOLFALSE)
637   {
638       return scan_throw(QUOTE);
639   }
640   else
641   {
642       pstBuffer = new std::string();
643       yy_push_state(SIMPLESTRING);
644   }
645 }
646
647
648 <INITIAL,MATRIX>{spaces}                {
649   scan_step();
650   scan_throw(SPACES);
651 }
652
653
654 <INITIAL>{newline}              {
655   yylloc.last_line += 1;
656   yylloc.last_column = 1;
657   scan_step();
658   if (last_token != EOL) {
659       return scan_throw(EOL);
660   }
661
662 }
663
664
665 <INITIAL,MATRIX>{blankline}             {
666   yylloc.last_line += 1;
667   yylloc.last_column = 1;
668   scan_step();
669   if (last_token != EOL)
670   {
671       return scan_throw(EOL);
672   }
673   scan_throw(EOL);
674 }
675
676 <INITIAL,MATRIX>{emptyline}             {
677   yylloc.last_line += 2;
678   yylloc.last_column = 1;
679   scan_step();
680   if (last_token != EOL)
681   {
682       return scan_throw(EOL);
683   }
684   scan_throw(EOL);
685 }
686 .                                       {
687     std::string str = "unexpected token '";
688     str += yytext;
689     str += "'";
690     exit_status = SCAN_ERROR;
691     scan_error(str);
692 }
693
694
695 <MATRIX>
696 {
697   {lparen} {
698     paren_level++;
699     return scan_throw(LPAREN);
700   }
701
702   {rparen} {
703     paren_level--;
704     return scan_throw(RPAREN);
705   }
706
707   {spaces}*{lparen} {
708       unput(yytext[yyleng -1]);
709       if (last_token == ID
710           || last_token == RPAREN
711           || last_token == QUOTE
712           || last_token == VARINT
713           || last_token == VARFLOAT
714           || last_token == NUM)
715       {
716           return scan_throw(COMMA);
717       }
718   }
719
720   {spaces}*{colon}{spaces}* {
721       return scan_throw(COLON);
722   }
723
724   {newline} {
725       yylloc.last_line += 1;
726       yylloc.last_column = 1;
727       if(last_token != DOTS && last_token != EOL)
728       {
729           return scan_throw(EOL);
730       }
731       scan_throw(EOL);
732   }
733
734
735   {rbrack}                              {
736     DEBUG("yy_pop_state()");
737     yy_pop_state();
738     ParserSingleInstance::popControlStatus();
739     return scan_throw(RBRACK);
740   }
741
742   {rbrace}                              {
743     yy_pop_state();
744     ParserSingleInstance::popControlStatus();
745     return scan_throw(RBRACE);
746   }
747
748   {plus}                                |
749   {spaces}{plus}{spaces}                {
750     return scan_throw(PLUS);
751   }
752
753   {minus}                               |
754   {spaces}{minus}{spaces}               {
755     return scan_throw(MINUS);
756   }
757
758   {spaces}{plus}                        {
759     // no need to unput the '+'
760     if (last_token != LBRACK
761        && last_token != EOL
762        && last_token != SEMI
763        && last_token != COMMA
764        && paren_level == 0)
765    {
766        return scan_throw(COMMA);
767    }
768    else
769    {
770        unput('+');
771    }
772   }
773
774   {spaces}{minus}                       {
775     unput('-');
776     if (last_token != LBRACK
777        && last_token != EOL
778        && last_token != SEMI
779        && last_token != COMMA
780        && paren_level == 0)
781    {
782        return scan_throw(COMMA);
783    }
784   }
785
786   .                                     {
787     std::string str = "unexpected token '";
788     str += yytext;
789     str += "' within a matrix.";
790     exit_status = SCAN_ERROR;
791     scan_error(str);
792   }
793
794   {next}{spaces}*{newline}          {
795       /* Just do nothing */
796       yylloc.last_line += 1;
797       yylloc.last_column = 1;
798       scan_step();
799       scan_throw(EOL);
800   }
801
802   {next}{spaces}*{startcomment}          {
803       /* Just do nothing */
804       pstBuffer = new std::string();
805       yy_push_state(LINECOMMENT);
806       scan_throw(DOTS);
807   }
808
809   <<EOF>>       {
810       yy_pop_state();
811   }
812 }
813
814 <LINEBREAK>
815 {
816   {newline}                             {
817     yylloc.last_line += 1;
818     yylloc.last_column = 1;
819     scan_step();
820     yy_pop_state();
821     ParserSingleInstance::popControlStatus();
822   }
823
824   {startblockcomment}                   {
825     ++comment_level;
826     yy_push_state(REGIONCOMMENT);
827   }
828
829   {startcomment}                        {
830     scan_throw(DOTS);
831     pstBuffer = new std::string();
832     yy_push_state(LINECOMMENT);
833   }
834
835   {spaces}                              {
836       /* Do nothing... */
837   }
838
839   <<EOF>>       {
840       yy_pop_state();
841   }
842   .                                     {
843     std::string str = "unexpected token '";
844     str += yytext;
845     str += "' after line break with .. or ...";
846     exit_status = SCAN_ERROR;
847     scan_error(str);
848   }
849 }
850
851
852 <LINECOMMENT>
853 {
854   {newline}     {
855     //yylloc.last_line += 1;
856     //yylloc.last_column = 1;
857     //scan_step();
858     yy_pop_state();
859     for (int i = yyleng - 1 ; i >= 0 ; --i)
860     {
861         //std::cerr << "Unputting i = {" << i << "}" << std::endl;
862         //std::cerr << "Unputting {" << yytext[i] << "}" << std::endl;
863         unput(yytext[i]);
864         yylloc.last_column--;
865     }
866     /*
867     ** To forgot comments after lines break
868     */
869     if (last_token != DOTS)
870     {
871         //std::cerr << "pstBuffer = {" << *pstBuffer << "}" << std::endl;
872         //std::cerr << "pstBuffer->c_str() = {" << pstBuffer->c_str() << "}" << std::endl;
873         wchar_t *pwstBuffer = to_wide_string(pstBuffer->c_str());
874         //std::wcerr << L"pwstBuffer = W{" << pwstBuffer << L"}" << std::endl;
875         if (pstBuffer->c_str() != NULL && pwstBuffer == NULL)
876         {
877             std::string str = "can not convert'";
878             str += pstBuffer->c_str();
879             str += "' to UTF-8";
880             exit_status = SCAN_ERROR;
881             scan_error("can not convert string to UTF-8");
882         }
883         yylval.comment = new std::wstring(pwstBuffer);
884         delete pstBuffer;
885         FREE (pwstBuffer);
886         return scan_throw(COMMENT);
887     }
888     else
889     {
890         delete pstBuffer;
891     }
892   }
893
894   <<EOF>>       {
895     yy_pop_state();
896     wchar_t *pwstBuffer = to_wide_string(pstBuffer->c_str());
897     if (pstBuffer->c_str() != NULL && pwstBuffer == NULL)
898     {
899         std::string str = "can not convert'";
900         str += pstBuffer->c_str();
901         str += "' to UTF-8";
902         exit_status = SCAN_ERROR;
903         scan_error("can not convert string to UTF-8");
904     }
905     yylval.comment = new std::wstring(pwstBuffer);
906     delete pstBuffer;
907     FREE (pwstBuffer);
908     return scan_throw(COMMENT);
909   }
910
911   .         {
912      // Put the char in a temporary CHAR buffer to go through UTF-8 trouble
913      // only translate to WCHAR_T when popping state.
914      *pstBuffer += yytext;
915   }
916
917 }
918
919
920 <REGIONCOMMENT>
921 {
922   {endblockcomment}                             {
923     --comment_level;
924     if (comment_level == 0) {
925       ParserSingleInstance::popControlStatus();
926       yy_pop_state();
927       //return scan_throw(BLOCKCOMMENT);
928     }
929   }
930
931   {startblockcomment}                           {
932     ++comment_level;
933     yy_push_state(REGIONCOMMENT);
934   }
935
936   {newline}                                     {
937     yylloc.last_line += 1;
938     yylloc.last_column = 1;
939     scan_step();
940     *yylval.comment += L"\n//";
941   }
942
943   .                                             {
944       wchar_t *pwText = to_wide_string(yytext);
945       *yylval.comment += std::wstring(pwText);
946       FREE(pwText);
947   }
948
949  <<EOF>>                                        {
950       yy_pop_state();
951 //    std::string str = "unexpected end of file in a comment";
952 //    exit_status = SCAN_ERROR;
953 //    scan_error(str);
954   }
955 }
956
957
958 <SIMPLESTRING>
959 {
960   {dquote}{dquote}                              {
961     *pstBuffer += "\"";
962   }
963
964   {dquote}{quote}                               {
965     *pstBuffer += "'";
966   }
967
968   {quote}{dquote}                               {
969     *pstBuffer += "\"";
970   }
971
972   {quote}{quote}                                {
973     *pstBuffer += "'";
974   }
975
976   {quote}                                       {
977     yy_pop_state();
978     scan_step();
979     wchar_t *pwstBuffer = to_wide_string(pstBuffer->c_str());
980     if (pstBuffer->c_str() != NULL && pwstBuffer == NULL)
981     {
982         std::string str = "can not convert'";
983         str += pstBuffer->c_str();
984         str += "' to UTF-8";
985         exit_status = SCAN_ERROR;
986         scan_error("can not convert string to UTF-8");
987     }
988     yylval.str = new std::wstring(pwstBuffer);
989     delete pstBuffer;
990     FREE(pwstBuffer);
991     return scan_throw(STR);
992   }
993
994   {dquote}                  {
995     std::string str = "Heterogeneous string detected, starting with ' and ending with \".";
996     exit_status = SCAN_ERROR;
997     scan_error(str);
998   }
999
1000   {next}{newline}           {
1001       /* Do nothing... Just skip */
1002   }
1003
1004   {newline}                                     {
1005     std::string str = "unexpected end of line in a string.";
1006     exit_status = SCAN_ERROR;
1007     scan_error(str);
1008     yylloc.last_line += 1;
1009     yylloc.last_column = 1;
1010   }
1011
1012   <<EOF>>                                       {
1013     std::string str = "unexpected end of file in a string.";
1014     exit_status = SCAN_ERROR;
1015     scan_error(str);
1016   }
1017
1018   .                                             {
1019     scan_step();
1020     *pstBuffer += yytext;
1021   }
1022 }
1023
1024
1025 <DOUBLESTRING>
1026 {
1027   {dquote}{dquote}                              {
1028     *pstBuffer += "\"";
1029   }
1030
1031   {dquote}{quote}                               {
1032     *pstBuffer += "'";
1033   }
1034
1035   {quote}{dquote}               {
1036     *pstBuffer += "\"";
1037   }
1038
1039   {quote}{quote}                                {
1040     *pstBuffer += "'";
1041   }
1042
1043   {dquote}                      {
1044     yy_pop_state();
1045     scan_step();
1046     wchar_t *pwstBuffer = to_wide_string(pstBuffer->c_str());
1047     if (pstBuffer->c_str() != NULL && pwstBuffer == NULL)
1048     {
1049         std::string str = "can not convert'";
1050         str += pstBuffer->c_str();
1051         str += "' to UTF-8";
1052         exit_status = SCAN_ERROR;
1053         scan_error("can not convert string to UTF-8");
1054     }
1055     yylval.str = new std::wstring(pwstBuffer);
1056     delete pstBuffer;
1057     FREE(pwstBuffer);
1058     return scan_throw(STR);
1059   }
1060
1061   {quote}                  {
1062     std::string str = "Heterogeneous string detected, starting with \" and ending with '.";
1063     exit_status = SCAN_ERROR;
1064     scan_error(str);
1065   }
1066
1067   {next}{newline}           {
1068       /* Do nothing... Just skip */
1069   }
1070
1071   {newline} {
1072     std::string str = "unexpected end of line in a string";
1073     exit_status = SCAN_ERROR;
1074     scan_error(str);
1075     yylloc.last_line += 1;
1076     yylloc.last_column = 1;
1077   }
1078
1079   <<EOF>>   {
1080     std::string str = "unexpected end of file in a string";
1081     exit_status = SCAN_ERROR;
1082     scan_error(str);
1083   }
1084
1085   .         {
1086    scan_step();
1087    *pstBuffer += yytext;
1088   }
1089 }
1090
1091
1092 <SHELLMODE>
1093 {
1094     {spaces}                    {
1095         if (last_token == ID)
1096         {
1097             scan_throw(SPACES);
1098             return ID;
1099         }
1100     }
1101
1102     {semicolon}                 {
1103         BEGIN(INITIAL);
1104         scan_step();
1105         return scan_throw(SEMI);
1106     }
1107
1108     {comma}                     {
1109         BEGIN(INITIAL);
1110         scan_step();
1111         return scan_throw(COMMA);
1112     }
1113
1114     {newline}                   {
1115         BEGIN(INITIAL);
1116         yylloc.last_line += 1;
1117         yylloc.last_column = 1;
1118         scan_step();
1119         return scan_throw(EOL);
1120     }
1121
1122     {assign} {
1123         if (last_token == STR)
1124         {
1125             wchar_t *pwText = to_wide_string(yytext);
1126             yylval.str = new std::wstring(pwText);
1127             FREE(pwText);
1128             return scan_throw(STR);
1129         }
1130         else
1131         {
1132             BEGIN(INITIAL);
1133             return scan_throw(ASSIGN);
1134         }
1135     }
1136
1137     {lparen} {
1138         if (last_token == STR)
1139         {
1140             wchar_t *pwText = to_wide_string(yytext);
1141             yylval.str = new std::wstring(pwText);
1142             FREE(pwText);
1143             return scan_throw(STR);
1144         }
1145         else
1146         {
1147             BEGIN(INITIAL);
1148             return scan_throw(LPAREN);
1149         }
1150     }
1151
1152     {lowerthan} {
1153         if (last_token == STR)
1154         {
1155             wchar_t *pwText = to_wide_string(yytext);
1156             yylval.str = new std::wstring(pwText);
1157             FREE(pwText);
1158             return scan_throw(STR);
1159         }
1160         else
1161         {
1162             BEGIN(INITIAL);
1163             return scan_throw(LT);
1164         }
1165     }
1166
1167     {greaterthan} {
1168         if (last_token == STR)
1169         {
1170             wchar_t *pwText = to_wide_string(yytext);
1171             yylval.str = new std::wstring(pwText);
1172             FREE(pwText);
1173             return scan_throw(STR);
1174         }
1175         else
1176         {
1177             BEGIN(INITIAL);
1178             return scan_throw(GT);
1179         }
1180     }
1181
1182     {boolnot} {
1183         if (last_token == STR)
1184         {
1185             wchar_t *pwText = to_wide_string(yytext);
1186             yylval.str = new std::wstring(pwText);
1187             FREE(pwText);
1188             return scan_throw(STR);
1189         }
1190         else
1191         {
1192             BEGIN(INITIAL);
1193             return scan_throw(NOT);
1194         }
1195     }
1196
1197
1198     [^ \t\v\f\r\n,;'"]+               {
1199         wchar_t *pwText = to_wide_string(yytext);
1200         yylval.str = new std::wstring(pwText);
1201         FREE(pwText);
1202         return scan_throw(STR);
1203     }
1204
1205     <<EOF>>                     {
1206         BEGIN(INITIAL);
1207     }
1208
1209 }
1210
1211 %%
1212
1213 int scan_throw(int token) {
1214   last_token = token;
1215 #ifdef DEV
1216   std::cout << "--> [DEBUG] TOKEN : " << token << std::endl;
1217 #endif
1218   return token;
1219 }
1220
1221 int get_last_token() {
1222     return last_token;
1223 }
1224
1225 void scan_step() {
1226   yylloc.first_line = yylloc.last_line;
1227   yylloc.first_column = yylloc.last_column;
1228 }
1229
1230 void scan_error(std::string msg)
1231 {
1232     wchar_t* pstMsg = to_wide_string(msg.c_str());
1233
1234     //std::wcerr << pstMsg << std::endl;
1235     ParserSingleInstance::PrintError(pstMsg);
1236     ParserSingleInstance::setExitStatus(Parser::Failed);
1237     ParserSingleInstance::resetControlStatus();
1238     FREE(pstMsg);
1239     last_token = YYEOF;
1240     BEGIN(INITIAL);
1241 }
1242
1243 /*
1244 ** convert floating numbers to C standard
1245 ** 1.2d-3 -> 1.2e-3
1246 ** 1.2D-3 -> 1.2e-3
1247 */
1248 void scan_exponent_convert(char *in)
1249 {
1250   char *pString;
1251   while((pString=strpbrk(in,"d"))!=NULL)
1252     {
1253       *pString='e';
1254     }
1255   while((pString=strpbrk(in,"D"))!=NULL)
1256     {
1257       *pString='e';
1258     }
1259 }
1260
1261 #ifdef _MSC_VER
1262 int isatty (int desc)
1263 {
1264   return 0;
1265 }
1266 #endif