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