fix precedence of uminus in operation
[scilab.git] / scilab / modules / ast / src / cpp / parse / bison / parsescilab.yy
1 %{ // -*- C++ -*-
2 /*
3  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
4  *  Copyright (C) 2008-2010 - DIGITEO - 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 #define YYERROR_VERBOSE 1
14
15 #define YYDEBUG 1
16
17 #define YYLTYPE Location
18
19 /*
20 ** This build the tree in verbose mode
21 ** for instance adding CommentExp
22 ** where nothing is needed.
23 */
24 //#define BUILD_DEBUG_AST
25
26 #include <string>
27 #include <sstream>
28 #include <list>
29 #include "all.hxx"
30 #include "parse.hxx"
31 #include "parser_private.hxx"
32 #include "location.hxx"
33 #include "symbol.hxx"
34 #include "charEncoding.h"
35 #include "sci_malloc.h"
36
37 #define StopOnError()                                           \
38     {                                                           \
39         if(ParserSingleInstance::stopOnFirstError())            \
40         {                                                       \
41             return ParserSingleInstance::getExitStatus();       \
42         }                                                       \
43     }
44
45
46 %}
47
48 //%pure-parser
49 %locations
50 %verbose
51 %debug
52 %defines
53
54 %union
55 {
56   /* Tokens. */
57     double                      number;
58     std::wstring*               str;
59     std::wstring*               path;
60     std::wstring*               comment;
61
62     LineBreakStr*               mute;
63
64     ast::exps_t*                t_list_var;
65     ast::exps_t*                t_list_exp;
66     ast::Exp*                   t_exp;
67
68     ast::SeqExp*                t_seq_exp;
69     ast::ReturnExp*             t_return_exp;
70
71     ast::IfExp*                 t_if_exp;
72     ast::WhileExp*              t_while_exp;
73     ast::ForExp*                t_for_exp;
74     ast::TryCatchExp*           t_try_exp;
75     ast::SelectExp*             t_select_exp;
76     ast::CaseExp*               t_case_exp;
77     ast::exps_t*                t_list_case;
78
79     ast::CallExp*               t_call_exp;
80
81     ast::MathExp*               t_math_exp;
82
83     ast::OpExp*                 t_op_exp;
84     ast::OpExp::Oper            t_op_exp_oper;
85     ast::LogicalOpExp::Oper     t_lop_exp_oper;
86
87     ast::AssignExp*             t_assign_exp;
88
89     ast::StringExp*             t_string_exp;
90
91     ast::ListExp*               t_implicit_list;
92
93     ast::MatrixExp*             t_matrix_exp;
94     ast::MatrixLineExp*         t_matrixline_exp;
95     ast::exps_t*                t_list_mline;
96
97     ast::CellExp*               t_cell_exp;
98
99     ast::CellCallExp*           t_cell_call_exp;
100
101     ast::FunctionDec*           t_function_dec;
102
103     ast::ArrayListExp*          t_arraylist_exp;
104     ast::AssignListExp*         t_assignlist_exp;
105     ast::ArrayListVar*          t_arraylist_var;
106
107     ast::SimpleVar*             t_simple_var;
108 }
109
110 %token YYEOF    0       "end of file"
111
112 %token DOTS             "line break"
113
114 %token EOL              "end of line"
115 %token SPACES           "spaces"
116
117 %token BOOLTRUE         "%t or %T"
118 %token BOOLFALSE        "%f or %F"
119
120 %token QUOTE            "'"
121 %token NOT              "~ or @"
122 %token DOLLAR           "$"
123 %token COMMA            ","
124 %token COLON            ":"
125 %token SEMI             ";"
126 %token LPAREN           "("
127 %token RPAREN           ")"
128 %token LBRACK           "["
129 %token RBRACK           "]"
130 %token LBRACE           "{"
131 %token RBRACE           "}"
132 %token DOT              "."
133
134 %token DOTQUOTE         ".'"
135
136 %token PLUS             "+"
137 %token MINUS            "-"
138 %token TIMES            "*"
139 %token DOTTIMES         ".*"
140 %token KRONTIMES        ".*."
141 %token CONTROLTIMES "*."
142 %token RDIVIDE          "/"
143 %token DOTRDIVIDE       "./"
144 %token CONTROLRDIVIDE   "/."
145 %token KRONRDIVIDE      "./."
146 %token LDIVIDE          "\\"
147 %token DOTLDIVIDE       ".\\"
148 %token CONTROLLDIVIDE "\\."
149 %token KRONLDIVIDE      ".\\."
150
151 %token POWER            "** or ^"
152 %token DOTPOWER         ".^"
153
154 %token EQ               "=="
155 %token NE               "<> or ~="
156 %token LT               "<"
157 %token LE               "<="
158 %token GT               ">"
159 %token GE               ">="
160 %token AND              "&"
161 %token ANDAND           "&&"
162 %token OR               "|"
163 %token OROR             "||"
164 %token ASSIGN           "="
165
166 %token IF               "if"
167 %token THEN             "then"
168 %token ELSE             "else"
169 %token ELSEIF           "elseif"
170 %token END              "end"
171
172 %token SELECT           "select"
173 %token SWITCH   "switch"
174 %token CASE             "case"
175 %token OTHERWISE "otherwise"
176
177 %token FUNCTION         "function"
178 %token ENDFUNCTION      "endfunction"
179 %token HIDDENFUNCTION   "#function"
180 %token HIDDEN           "hidden"
181
182
183 %token FOR              "for"
184
185 %token WHILE            "while"
186 %token DO               "do"
187 %token BREAK            "break"
188 %token CONTINUE     "continue"
189
190 %token TRY              "try"
191 %token CATCH            "catch"
192 %token RETURN           "return"
193
194 %token <str>            STR     "string"
195 %token <str>            ID      "identifier"
196 %token <number>         VARINT  "integer"
197 %token <number>         VARFLOAT"float"
198 %token <number>         NUM     "number"
199
200 %token <path>           PATH    "path"
201
202 %token <comment>        COMMENT "line comment"
203 %token <comment>        BLOCKCOMMENT "block comment"
204
205 %type <t_seq_exp>       expressions
206 %type <t_list_exp>      recursiveExpression
207
208 %type <t_exp>           assignable
209 %type <t_assignlist_exp>multipleResults
210 %type <t_exp>           variable
211 %type <t_list_exp>      variableFields
212 %type <t_exp>           expression
213
214 %type <t_op_exp>        comparison
215 %type <t_op_exp>        rightComparable
216 %type <t_exp>           operation
217 %type <t_op_exp>        rightOperand
218
219  // IF Control
220 %type <t_if_exp>        ifControl
221 %type <t_exp>           condition
222 %type <t_seq_exp>       thenBody
223 %type <t_seq_exp>       elseBody
224 %type <t_seq_exp>       elseIfControl
225
226  // WHILE Control
227 %type <t_while_exp>     whileControl
228 %type <t_seq_exp>       whileBody
229
230  // FOR Control
231 %type <t_for_exp>       forControl
232 %type <t_exp>           forIterator
233 %type <t_seq_exp>       forBody
234
235  // RETURN Control
236 %type <t_return_exp>    returnControl
237
238  // TRY Control
239 %type<t_try_exp>        tryControl
240 %type<t_seq_exp>    catchBody
241
242  // SELECT Control
243 %type<t_select_exp> selectControl
244 %type<t_exp>            selectable
245 %type<t_list_case>  casesControl
246 %type <t_seq_exp>       caseBody
247
248  // Implicit Function Call
249 %type <t_call_exp>      implicitFunctionCall
250 %type <t_string_exp>    implicitCallable
251
252  // Function Call
253 %type <t_call_exp>      functionCall
254  //%type <t_call_exp>   recursiveFunctionCall
255 %type <t_call_exp>      simpleFunctionCall
256 %type <t_list_exp>      functionArgs
257 %type <t_seq_exp>       functionBody
258
259  // Function Declaration
260 %type <t_function_dec>  functionDeclaration
261 %type <t_list_var>      functionDeclarationReturns
262 %type <t_list_var>      functionDeclarationArguments
263 %type <t_list_var>      idList
264
265  // Variable Declaration
266 %type <t_assign_exp>    variableDeclaration
267
268  // Implicit List
269 %type <t_implicit_list> listableEnd
270 %type <t_exp>           listableBegin
271
272  // Matrix & Cell
273 %type<t_matrix_exp>     matrix
274 %type<t_cell_exp>       cell
275 %type<t_list_exp>       matrixOrCellColumns
276 %type<t_matrixline_exp> matrixOrCellLine
277 %type<t_list_mline>     matrixOrCellLines
278
279 %type<mute>             expressionLineBreak
280
281 %type<t_simple_var> keywords
282
283 %nonassoc TOPLEVEL
284 %nonassoc HIGHLEVEL
285 %nonassoc UPLEVEL
286 %nonassoc LISTABLE
287
288 %nonassoc CONTROLBREAK
289
290 %left OR OROR
291 %left AND ANDAND
292
293 %left COLON
294 %left EQ NE LT LE GT GE
295 %left MINUS PLUS
296 %left TIMES DOTTIMES KRONTIMES CONTROLTIMES RDIVIDE DOTRDIVIDE KRONRDIVIDE CONTROLRDIVIDE LDIVIDE DOTLDIVIDE KRONLDIVIDE CONTROLLDIVIDE
297 %left UMINUS
298 %right POWER DOTPOWER
299
300 %left QUOTE DOTQUOTE
301
302 %left NOT
303
304 %left DOT
305
306 %nonassoc FUNCTIONCALL
307 %nonassoc BOOLTRUE BOOLFALSE
308 %nonassoc LPAREN LBRACE
309
310 %start program
311
312
313 %%
314 /*
315 ** -*- PROGRAM -*-
316 */
317 /* Root of the Abstract Syntax Tree */
318 program:
319 expressions                     { ParserSingleInstance::setTree($1); }
320 | EOL expressions                               { ParserSingleInstance::setTree($2); }
321 | expressionLineBreak           {
322                                   ast::exps_t* tmp = new ast::exps_t;
323                                   #ifdef BUILD_DEBUG_AST
324                                       tmp->push_back(new ast::CommentExp(@$, new std::wstring(L"Empty body");
325                                   #endif
326                                   ParserSingleInstance::setTree(new ast::SeqExp(@$, *tmp));
327                                   delete $1;
328                                 }
329 | /* Epsilon */                 {
330                                   ast::exps_t* tmp = new ast::exps_t;
331                                   #ifdef BUILD_DEBUG_AST
332                                       tmp->push_back(new ast::CommentExp(@$, new std::wstring(L"Empty body")));
333                                   #endif
334                                   ParserSingleInstance::setTree(new ast::SeqExp(@$, *tmp));
335                                 }
336 ;
337
338 /*
339 ** -*- EXPRESSIONS -*-
340 */
341 /* List of expression or single instruction */
342 expressions :
343 recursiveExpression                             {
344                                                   $$ = new ast::SeqExp(@$, *$1);
345                                                 }
346 | recursiveExpression expression                {
347                                                   $2->setVerbose(true);
348                                                   $1->push_back($2);
349                                                   $$ = new ast::SeqExp(@$, *$1);
350                                                 }
351 | recursiveExpression expression COMMENT        {
352                                                   $2->setVerbose(true);
353                                                   $1->push_back($2);
354                                                   $1->push_back(new ast::CommentExp(@3, $3));
355                                                   $$ = new ast::SeqExp(@$, *$1);
356                                                 }
357 | expression                                    {
358                                                   ast::exps_t* tmp = new ast::exps_t;
359                                                   $1->setVerbose(true);
360                                                   tmp->push_back($1);
361                                                   $$ = new ast::SeqExp(@$, *tmp);
362                                                 }
363 | expression COMMENT                            {
364                                                   ast::exps_t* tmp = new ast::exps_t;
365                                                   $1->setVerbose(true);
366                                                   tmp->push_back($1);
367                                                   tmp->push_back(new ast::CommentExp(@2, $2));
368                                                   $$ = new ast::SeqExp(@$, *tmp);
369                                                 }
370 ;
371
372 /*
373 ** -*- RECURSIVE EXPRESSION -*-
374 */
375 /* List of instructions. _MUST_BE_ left recursive Rule */
376 recursiveExpression :
377 recursiveExpression expression expressionLineBreak      {
378                                                           $2->setVerbose($3->bVerbose);
379                                                           $1->push_back($2);
380                                                           $$ = $1;
381                               if ($3->iNbBreaker != 0)
382                               {
383                                   $2->getLocation().last_column = $3->iNbBreaker;
384                               }
385                               delete $3;
386                                                         }
387 | recursiveExpression expression COMMENT expressionLineBreak {
388                                                           $2->setVerbose($4->bVerbose);
389                                                           $1->push_back($2);
390                               @3.columns($4->iNbBreaker);
391                                                           $1->push_back(new ast::CommentExp(@3, $3));
392                                                           $$ = $1;
393                                                           delete $4;
394                                                         }
395 | expression COMMENT expressionLineBreak                {
396                                                           ast::exps_t* tmp = new ast::exps_t;
397                               @2.columns($3->iNbBreaker);
398                                                           $1->setVerbose($3->bVerbose);
399                                                           tmp->push_back($1);
400                                                           tmp->push_back(new ast::CommentExp(@2, $2));
401                                                           $$ = tmp;
402                                                           delete $3;
403                                                         }
404 | expression expressionLineBreak                        {
405                                                           ast::exps_t* tmp = new ast::exps_t;
406                                                           $1->setVerbose($2->bVerbose);
407                                                           tmp->push_back($1);
408                                                           $$ = tmp;
409                               if ($2->iNbBreaker != 0)
410                               {
411                                   $1->getLocation().last_column = $2->iNbBreaker;
412                               }
413                               delete $2;
414                                                         }
415 ;
416
417 /*
418 ** -*- EXPRESSION LINE BREAK -*-
419 */
420 /* Fake Rule : How can we be sure this is the end of an instruction. */
421 expressionLineBreak :
422 SEMI                            { $$ = new LineBreakStr(); $$->bVerbose = false; $$->iNbBreaker = @1.last_column; }
423 | COMMA                         { $$ = new LineBreakStr(); $$->bVerbose = true; $$->iNbBreaker = @1.last_column; }
424 | EOL                           { $$ = new LineBreakStr(); $$->bVerbose = true; $$->iNbBreaker = 0; }
425 | expressionLineBreak SEMI      { $$ = $1; $$->bVerbose = false || $1->bVerbose; $$->iNbBreaker = @2.last_column; }
426 | expressionLineBreak COMMA     { $$ = $1; $$->iNbBreaker = @2.last_column; }
427 | expressionLineBreak EOL       { $$ = $1; }
428 ;
429
430 /*
431 ** -*- EXPRESSION -*-
432 */
433 /* Expression or Instruction : quite similar. */
434 expression :
435 functionDeclaration                             { $$ = $1; }
436 | functionCall                  %prec TOPLEVEL  { $$ = $1; }
437 | variableDeclaration                           { $$ = $1; }
438 | ifControl                                     { $$ = $1; }
439 | selectControl                                 { $$ = $1; }
440 | forControl                                    { $$ = $1; }
441 | whileControl                                  { $$ = $1; }
442 | tryControl                                    { $$ = $1; }
443 | variable                      %prec TOPLEVEL  { $$ = $1; }
444 | implicitFunctionCall          %prec TOPLEVEL  { $$ = $1; }
445 | BREAK                                         { $$ = new ast::BreakExp(@$); }
446 | CONTINUE                                      { $$ = new ast::ContinueExp(@$); }
447 | returnControl                                 { $$ = $1; }
448 | COMMENT                                       { $$ = new ast::CommentExp(@$, $1); }
449 | error                                         {
450   $$ = new ast::CommentExp(@$, new std::wstring(L"@@ ERROR RECOVERY @@"));
451   StopOnError();
452   }
453 ;
454
455 /*
456 ** -*- IMPLICIT FUNCTION CALL -*-
457 */
458 /* FIXME : Must be improved */
459 /* Bash-like : foo bar titi <=> foo('bar', 'titi'). */
460 implicitFunctionCall :
461 /* FIXME : Add arguments to call */
462 implicitFunctionCall implicitCallable           {
463                                                   $1->addArg($2);
464                                                   $1->setLocation(@$);
465                           $$ = $1;
466                                                 }
467 | ID implicitCallable                           {
468                                                   ast::exps_t* tmp = new ast::exps_t;
469                                                   tmp->push_back($2);
470                                                   $$ = new ast::CallExp(@$, *new ast::SimpleVar(@1, symbol::Symbol(*$1)), *tmp);
471                                                   delete $1;
472                                                 }
473 ;
474
475 /*
476 ** -*- IMPLICIT CALLABLE -*-
477 */
478 /* FIXME : Must be improved */
479 /* Bash-like : foo bar titi <=> foo('bar', 'titi').
480 ** Describe 'bar', 'titi' that can be more complex.
481 */
482 implicitCallable :
483 ID                                              { $$ = new ast::StringExp(@$, *$1); delete $1;}
484 | VARINT                                        {
485                                                   std::wstringstream tmp;
486                                                   tmp << $1;
487                                                   $$ = new ast::StringExp(@$, tmp.str());
488                                                 }
489 | NUM                                           {
490                                                   std::wstringstream tmp;
491                                                   tmp << $1;
492                                                   $$ = new ast::StringExp(@$, tmp.str());
493                                                 }
494 | VARFLOAT                                      {
495                                                   std::wstringstream tmp;
496                                                   tmp << $1;
497                                                   $$ = new ast::StringExp(@$, tmp.str());
498                                                 }
499 | STR                                           { $$ = new ast::StringExp(@$, *$1); delete $1;}
500 | DOLLAR                                        { $$ = new ast::StringExp(@$, std::wstring(L"$")); }
501 | BOOLTRUE                                      { $$ = new ast::StringExp(@$, std::wstring(L"%t")); }
502 | BOOLFALSE                                     { $$ = new ast::StringExp(@$, std::wstring(L"%f")); }
503 | implicitCallable DOT ID                       {
504                                                   std::wstringstream tmp;
505                                                   tmp << $1->getValue() << "." << *$3;
506                                                   $$ = new ast::StringExp(@$, tmp.str());
507                                                   delete $3;
508                                                 }
509 | implicitCallable DOT functionCall             { $$ = new ast::StringExp(@$, std::wstring(L"!! FIXME : implicitCallable implicitCallable DOT functionCall !!")); }
510 | simpleFunctionCall                            { $$ = new ast::StringExp(@$, std::wstring(L"!! FIXME : implicitCallable simpleFunctionCall !!")); }
511 | implicitCallable rightOperand                 { $$ = new ast::StringExp(@$, std::wstring(L"!! FIXME : implicitCallable implicitCallable rightOperand !!")); }
512 | PATH                                          { $$ = new ast::StringExp(@$, *$1); delete $1;}
513 ;
514
515 /*
516 ** -*- FUNCTION CALL -*-
517 */
518 /* How to call a function or a cell extraction */
519 functionCall :
520 simpleFunctionCall                      { $$ = $1; }
521 //| recursiveFunctionCall               %prec FUNCTIONCALL      { $$ = $1; }
522 | LPAREN functionCall RPAREN    { $$ = $2; }
523 ;
524
525 /*
526 ** -*- SIMPLE FUNCTION CALL -*-
527 */
528 /* Usual way to call functions foo(arg1, arg2, arg3)
529 ** or extract cell values foo{arg1, arg2, arg3}
530 */
531 simpleFunctionCall :
532
533 ID LPAREN functionArgs RPAREN                           { $$ = new ast::CallExp(@$, *new ast::SimpleVar(@1, symbol::Symbol(*$1)), *$3); delete $1;}
534 | ID LBRACE functionArgs RBRACE                         { $$ = new ast::CellCallExp(@$, *new ast::SimpleVar(@1, symbol::Symbol(*$1)), *$3); delete $1;}
535 | ID LPAREN RPAREN                                          { $$ = new ast::CallExp(@$, *new ast::SimpleVar(@1, symbol::Symbol(*$1)), *new ast::exps_t); delete $1;}
536 | ID LBRACE RBRACE                                          { $$ = new ast::CellCallExp(@$, *new ast::SimpleVar(@1, symbol::Symbol(*$1)), *new ast::exps_t); delete $1;}
537 ;
538
539 /*
540 ** -*- RECURSIVE FUNCTION CALL -*-
541 */
542 /* To manage foo(a)(b)(c) <=> ((foo(a))(b))(c)
543 ** foo{a}{b}{c} <=> ((foo{a}){b}){c}
544 ** foo{a}(b){c} <=> ((foo{a})(b)){c}
545 ** foo(a){b}(c) <=> ((foo(a)){b})(c)
546 */
547 //recursiveFunctionCall :
548 //simpleFunctionCall LPAREN functionArgs RPAREN         { $$ = new ast::CallExp(@$, *$1, *$3); }
549 //| recursiveFunctionCall LPAREN functionArgs RPAREN    { $$ = new ast::CallExp(@$, *$1, *$3); }
550 //| simpleFunctionCall LBRACE functionArgs RBRACE               { $$ = new ast::CellCallExp(@$, *$1, *$3); }
551 //| recursiveFunctionCall LBRACE functionArgs RBRACE    { $$ = new ast::CellCallExp(@$, *$1, *$3); }
552 //;
553
554 /*
555 ** -*- FUNCTION ARGS -*-
556 */
557 /* What can be use in a function call */
558 functionArgs :
559 variable                        {
560                                   $$ = new ast::exps_t;
561                                   $$->push_back($1);
562                                 }
563 | functionCall                  {
564                                   $$ = new ast::exps_t;
565                                   $$->push_back($1);
566                                 }
567 | COLON                         {
568                                   $$ = new ast::exps_t;
569                                   $$->push_back(new ast::ColonVar(@1));
570                                 }
571 | variableDeclaration           {
572                                   $$ = new ast::exps_t;
573                                   $$->push_back($1);
574                                 }
575 | COMMA {
576                   $$ = new ast::exps_t;
577                                   $$->push_back(new ast::NilExp(@1));
578                                   $$->push_back(new ast::NilExp(@1));
579                   }
580 | COMMA variable        {
581                                   $$ = new ast::exps_t;
582                                   $$->push_back(new ast::NilExp(@1));
583                   $$->push_back($2);
584                                 }
585 | COMMA functionCall {
586                                   $$ = new ast::exps_t;
587                                   $$->push_back(new ast::NilExp(@1));
588                   $$->push_back($2);
589                                 }
590 | COMMA COLON   {
591                                   $$ = new ast::exps_t;
592                                   $$->push_back(new ast::NilExp(@1));
593                   $$->push_back(new ast::ColonVar(@2));
594                                 }
595 | COMMA variableDeclaration {
596                                   $$ = new ast::exps_t;
597                                   $$->push_back(new ast::NilExp(@1));
598                   $$->push_back($2);
599                                 }
600 | functionArgs COMMA {
601                   $1->push_back(new ast::NilExp(@2));
602                                   $$ = $1;
603                                 }
604 | functionArgs COMMA variable   {
605                                   $1->push_back($3);
606                                   $$ = $1;
607                                 }
608 | functionArgs COMMA functionCall {
609                                   $1->push_back($3);
610                                   $$ = $1;
611                                 }
612 | functionArgs COMMA COLON      {
613                                   $1->push_back(new ast::ColonVar(@1));
614                               $$ = $1;
615                                 }
616 | functionArgs COMMA variableDeclaration {
617                                   $1->push_back($3);
618                                   $$ = $1;
619                                 }
620 //| functionArgs COMMA {
621 //                  $1->push_back(new ast::NilExp(@2));
622 //                                $$ = $1;
623 //                              }
624 //| COMMA functionArgs {
625 //                  $2->insert($2->begin(), new ast::NilExp(@1));
626 //                                $$ = $2;
627 //                              }
628 ;
629
630 /*
631 ** -*- FUNCTION DECLARATION -*-
632 */
633 /* How to declare a function */
634 functionDeclaration :
635 FUNCTION ID ASSIGN ID functionDeclarationArguments functionDeclarationBreak functionBody ENDFUNCTION {
636                                   ast::exps_t* tmp = new ast::exps_t;
637                                   tmp->push_back(new ast::SimpleVar(@2, symbol::Symbol(*$2)));
638                                   $$ = new ast::FunctionDec(@$,
639                                                             symbol::Symbol(*$4),
640                                                             *new ast::ArrayListVar(@5, *$5),
641                                                             *new ast::ArrayListVar(@2, *tmp),
642                                                             *$7);
643                                   delete $2;
644                                   delete $4;
645                                 }
646 | FUNCTION LBRACK functionDeclarationReturns RBRACK ASSIGN ID functionDeclarationArguments functionDeclarationBreak functionBody ENDFUNCTION {
647                                   $$ = new ast::FunctionDec(@$,
648                                                             symbol::Symbol(*$6),
649                                                             *new ast::ArrayListVar(@7, *$7),
650                                                             *new ast::ArrayListVar(@3 ,*$3),
651                                                             *$9);
652                                   delete $6;
653                                 }
654 | FUNCTION LBRACK RBRACK ASSIGN ID functionDeclarationArguments functionDeclarationBreak functionBody ENDFUNCTION {
655                                   ast::exps_t* tmp = new ast::exps_t;
656                                   $$ = new ast::FunctionDec(@$,
657                                                             symbol::Symbol(*$5),
658                                                             *new ast::ArrayListVar(@6, *$6),
659                                                             *new ast::ArrayListVar(@2, *tmp),
660                                                             *$8);
661                                   delete $5;
662                                 }
663 | FUNCTION ID functionDeclarationArguments functionDeclarationBreak functionBody ENDFUNCTION {
664                                   ast::exps_t* tmp = new ast::exps_t;
665                                   $$ = new ast::FunctionDec(@$,
666                                                             symbol::Symbol(*$2),
667                                                             *new ast::ArrayListVar(@3, *$3),
668                                                             *new ast::ArrayListVar(@$, *tmp),
669                                                             *$5);
670                                   delete $2;
671                                 }
672 | FUNCTION ID ASSIGN ID functionDeclarationArguments functionDeclarationBreak functionBody END {
673                                   ast::exps_t* tmp = new ast::exps_t;
674                                   tmp->push_back(new ast::SimpleVar(@2, symbol::Symbol(*$2)));
675                                   $$ = new ast::FunctionDec(@$,
676                                                             symbol::Symbol(*$4),
677                                                             *new ast::ArrayListVar(@5, *$5),
678                                                             *new ast::ArrayListVar(@2, *tmp),
679                                                             *$7);
680                                   delete $2;
681                                   delete $4;
682                                 }
683 | FUNCTION LBRACK functionDeclarationReturns RBRACK ASSIGN ID functionDeclarationArguments functionDeclarationBreak functionBody END {
684                                   $$ = new ast::FunctionDec(@$,
685                                                             symbol::Symbol(*$6),
686                                                             *new ast::ArrayListVar(@7, *$7),
687                                                             *new ast::ArrayListVar(@3 ,*$3),
688                                                             *$9);
689                                   delete $6;
690                                 }
691 | FUNCTION LBRACK RBRACK ASSIGN ID functionDeclarationArguments functionDeclarationBreak functionBody END {
692                                   ast::exps_t* tmp = new ast::exps_t;
693                                   $$ = new ast::FunctionDec(@$,
694                                                             symbol::Symbol(*$5),
695                                                             *new ast::ArrayListVar(@6, *$6),
696                                                             *new ast::ArrayListVar(@2, *tmp),
697                                                             *$8);
698                                   delete $5;
699                                 }
700 | FUNCTION ID functionDeclarationArguments functionDeclarationBreak functionBody END {
701                                   ast::exps_t* tmp = new ast::exps_t;
702                                   $$ = new ast::FunctionDec(@$,
703                                                             symbol::Symbol(*$2),
704                                                             *new ast::ArrayListVar(@3, *$3),
705                                                             *new ast::ArrayListVar(@$, *tmp),
706                                                             *$5);
707                                   delete $2;
708                                 }
709 | HIDDENFUNCTION ID ASSIGN ID functionDeclarationArguments functionDeclarationBreak functionBody ENDFUNCTION {
710                                   ast::exps_t* tmp = new ast::exps_t;
711                                   tmp->push_back(new ast::SimpleVar(@2, symbol::Symbol(*$2)));
712                                   $$ = new ast::FunctionDec(@$,
713                                                             symbol::Symbol(*$4),
714                                                             *new ast::ArrayListVar(@5, *$5),
715                                                             *new ast::ArrayListVar(@2, *tmp),
716                                                             *$7);
717                                   delete $2;
718                                   delete $4;
719                                 }
720 | HIDDENFUNCTION LBRACK functionDeclarationReturns RBRACK ASSIGN ID functionDeclarationArguments functionDeclarationBreak functionBody ENDFUNCTION {
721                                   $$ = new ast::FunctionDec(@$,
722                                                             symbol::Symbol(*$6),
723                                                             *new ast::ArrayListVar(@7, *$7),
724                                                             *new ast::ArrayListVar(@3 ,*$3),
725                                                             *$9);
726                                   delete $6;
727                                 }
728 | HIDDENFUNCTION LBRACK RBRACK ASSIGN ID functionDeclarationArguments functionDeclarationBreak functionBody ENDFUNCTION {
729                                   ast::exps_t* tmp = new ast::exps_t;
730                                   $$ = new ast::FunctionDec(@$,
731                                                             symbol::Symbol(*$5),
732                                                             *new ast::ArrayListVar(@6, *$6),
733                                                             *new ast::ArrayListVar(@2, *tmp),
734                                                             *$8);
735                                   delete $5;
736                                 }
737 | HIDDENFUNCTION ID functionDeclarationArguments functionDeclarationBreak functionBody ENDFUNCTION {
738                                   ast::exps_t* tmp = new ast::exps_t;
739                                   $$ = new ast::FunctionDec(@$,
740                                                             symbol::Symbol(*$2),
741                                                             *new ast::ArrayListVar(@3, *$3),
742                                                             *new ast::ArrayListVar(@$, *tmp),
743                                                             *$5);
744                                   delete $2;
745                                 }
746 | HIDDENFUNCTION ID ASSIGN ID functionDeclarationArguments functionDeclarationBreak functionBody END {
747                                   ast::exps_t* tmp = new ast::exps_t;
748                                   tmp->push_back(new ast::SimpleVar(@2, symbol::Symbol(*$2)));
749                                   $$ = new ast::FunctionDec(@$,
750                                                             symbol::Symbol(*$4),
751                                                             *new ast::ArrayListVar(@5, *$5),
752                                                             *new ast::ArrayListVar(@2, *tmp),
753                                                             *$7);
754                                   delete $2;
755                                   delete $4;
756                                 }
757 | HIDDENFUNCTION LBRACK functionDeclarationReturns RBRACK ASSIGN ID functionDeclarationArguments functionDeclarationBreak functionBody END {
758                                   $$ = new ast::FunctionDec(@$,
759                                                             symbol::Symbol(*$6),
760                                                             *new ast::ArrayListVar(@7, *$7),
761                                                             *new ast::ArrayListVar(@3 ,*$3),
762                                                             *$9);
763                                   delete $6;
764                                 }
765 | HIDDENFUNCTION LBRACK RBRACK ASSIGN ID functionDeclarationArguments functionDeclarationBreak functionBody END {
766                                   ast::exps_t* tmp = new ast::exps_t;
767                                   $$ = new ast::FunctionDec(@$,
768                                                             symbol::Symbol(*$5),
769                                                             *new ast::ArrayListVar(@6, *$6),
770                                                             *new ast::ArrayListVar(@2, *tmp),
771                                                             *$8);
772                                   delete $5;
773                                 }
774 | HIDDENFUNCTION ID functionDeclarationArguments functionDeclarationBreak functionBody END {
775                                   ast::exps_t* tmp = new ast::exps_t;
776                                   $$ = new ast::FunctionDec(@$,
777                                                             symbol::Symbol(*$2),
778                                                             *new ast::ArrayListVar(@3, *$3),
779                                                             *new ast::ArrayListVar(@$, *tmp),
780                                                             *$5);
781                                   delete $2;
782                                 }
783 | HIDDEN FUNCTION ID ASSIGN ID functionDeclarationArguments functionDeclarationBreak functionBody ENDFUNCTION {
784                                   ast::exps_t* tmp = new ast::exps_t;
785                                   tmp->push_back(new ast::SimpleVar(@2, symbol::Symbol(*$3)));
786                                   $$ = new ast::FunctionDec(@$,
787                                                             symbol::Symbol(*$5),
788                                                             *new ast::ArrayListVar(@6, *$6),
789                                                             *new ast::ArrayListVar(@3, *tmp),
790                                                             *$8);
791                                   delete $3;
792                                   delete $5;
793                                 }
794 | HIDDEN FUNCTION LBRACK functionDeclarationReturns RBRACK ASSIGN ID functionDeclarationArguments functionDeclarationBreak functionBody ENDFUNCTION {
795                                   $$ = new ast::FunctionDec(@$,
796                                                             symbol::Symbol(*$7),
797                                                             *new ast::ArrayListVar(@8, *$8),
798                                                             *new ast::ArrayListVar(@4 ,*$4),
799                                                             *$10);
800                                   delete $7;
801                                 }
802 | HIDDEN FUNCTION LBRACK RBRACK ASSIGN ID functionDeclarationArguments functionDeclarationBreak functionBody ENDFUNCTION {
803                                   ast::exps_t* tmp = new ast::exps_t;
804                                   $$ = new ast::FunctionDec(@$,
805                                                             symbol::Symbol(*$6),
806                                                             *new ast::ArrayListVar(@7, *$7),
807                                                             *new ast::ArrayListVar(@3, *tmp),
808                                                             *$9);
809                                   delete $6;
810                                 }
811 | HIDDEN FUNCTION ID functionDeclarationArguments functionDeclarationBreak functionBody ENDFUNCTION {
812                                   ast::exps_t* tmp = new ast::exps_t;
813                                   $$ = new ast::FunctionDec(@$,
814                                                             symbol::Symbol(*$3),
815                                                             *new ast::ArrayListVar(@4, *$4),
816                                                             *new ast::ArrayListVar(@$, *tmp),
817                                                             *$6);
818                                   delete $3;
819                                 }
820 | HIDDEN FUNCTION ID ASSIGN ID functionDeclarationArguments functionDeclarationBreak functionBody END {
821                                   ast::exps_t* tmp = new ast::exps_t;
822                                   tmp->push_back(new ast::SimpleVar(@3, symbol::Symbol(*$3)));
823                                   $$ = new ast::FunctionDec(@$,
824                                                             symbol::Symbol(*$5),
825                                                             *new ast::ArrayListVar(@6, *$6),
826                                                             *new ast::ArrayListVar(@2, *tmp),
827                                                             *$8);
828                                   delete $3;
829                                   delete $5;
830                                 }
831 | HIDDEN FUNCTION LBRACK functionDeclarationReturns RBRACK ASSIGN ID functionDeclarationArguments functionDeclarationBreak functionBody END {
832                                   $$ = new ast::FunctionDec(@$,
833                                                             symbol::Symbol(*$7),
834                                                             *new ast::ArrayListVar(@8, *$8),
835                                                             *new ast::ArrayListVar(@4 ,*$4),
836                                                             *$10);
837                                   delete $7;
838                                 }
839 | HIDDEN FUNCTION LBRACK RBRACK ASSIGN ID functionDeclarationArguments functionDeclarationBreak functionBody END {
840                                   ast::exps_t* tmp = new ast::exps_t;
841                                   $$ = new ast::FunctionDec(@$,
842                                                             symbol::Symbol(*$6),
843                                                             *new ast::ArrayListVar(@7, *$7),
844                                                             *new ast::ArrayListVar(@3, *tmp),
845                                                             *$9);
846                                   delete $6;
847                                 }
848 | HIDDEN FUNCTION ID functionDeclarationArguments functionDeclarationBreak functionBody END {
849                                   ast::exps_t* tmp = new ast::exps_t;
850                                   $$ = new ast::FunctionDec(@$,
851                                                             symbol::Symbol(*$3),
852                                                             *new ast::ArrayListVar(@4, *$4),
853                                                             *new ast::ArrayListVar(@$, *tmp),
854                                                             *$6);
855                                   delete $3;
856                                 }
857 ;
858
859 /*
860 ** -*- FUNCTION DECLARATION RETURNS -*-
861 */
862 /* Simple Forward to idList */
863 functionDeclarationReturns :
864 idList                          { $$ = $1; }
865 ;
866
867 /*
868 ** -*- FUNCTION DECLARATION ARGUMENTS -*-
869 */
870 /* Arguments passed to a function in it's declaration. */
871 functionDeclarationArguments :
872 LPAREN idList RPAREN            { $$ = $2; }
873 | LPAREN RPAREN                 { $$ = new ast::exps_t; }
874 | /* Epsilon */                 { $$ = new ast::exps_t; }
875 ;
876
877 /*
878 ** -*- ID LIST -*-
879 */
880 /* ID (,ID)* */
881 idList:
882 idList COMMA ID                 {
883                                   $1->push_back(new ast::SimpleVar(@3, symbol::Symbol(*$3)));
884                                   delete $3;
885                                   $$ = $1;
886                                 }
887 | ID                            {
888                                   $$ = new ast::exps_t;
889                                   $$->push_back(new ast::SimpleVar(@$, symbol::Symbol(*$1)));
890                                   delete $1;
891                                 }
892 ;
893
894 /*
895 ** -*- FUNCTION DECLARATION BREAK -*-
896 */
897 /* Fake Rule : How can we be sure this is the 'function' prototype ending */
898 functionDeclarationBreak :
899 lineEnd                         { /* !! Do Nothing !! */ }
900 | SEMI                          { /* !! Do Nothing !! */ }
901 | SEMI EOL                      { /* !! Do Nothing !! */ }
902 | COMMA                         { /* !! Do Nothing !! */ }
903 | COMMA EOL                     { /* !! Do Nothing !! */ }
904 ;
905
906 /*
907 ** -*- FUNCTION BODY -*-
908 */
909 /* What may content a function */
910 functionBody :
911 expressions                     { $$ = $1; }
912 | /* Epsilon */                 {
913                                   ast::exps_t* tmp = new ast::exps_t;
914                                   #ifdef BUILD_DEBUG_AST
915                                     tmp->push_back(new ast::CommentExp(@$, new std::wstring(L"Empty function body")));
916                                   #endif
917                                   $$ = new ast::SeqExp(@$, *tmp);
918                                 }
919 ;
920
921 /*
922 ** -*- CONDITION -*-
923 */
924 /* Condition for tests in Control Loop */
925 condition :
926 functionCall    %prec HIGHLEVEL         { $$ = $1; }
927 | variable      %prec HIGHLEVEL         { $$ = $1; }
928 ;
929
930 /*
931 ** -*- COMPARISON -*-
932 */
933 /* a way to compare two expressions */
934 comparison :
935 variable rightComparable                {
936                                           delete &($2->getLeft());
937                                           $2->setLeft(*$1);
938                                           $$ = $2;
939                                         }
940 | functionCall rightComparable          {
941                                           delete &($2->getLeft());
942                                           $2->setLeft(*$1);
943                                           $$ = $2;
944                                         }
945 ;
946
947 /*
948 ** -*- RIGHT COMPARABLE -*-
949 */
950 /* rightComparable for comparison */
951 rightComparable :
952 /* & */
953 AND variable                            { $$ = new ast::LogicalOpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::LogicalOpExp::logicalAnd, *$2); }
954 | AND functionCall                      { $$ = new ast::LogicalOpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::LogicalOpExp::logicalAnd, *$2); }
955 | AND COLON                             { $$ = new ast::LogicalOpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::LogicalOpExp::logicalAnd, * new ast::ColonVar(@$)); }
956 /* && */
957 | ANDAND variable                       { $$ = new ast::LogicalOpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::LogicalOpExp::logicalShortCutAnd, *$2); }
958 | ANDAND functionCall                   { $$ = new ast::LogicalOpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::LogicalOpExp::logicalShortCutAnd, *$2); }
959 | ANDAND COLON                          { $$ = new ast::LogicalOpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::LogicalOpExp::logicalShortCutAnd, * new ast::ColonVar(@$)); }
960 /* | */
961 | OR variable                           { $$ = new ast::LogicalOpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::LogicalOpExp::logicalOr, *$2); }
962 | OR functionCall                       { $$ = new ast::LogicalOpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::LogicalOpExp::logicalOr, *$2); }
963 | OR COLON                              { $$ = new ast::LogicalOpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::LogicalOpExp::logicalOr, * new ast::ColonVar(@$)); }
964 /* || */
965 | OROR variable                         { $$ = new ast::LogicalOpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::LogicalOpExp::logicalShortCutOr, *$2); }
966 | OROR functionCall                     { $$ = new ast::LogicalOpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::LogicalOpExp::logicalShortCutOr, *$2); }
967 | OROR COLON                            { $$ = new ast::LogicalOpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::LogicalOpExp::logicalShortCutOr, * new ast::ColonVar(@$)); }
968 /* == */
969 | EQ variable                           { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::eq, *$2); }
970 | EQ functionCall                       { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::eq, *$2); }
971 | EQ COLON                              { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::eq, * new ast::ColonVar(@$)); }
972 /* ~= */
973 | NE variable                           { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::ne, *$2); }
974 | NE functionCall                       { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::ne, *$2); }
975 | NE COLON                              { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::ne, * new ast::ColonVar(@$)); }
976 /* > */
977 | GT variable                           { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::gt, *$2); }
978 | GT functionCall                       { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::gt, *$2); }
979 | GT COLON                              { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::gt, * new ast::ColonVar(@$)); }
980 /* < */
981 | LT variable                           { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::lt, *$2); }
982 | LT functionCall                       { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::lt, *$2); }
983 | LT COLON                              { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::lt, * new ast::ColonVar(@$)); }
984 /* >= */
985 | GE variable                           { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::ge, *$2); }
986 | GE functionCall                       { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::ge, *$2); }
987 | GE COLON                              { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::ge, * new ast::ColonVar(@$)); }
988 /* <= */
989 | LE variable                           { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::le, *$2); }
990 | LE functionCall                       { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::le, *$2); }
991 | LE COLON                              { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::le, * new ast::ColonVar(@$)); }
992 ;
993
994 /*
995 ** -*- OPERATIONS -*-
996 */
997 /* Operations */
998 operation :
999 variable rightOperand                   {
1000                                           delete &($2->getLeft());
1001                                           $2->setLeft(*$1);
1002                                           $2->setLocation(@$);
1003                                           $$ = $2;
1004                                         }
1005 | functionCall rightOperand             {
1006                                           delete &($2->getLeft());
1007                                           $2->setLeft(*$1);
1008                                           $2->setLocation(@$);
1009                                           $$ = $2;
1010                                         }
1011 | MINUS variable        %prec UMINUS    { if ($2->isDoubleExp()) { $$ = $2->getAs<ast::DoubleExp>()->neg(); } else { $$ = new ast::OpExp(@$, *new ast::DoubleExp(@$, 0.0), ast::OpExp::unaryMinus, *$2); } }
1012 | MINUS functionCall    %prec UMINUS    { $$ = new ast::OpExp(@$, *new ast::DoubleExp(@$, 0.0), ast::OpExp::unaryMinus, *$2); }
1013 | PLUS variable                                     { $$ = $2; }
1014 | PLUS functionCall                                 { $$ = $2; }
1015 | variable POWER variable                       { $$ = new ast::OpExp(@$, *$1, ast::OpExp::power, *$3); }
1016 | variable POWER functionCall               { $$ = new ast::OpExp(@$, *$1, ast::OpExp::power, *$3); }
1017 | functionCall POWER variable               { $$ = new ast::OpExp(@$, *$1, ast::OpExp::power, *$3); }
1018 | functionCall POWER functionCall           { $$ = new ast::OpExp(@$, *$1, ast::OpExp::power, *$3); }
1019 | variable DOTPOWER variable                { $$ = new ast::OpExp(@$, *$1, ast::OpExp::dotpower, *$3); }
1020 | variable DOTPOWER functionCall            { $$ = new ast::OpExp(@$, *$1, ast::OpExp::dotpower, *$3); }
1021 | functionCall DOTPOWER variable            { $$ = new ast::OpExp(@$, *$1, ast::OpExp::dotpower, *$3); }
1022 | functionCall DOTPOWER functionCall    { $$ = new ast::OpExp(@$, *$1, ast::OpExp::dotpower, *$3); }
1023 | variable QUOTE                                    { $$ = new ast::TransposeExp(@$, *$1, ast::TransposeExp::_Conjugate_); }
1024 | variable DOTQUOTE                                 { $$ = new ast::TransposeExp(@$, *$1, ast::TransposeExp::_NonConjugate_); }
1025 | functionCall QUOTE                            { $$ = new ast::TransposeExp(@$, *$1, ast::TransposeExp::_Conjugate_); }
1026 | functionCall DOTQUOTE                         { $$ = new ast::TransposeExp(@$, *$1, ast::TransposeExp::_NonConjugate_); }
1027 ;
1028
1029 /*
1030 ** -*- RIGHT OPERAND -*-
1031 */
1032 /* rightOperand for operation */
1033 rightOperand :
1034 /*   '+'   '.+'   '.+.'?   */
1035 PLUS variable                           { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::plus, *$2); }
1036 | PLUS functionCall                     { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::plus, *$2); }
1037 /*   '-'   '.-'   */
1038 | MINUS variable                        { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::minus, *$2); }
1039 | MINUS functionCall                    { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::minus, *$2); }
1040 /*   '*'   '.*'   '.*.'   '*.'   */
1041 | TIMES variable                        { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::times, *$2); }
1042 | TIMES functionCall                    { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::times, *$2); }
1043 | DOTTIMES variable                     { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::dottimes, *$2); }
1044 | DOTTIMES functionCall                 { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::dottimes, *$2); }
1045 | KRONTIMES variable                    { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::krontimes, *$2); }
1046 | KRONTIMES functionCall                { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::krontimes, *$2); }
1047 | CONTROLTIMES variable                 { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::controltimes, *$2); }
1048 | CONTROLTIMES functionCall                     { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::controltimes, *$2); }
1049 /*   '/'   './'   './.'   '/.'   */
1050 | RDIVIDE variable                      { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::rdivide, *$2); }
1051 | RDIVIDE functionCall                  { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::rdivide, *$2); }
1052 | DOTRDIVIDE variable                   { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::dotrdivide, *$2); }
1053 | DOTRDIVIDE functionCall               { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::dotrdivide, *$2); }
1054 | KRONRDIVIDE variable                  { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::kronrdivide, *$2); }
1055 | KRONRDIVIDE functionCall              { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::kronrdivide, *$2); }
1056 | CONTROLRDIVIDE variable               { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::controlrdivide, *$2); }
1057 | CONTROLRDIVIDE functionCall           { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::controlrdivide, *$2); }
1058 /*   '\'   '.\'   '.\.'   '\.'   */
1059 | LDIVIDE variable                      { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::ldivide, *$2); }
1060 | LDIVIDE functionCall                  { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::ldivide, *$2); }
1061 | DOTLDIVIDE variable                   { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::dotldivide, *$2); }
1062 | DOTLDIVIDE functionCall               { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::dotldivide, *$2); }
1063 | KRONLDIVIDE variable                  { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::kronldivide, *$2); }
1064 | KRONLDIVIDE functionCall              { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::kronldivide, *$2); }
1065 | CONTROLLDIVIDE variable                       { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::controlldivide, *$2); }
1066 | CONTROLLDIVIDE functionCall           { $$ = new ast::OpExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), ast::OpExp::controlldivide, *$2); }
1067 ;
1068
1069 /*
1070 ** -*- LISTABLE BEGIN -*-
1071 */
1072 /* May have no stride in the list, assume it is 1. */
1073 listableBegin :
1074 COLON variable                          { $$ = $2; }
1075 | COLON functionCall                    { $$ = $2; }
1076 ;
1077
1078 /*
1079 ** -*- LISTABLE END -*-
1080 */
1081 /* Stride parameter or not. */
1082 listableEnd :
1083 listableBegin COLON variable            { $$ = new ast::ListExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), *$1, *$3, true); }
1084 | listableBegin COLON functionCall      { $$ = new ast::ListExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), *$1, *$3, true); }
1085 | listableBegin %prec LISTABLE          { $$ = new ast::ListExp(@$, *new ast::CommentExp(@$, new std::wstring(L"Should not stay in that state")), *new ast::DoubleExp(@$, 1.0), *$1); }
1086 ;
1087
1088 /*
1089 ** -*- VARIABLE -*-
1090 */
1091 /* Variables */
1092 variable :
1093 NOT variable                            %prec NOT       { $$ = new ast::NotExp(@$, *$2); }
1094 | NOT functionCall                      %prec NOT       { $$ = new ast::NotExp(@$, *$2); }
1095 | variable DOT ID                       %prec UPLEVEL   { $$ = new ast::FieldExp(@$, *$1, *new ast::SimpleVar(@$, symbol::Symbol(*$3))); delete $3;}
1096 | variable DOT keywords         %prec UPLEVEL   { $$ = new ast::FieldExp(@$, *$1, *$3); }
1097 | variable DOT functionCall                             {
1098                                                           $3->setName(new ast::FieldExp(@$, *$1, $3->getName()));
1099                                                           $3->setLocation(@$);
1100                                                           $$ = $3;
1101 }
1102 | functionCall DOT variable                             { $$ = new ast::FieldExp(@$, *$1, *$3); }
1103 | functionCall DOT keywords                             { $$ = new ast::FieldExp(@$, *$1, *$3); }
1104 | functionCall DOT functionCall                         {
1105                                                           $3->setName(new ast::FieldExp(@$, *$1, $3->getName()));
1106                                                           $3->setLocation(@$);
1107                                                           $$ = $3;
1108 }
1109 | variable listableEnd                                  {
1110     $$ = new ast::ListExp(@$, *$1, *($2->getStep().clone()), *($2->getEnd().clone()), $2->hasExplicitStep());
1111     delete($2);
1112 }
1113 | functionCall listableEnd              %prec UPLEVEL   {
1114     $$ = new ast::ListExp(@$, *$1, *($2->getStep().clone()), *($2->getEnd().clone()), $2->hasExplicitStep());
1115     delete($2);
1116 }
1117 | matrix                                                { $$ = $1; }
1118 | cell                                                  { $$ = $1; }
1119 | operation                             %prec UPLEVEL           { $$ = $1; }
1120 | ID                                    %prec LISTABLE  { $$ = new ast::SimpleVar(@$, symbol::Symbol(*$1)); delete $1;}
1121 | VARINT                                %prec LISTABLE  { $$ = new ast::DoubleExp(@$, $1); }
1122 | NUM                                   %prec LISTABLE  { $$ = new ast::DoubleExp(@$, $1); }
1123 | VARFLOAT                                              { $$ = new ast::DoubleExp(@$, $1); }
1124 | STR                                                   { $$ = new ast::StringExp(@$, *$1); delete $1;}
1125 | DOLLAR                                                { $$ = new ast::DollarVar(@$); }
1126 | BOOLTRUE                              %prec BOOLTRUE  { $$ = new ast::BoolExp(@$, true); }
1127 | BOOLFALSE                             %prec BOOLFALSE { $$ = new ast::BoolExp(@$, false); }
1128 | LPAREN variable RPAREN                                { $$ = $2; }
1129 | LPAREN variableFields RPAREN                          { $$ = new ast::ArrayListExp(@$, *$2); }
1130 | comparison                                            { $$ = $1; }
1131 | variable LPAREN functionArgs RPAREN { $$ = new ast::CallExp(@$, *$1, *$3); }
1132 | functionCall LPAREN functionArgs RPAREN { $$ = new ast::CallExp(@$, *$1, *$3); }
1133 ;
1134
1135 /*
1136 ** -*- VARIABLE FIELDS -*-
1137 */
1138 /* variable (, variable)+ */
1139 variableFields :
1140 variableFields COMMA variable           {
1141                                           $1->push_back($3);
1142                                           $$ = $1;
1143                                         }
1144 | variableFields COMMA functionCall     {
1145                                           $1->push_back($3);
1146                                           $$ = $1;
1147                                         }
1148 | variable COMMA variable               {
1149                                           $$ = new ast::exps_t;
1150                                           $$->push_back($1);
1151                                           $$->push_back($3);
1152                                         }
1153 | functionCall COMMA functionCall       {
1154                                           $$ = new ast::exps_t;
1155                                           $$->push_back($1);
1156                                           $$->push_back($3);
1157                                         }
1158 | functionCall COMMA variable           {
1159                                           $$ = new ast::exps_t;
1160                                           $$->push_back($1);
1161                                           $$->push_back($3);
1162                                         }
1163 | variable COMMA functionCall           {
1164                                           $$ = new ast::exps_t;
1165                                           $$->push_back($1);
1166                                           $$->push_back($3);
1167 }
1168 ;
1169
1170 /*
1171 ** -*- CELL -*-
1172 */
1173 cell :
1174 LBRACE matrixOrCellLines RBRACE                                 { $$ = new ast::CellExp(@$, *$2); }
1175 | LBRACE EOL matrixOrCellLines RBRACE                   { $$ = new ast::CellExp(@$, *$3); }
1176 | LBRACE matrixOrCellLines matrixOrCellColumns RBRACE                   {
1177                                                                   $2->push_back(new ast::MatrixLineExp(@3, *$3));
1178                                                                   $$ = new ast::CellExp(@$, *$2);
1179                                                                 }
1180 | LBRACE EOL matrixOrCellLines matrixOrCellColumns RBRACE               {
1181                                                                   $3->push_back(new ast::MatrixLineExp(@4, *$4));
1182                                                                   $$ = new ast::CellExp(@$, *$3);
1183                                                                 }
1184 | LBRACE matrixOrCellColumns RBRACE                                     {
1185                                                                   ast::exps_t* tmp = new ast::exps_t;
1186                                                                   tmp->push_back(new ast::MatrixLineExp(@2, *$2));
1187                                                                   $$ = new ast::CellExp(@$, *tmp);
1188                                                                 }
1189 | LBRACE EOL matrixOrCellColumns RBRACE                         {
1190                                                                   ast::exps_t* tmp = new ast::exps_t;
1191                                                                   tmp->push_back(new ast::MatrixLineExp(@3, *$3));
1192                                                                   $$ = new ast::CellExp(@$, *tmp);
1193                                 }
1194 | LBRACE EOL RBRACE                                             { ast::exps_t* tmp = new ast::exps_t;$$ = new ast::CellExp(@$, *tmp); }
1195 | LBRACE RBRACE                                                 { ast::exps_t* tmp = new ast::exps_t;$$ = new ast::CellExp(@$, *tmp); }
1196 ;
1197
1198
1199 /*
1200 ** -*- MATRIX -*-
1201 */
1202 /* How Matrix are written */
1203 matrix :
1204 LBRACK matrixOrCellLines RBRACK                                 { $$ = new ast::MatrixExp(@$, *$2); }
1205 | LBRACK EOL matrixOrCellLines RBRACK                           { $$ = new ast::MatrixExp(@$, *$3); }
1206 | LBRACK matrixOrCellLines matrixOrCellColumns RBRACK                   {
1207                                                                   $2->push_back(new ast::MatrixLineExp(@3, *$3));
1208                                                                   $$ = new ast::MatrixExp(@$, *$2);
1209                                                                 }
1210 | LBRACK EOL matrixOrCellLines matrixOrCellColumns RBRACK               {
1211                                                                   $3->push_back(new ast::MatrixLineExp(@4, *$4));
1212                                                                   $$ = new ast::MatrixExp(@$, *$3);
1213                                                                 }
1214 | LBRACK matrixOrCellColumns RBRACK                                     {
1215                                                                   ast::exps_t* tmp = new ast::exps_t;
1216                                                                   tmp->push_back(new ast::MatrixLineExp(@2, *$2));
1217                                                                   $$ = new ast::MatrixExp(@$, *tmp);
1218                                                                 }
1219 | LBRACK EOL matrixOrCellColumns RBRACK                         {
1220                                                                   ast::exps_t* tmp = new ast::exps_t;
1221                                                                   tmp->push_back(new ast::MatrixLineExp(@3, *$3));
1222                                                                   $$ = new ast::MatrixExp(@$, *tmp);
1223                                                                 }
1224 | LBRACK EOL RBRACK                                             { ast::exps_t* tmp = new ast::exps_t;$$ = new ast::MatrixExp(@$, *tmp); }
1225 | LBRACK RBRACK                                                 { ast::exps_t* tmp = new ast::exps_t;$$ = new ast::MatrixExp(@$, *tmp); }
1226 ;
1227
1228 /*
1229 ** -*- MATRIX ORC ELL LINES -*-
1230 */
1231 /* Matrix or Cell Lines : matrixOrCellLine (matrixOrCellline)* */
1232 matrixOrCellLines :
1233 matrixOrCellLines matrixOrCellLine      {
1234                                           $1->push_back($2);
1235                                           $$ = $1;
1236                                         }
1237 | matrixOrCellLine                      {
1238                                           $$ = new ast::exps_t;
1239                                           $$->push_back($1);
1240                                         }
1241 //| matrixOrCellLines lineEnd {}
1242 //| COMMENT EOL {}
1243 ;
1244
1245 /*
1246 ** -*- MATRIX OR CELL LINE BREAK -*-
1247 */
1248 /* Fake Rule : How can we be sure this is a line ending in a Matrix/Cell */
1249 matrixOrCellLineBreak :
1250 SEMI                            { /* !! Do Nothing !! */ }
1251 | EOL                           { /* !! Do Nothing !! */ }
1252 | matrixOrCellLineBreak EOL     { /* !! Do Nothing !! */ }
1253 | matrixOrCellLineBreak SEMI    { /* !! Do Nothing !! */ }
1254 ;
1255
1256 /*
1257 ** -*- MATRIX OR CELL LINE -*-
1258 */
1259 /* Some matrix/cell columns with a special matrix/cell line break at the end */
1260 matrixOrCellLine :
1261 matrixOrCellColumns matrixOrCellLineBreak                               { $$ = new ast::MatrixLineExp(@$, *$1); }
1262 | matrixOrCellColumns matrixOrCellColumnsBreak matrixOrCellLineBreak    { $$ = new ast::MatrixLineExp(@$, *$1); }
1263 ;
1264
1265 /*
1266 ** -*- MATRIX OR CELL COLUMNS -*-
1267 */
1268 /* Matrix or Cell Columns : [variable|functinoCall] ([,|][variable|functionCall])* */
1269 matrixOrCellColumns :
1270 matrixOrCellColumns matrixOrCellColumnsBreak variable       %prec HIGHLEVEL {
1271                                                                                 $1->push_back($3);
1272                                                                                 $$ = $1;
1273                                                                             }
1274 | matrixOrCellColumns matrixOrCellColumnsBreak functionCall     %prec HIGHLEVEL {
1275                                                                                 $1->push_back($3);
1276                                                                                 $$ = $1;
1277                                                                             }
1278 | matrixOrCellColumns variable                              %prec HIGHLEVEL {
1279                                                                                 $1->push_back($2);
1280                                                                                 $$ = $1;
1281                                                                             }
1282 | matrixOrCellColumns functionCall                          %prec HIGHLEVEL {
1283                                                                                 $1->push_back($2);
1284                                                                                 $$ = $1;
1285                                                                             }
1286 | matrixOrCellColumns COMMENT                               %prec HIGHLEVEL {
1287                                                                                 $1->push_back(new ast::CommentExp(@2, $2));
1288                                                                                 $$ = $1;
1289                                                                             }
1290 | variable                                                  %prec HIGHLEVEL {
1291                                                                                 $$ = new ast::exps_t;
1292                                                                                 $$->push_back($1);
1293                                                                             }
1294 | functionCall                                              %prec HIGHLEVEL {
1295                                                                                 $$ = new ast::exps_t;
1296                                                                                 $$->push_back($1);
1297                                                                             }
1298 | COMMENT                                                                   {
1299                                                                                 $$ = new ast::exps_t;
1300                                                                                 $$->push_back(new ast::CommentExp(@$, $1));
1301                                                                             }
1302 ;
1303
1304 /*
1305 ** -*- MATRIX OR CELL COLUMNS BREAK -*-
1306 */
1307 /* How to tell the column is now ended. */
1308 matrixOrCellColumnsBreak :
1309 matrixOrCellColumnsBreak COMMA                                  { /* !! Do Nothing !! */ }
1310 | COMMA                                                         { /* !! Do Nothing !! */ }
1311 ;
1312
1313 /*
1314 ** -*- VARIABLE DECLARATION -*-
1315 */
1316 /* How to declare a new variable */
1317 variableDeclaration :
1318 assignable ASSIGN variable              %prec HIGHLEVEL { $$ = new ast::AssignExp(@$, *$1, *$3); }
1319 | assignable ASSIGN functionCall        %prec HIGHLEVEL { $$ = new ast::AssignExp(@$, *$1, *$3); }
1320 | functionCall ASSIGN variable          %prec HIGHLEVEL { $$ = new ast::AssignExp(@$, *$1, *$3); }
1321 | functionCall ASSIGN functionCall      %prec HIGHLEVEL { $$ = new ast::AssignExp(@$, *$1, *$3); }
1322 // --> Sugar Syntax for ':' meaning eye .* 1
1323 | assignable ASSIGN COLON                               { $$ = new ast::AssignExp(@$, *$1, *new ast::ColonVar(@3)); }
1324 | functionCall ASSIGN COLON                             { $$ = new ast::AssignExp(@$, *$1, *new ast::ColonVar(@3)); }
1325 // --> Strange Syntax : a = return (x)
1326 | assignable ASSIGN returnControl                       { $$ = new ast::AssignExp(@$, *$1, *$3); }
1327 | functionCall ASSIGN returnControl                     { $$ = new ast::AssignExp(@$, *$1, *$3); }
1328 ;
1329
1330
1331 /*
1332 ** -*- ASSIGNABLE -*-
1333 */
1334 /* What we can assign something to. */
1335 assignable :
1336 variable DOT ID                 %prec UPLEVEL           { $$ = new ast::FieldExp(@$, *$1, *new ast::SimpleVar(@$, symbol::Symbol(*$3))); delete $3;}
1337 | variable DOT keywords %prec UPLEVEL           { $$ = new ast::FieldExp(@$, *$1, *$3); }
1338 | variable DOT functionCall                 {
1339                                                 $3->setName(new ast::FieldExp(@$, *$1, $3->getName()));
1340                                                 $3->setLocation(@$);
1341                                                 $$ = $3;
1342                                             }
1343 | functionCall DOT variable                             { $$ = new ast::FieldExp(@$, *$1, *$3); }
1344 | functionCall DOT keywords                             { $$ = new ast::FieldExp(@$, *$1, *$3); }
1345 | functionCall DOT functionCall                         {
1346                                                           $3->setName(new ast::FieldExp(@$, *$1, $3->getName()));
1347                                                           $3->setLocation(@$);
1348                                                           $$ = $3;
1349                                             }
1350 | ID                                    %prec LISTABLE  { $$ = new ast::SimpleVar(@$, symbol::Symbol(*$1)); delete $1;}
1351 | multipleResults                                       { $$ = $1; }
1352 | variable LPAREN functionArgs RPAREN { $$ = new ast::CallExp(@$, *$1, *$3); }
1353 | functionCall LPAREN functionArgs RPAREN { $$ = new ast::CallExp(@$, *$1, *$3); }
1354 ;
1355
1356 /*
1357 ** -*- MULTIPLE RESULTS -*-
1358 */
1359 multipleResults :
1360 LBRACK matrixOrCellColumns RBRACK                       { $$ = new ast::AssignListExp(@$, *$2); }
1361 ;
1362
1363
1364 /*
1365 ** -*- IF CONTROL -*-
1366 */
1367 /* If Then Else End control block */
1368 ifControl :
1369 IF condition then thenBody END                          { $$ = new ast::IfExp(@$, *$2, *$4); }
1370 | IF condition then thenBody else elseBody END          {
1371     if ($6 != NULL)
1372     {
1373         $$ = new ast::IfExp(@$, *$2, *$4, *$6);
1374     }
1375     else
1376     {
1377        $$ = new ast::IfExp(@$, *$2, *$4);
1378     }
1379     }
1380 | IF condition then thenBody elseIfControl END          { $$ = new ast::IfExp(@$, *$2, *$4, *$5); }
1381 ;
1382
1383 /*
1384 ** -*- THEN BODY -*-
1385 */
1386 /* Instructions that can be managed inside THEN */
1387 thenBody :
1388 expressions                             { $$ = $1; }
1389 | /* Epsilon */                         {
1390     ast::exps_t* tmp = new ast::exps_t;
1391     #ifdef BUILD_DEBUG_AST
1392     tmp->push_back(new ast::CommentExp(@$, new std::wstring(L"Empty then body")));
1393     #endif
1394     $$ = new ast::SeqExp(@$, *tmp);
1395                                         }
1396 ;
1397
1398 /*
1399 ** -*- ELSE BODY -*-
1400 */
1401 /* Instructions that can be managed inside ELSE */
1402 elseBody :
1403 expressions                             { $$ = $1; }
1404 | /* Epsilon */                         {
1405                                         #ifdef BUILD_DEBUG_AST
1406                                             ast::exps_t* tmp = new ast::exps_t;
1407                                             tmp->push_back(new ast::CommentExp(@$, new std::wstring(L"Empty else body")));
1408                                             $$ = new ast::SeqExp(@$, *tmp);
1409                                         #else
1410                                             $$ = NULL;
1411                                         #endif
1412                                         }
1413 ;
1414
1415 /*
1416 ** -*- IF CONDITION BREAK -*-
1417 */
1418 /* Fake Rule : How can we be sure this is the 'if' condition ending */
1419 ifConditionBreak :
1420 SEMI                                                    { /* !! Do Nothing !! */ }
1421 | SEMI EOL                                              { /* !! Do Nothing !! */ }
1422 | COMMA                                                 { /* !! Do Nothing !! */ }
1423 | COMMA EOL                                             { /* !! Do Nothing !! */ }
1424 | EOL                                                   { /* !! Do Nothing !! */ }
1425 ;
1426
1427 /*
1428 ** -*- THEN -*-
1429 */
1430 /* Fake Rule : Only for lazy syntax */
1431 then :
1432 THEN                                                    { /* !! Do Nothing !! */ }
1433 | ifConditionBreak THEN                                 { /* !! Do Nothing !! */ }
1434 | ifConditionBreak THEN EOL                             { /* !! Do Nothing !! */ }
1435 | THEN ifConditionBreak                                 { /* !! Do Nothing !! */ }
1436 | ifConditionBreak                                      { /* !! Do Nothing !! */ }
1437 | /* Epsilon */                                         { /* !! Do Nothing !! */ }
1438 ;
1439
1440 /*
1441 ** -*- ELSE -*-
1442 */
1443 /* Fake Rule : Only for lazy syntax */
1444 else :
1445 ELSE                                                    { /* !! Do Nothing !! */ }
1446 | ELSE COMMA                                            { /* !! Do Nothing !! */ }
1447 | ELSE SEMI                                             { /* !! Do Nothing !! */ }
1448 | ELSE EOL                                              { /* !! Do Nothing !! */ }
1449 | ELSE COMMA EOL                                        { /* !! Do Nothing !! */ }
1450 | ELSE SEMI EOL                                         { /* !! Do Nothing !! */ }
1451 ;
1452
1453 /*
1454 ** -*- ELSEIF CONTROL
1455 */
1456 /* else if ... then ... */
1457 elseIfControl :
1458 ELSEIF condition then thenBody                                          {
1459                                                                                 ast::exps_t* tmp = new ast::exps_t;
1460                                                                                 tmp->push_back(new ast::IfExp(@$, *$2, *$4));
1461                                                                                 $$ = new ast::SeqExp(@$, *tmp);
1462                                                                         }
1463 | ELSEIF condition then thenBody else elseBody                          {
1464                                                                                 ast::exps_t* tmp = new ast::exps_t;
1465                                                                                 if( $6 == NULL)
1466                                         {
1467                                             tmp->push_back(new ast::IfExp(@$, *$2, *$4));
1468                                         }
1469                                         else
1470                                         {
1471                                             tmp->push_back(new ast::IfExp(@$, *$2, *$4, *$6));
1472                                         }
1473                                                                                 $$ = new ast::SeqExp(@$, *tmp);
1474
1475                                                                         }
1476 | ELSEIF condition then thenBody elseIfControl                          {
1477                                                                                 ast::exps_t* tmp = new ast::exps_t;
1478                                                                                 tmp->push_back(new ast::IfExp(@$, *$2, *$4, *$5));
1479                                                                                 $$ = new ast::SeqExp(@$, *tmp);
1480                                                                         }
1481 ;
1482
1483 //| ELSEIF condition then thenBody else elseBody elseIfControl          { $$ = new ast::CommentExp(@$, new std::wstring("!! FIXME !! Elseif additionnal control ??")); }
1484
1485
1486 /*
1487 ** -*- SELECT CONTROL -*-
1488 */
1489 /* Select Case Then End control block */
1490 selectControl :
1491 select selectable selectConditionBreak casesControl END                                                                 { $$ = new ast::SelectExp(@$, *$2, *$4); }
1492 | select selectable selectConditionBreak casesControl defaultCase elseBody END                  {
1493                                         if($6 == NULL)
1494                                         {
1495                                             $$ = new ast::SelectExp(@$, *$2, *$4);
1496                                         }
1497                                         else
1498                                         {
1499                                             $$ = new ast::SelectExp(@$, *$2, *$4, *$6);
1500                                         }
1501                                     }
1502 | select selectable COMMENT selectConditionBreak casesControl END                                               { $$ = new ast::SelectExp(@$, *$2, *$5); delete $3;}
1503 | select selectable COMMENT selectConditionBreak casesControl defaultCase elseBody END  {
1504                                         if($7 == NULL)
1505                                         {
1506                                             $$ = new ast::SelectExp(@$, *$2, *$5);
1507                                         }
1508                                         else
1509                                         {
1510                                             $$ = new ast::SelectExp(@$, *$2, *$5, *$7);
1511                                         }
1512                                         delete $3;
1513                                     }
1514 ;
1515
1516 /*
1517 ** -*- SELECT -*-
1518 */
1519 /* Fake Rule : Only for lazy syntax */
1520 select :
1521 SELECT                                  { /* !! Do Nothing !! */ }
1522 | SWITCH                                { /* !! Do Nothing !! */ }
1523 ;
1524
1525 /*
1526 ** -*- defaultCase -*-
1527 */
1528 /* Fake Rule : Only for lazy syntax */
1529 defaultCase :
1530 else                                                            { /* !! Do Nothing !! */ }
1531 | OTHERWISE                                                     { /* !! Do Nothing !! */ }
1532 | OTHERWISE COMMA                                       { /* !! Do Nothing !! */ }
1533 | OTHERWISE SEMI                                        { /* !! Do Nothing !! */ }
1534 | OTHERWISE EOL                                         { /* !! Do Nothing !! */ }
1535 | OTHERWISE COMMA EOL                           { /* !! Do Nothing !! */ }
1536 | OTHERWISE SEMI EOL                            { /* !! Do Nothing !! */ }
1537 ;
1538
1539 /*
1540 ** -*- SELECTABLE -*-
1541 */
1542 /* On what can a select bloc be switch. */
1543 selectable :
1544 variable                                { $$ = $1; }
1545 | functionCall                  { $$ = $1; }
1546 ;
1547
1548 /*
1549 ** -*- SELECT CONDITION BREAK -*-
1550 */
1551 /* Fake Rule : How can we be sure this is the 'select' condition ending. */
1552 selectConditionBreak :
1553 EOL                                                             { /* !! Do Nothing !! */ }
1554 | COMMA EOL                                             { /* !! Do Nothing !! */ }
1555 | SEMI EOL                                              { /* !! Do Nothing !! */ }
1556 | COMMA                                                 { /* !! Do Nothing !! */ }
1557 | SEMI                                                  { /* !! Do Nothing !! */ }
1558 ;
1559
1560 /*
1561 ** -*- CASE CONTROL -*-
1562 */
1563 /* (Case ... Then ...)+ control block */
1564 casesControl :
1565 CASE variable caseControlBreak caseBody                                                 {
1566                                                                                                                                   $$ = new ast::exps_t;
1567                                                                                                                                   $$->push_back(new ast::CaseExp(@$, *$2, *$4));
1568                                                                                                                                 }
1569 | CASE functionCall caseControlBreak caseBody                                   {
1570                                                                                                                                   $$ = new ast::exps_t;
1571                                                                                                                                   $$->push_back(new ast::CaseExp(@$, *$2, *$4));
1572                                                                                                                                 }
1573 | comments CASE variable caseControlBreak caseBody                              {
1574                                                                                                                                   $$ = new ast::exps_t;
1575                                                                                                                                   $$->push_back(new ast::CaseExp(@$, *$3, *$5));
1576                                                                                                                                 }
1577 | comments CASE functionCall caseControlBreak caseBody          {
1578                                                                                                                                   $$ = new ast::exps_t;
1579                                                                                                                                   $$->push_back(new ast::CaseExp(@$, *$3, *$5));
1580                                                                                                                                 }
1581 | casesControl CASE variable caseControlBreak caseBody                  {
1582                                                                                                                                   $1->push_back(new ast::CaseExp(@$, *$3, *$5));
1583                                                                                                                                   $$ = $1;
1584                                                                                                                                 }
1585 | casesControl CASE functionCall caseControlBreak caseBody              {
1586                                                                                                                                   $1->push_back(new ast::CaseExp(@$, *$3, *$5));
1587                                                                                                                                   $$ = $1;
1588                                                                                                                                 }
1589 ;
1590
1591 caseBody :
1592 expressions                             { $$ = $1; }
1593 | /* Epsilon */                 {
1594                             ast::exps_t* tmp = new ast::exps_t;
1595                             #ifdef BUILD_DEBUG_AST
1596                                 tmp->push_back(new ast::CommentExp(@$, new std::wstring(L"Empty case body")));
1597                             #endif
1598                             $$ = new ast::SeqExp(@$, *tmp);
1599                                                 }
1600 ;
1601
1602 /*
1603 ** -*- CASE CONTROL BREAK -*-
1604 */
1605 /* Fake Rule : How can we be sure this is the 'case' ending */
1606 caseControlBreak :
1607 THEN                                            { /* !! Do Nothing !! */ }
1608 | COMMA                                         { /* !! Do Nothing !! */ }
1609 | SEMI                                          { /* !! Do Nothing !! */ }
1610 | EOL                                           { /* !! Do Nothing !! */ }
1611 | THEN EOL                                      { /* !! Do Nothing !! */ }
1612 | COMMA EOL                                     { /* !! Do Nothing !! */ }
1613 | SEMI EOL                                      { /* !! Do Nothing !! */ }
1614 | THEN COMMA                            { /* !! Do Nothing !! */ }
1615 | THEN COMMA EOL                        { /* !! Do Nothing !! */ }
1616 | THEN SEMI                                     { /* !! Do Nothing !! */ }
1617 | THEN SEMI EOL                         { /* !! Do Nothing !! */ }
1618 | /* Epsilon */         %prec CONTROLBREAK              { /* !! Do Nothing !! */ }
1619 ;
1620
1621 /*
1622 ** -*- FOR CONTROL -*-
1623 */
1624 /* For ... End control block */
1625 forControl :
1626 FOR ID ASSIGN forIterator forConditionBreak forBody END                 { $$ = new ast::ForExp(@$, *new ast::VarDec(@3, symbol::Symbol(*$2), *$4), *$6); delete $2;}
1627 | FOR LPAREN ID ASSIGN forIterator RPAREN forConditionBreak forBody END { $$ = new ast::ForExp(@$, *new ast::VarDec(@4, symbol::Symbol(*$3), *$5), *$8); delete $3;}
1628 ;
1629
1630 /*
1631 ** -*- FOR ITERATOR -*-
1632 */
1633 /* For loop variable to tell the number of iterations. */
1634 forIterator :
1635 functionCall            %prec UPLEVEL           { $$ = $1; }
1636 | variable              %prec UPLEVEL           { $$ = $1; }
1637 ;
1638
1639
1640 /*
1641 ** -*- FOR CONDITION BREAK -*-
1642 */
1643 /* Fake Rule : How can we be sure this is the 'for' condition ending. */
1644 forConditionBreak :
1645 EOL                                             { /* !! Do Nothing !! */ }
1646 | SEMI                                          { /* !! Do Nothing !! */ }
1647 | SEMI EOL                                      { /* !! Do Nothing !! */ }
1648 | COMMA                                         { /* !! Do Nothing !! */ }
1649 | COMMA EOL                                     { /* !! Do Nothing !! */ }
1650 | DO                                            { /* !! Do Nothing !! */ }
1651 | DO EOL                                        { /* !! Do Nothing !! */ }
1652 | /* Epsilon */                                 { /* !! Do Nothing !! */ }
1653 ;
1654
1655 forBody :
1656 expressions                     { $$ = $1; }
1657 | /* Epsilon */                 {
1658                     ast::exps_t* tmp = new ast::exps_t;
1659                     #ifdef BUILD_DEBUG_AST
1660                         tmp->push_back(new ast::CommentExp(@$, new std::wstring(L"Empty for body")));
1661                     #endif
1662                     $$ = new ast::SeqExp(@$, *tmp);
1663                                 }
1664 ;
1665
1666 /*
1667 ** -*- WHILE CONTROL -*-
1668 */
1669 /* while ... End control block. */
1670 whileControl :
1671 WHILE condition whileConditionBreak whileBody END       { $$ = new ast::WhileExp(@$, *$2, *$4); }
1672 ;
1673
1674 /*
1675 ** -*- WHILE BODY -*-
1676 */
1677 /* Which instructions can be used in a while loop. */
1678 whileBody :
1679 expressions             { $$ = $1; }
1680 | /* Epsilon */                 {
1681                             ast::exps_t* tmp = new ast::exps_t;
1682                             #ifdef BUILD_DEBUG_AST
1683                                 tmp->push_back(new ast::CommentExp(@$, new std::wstring(L"Empty while body")));
1684                             #endif
1685                             $$ = new ast::SeqExp(@$, *tmp);
1686                         }
1687 ;
1688
1689 /*
1690 ** -*- WHILE CONDITION BREAK -*-
1691 */
1692 /* Fake Rule : How can we be sure this is the 'while' condition ending. */
1693 whileConditionBreak :
1694 COMMA                   { /* !! Do Nothing !! */ }
1695 | SEMI                  { /* !! Do Nothing !! */ }
1696 | DO                    { /* !! Do Nothing !! */ }
1697 | DO COMMA              { /* !! Do Nothing !! */ }
1698 | DO SEMI               { /* !! Do Nothing !! */ }
1699 | THEN                  { /* !! Do Nothing !! */ }
1700 | THEN COMMA            { /* !! Do Nothing !! */ }
1701 | THEN SEMI             { /* !! Do Nothing !! */ }
1702 | COMMENT EOL           { delete $1;/* !! Do Nothing !! */ }
1703 | EOL                   { /* !! Do Nothing !! */ }
1704 | COMMA EOL             { /* !! Do Nothing !! */ }
1705 | SEMI EOL              { /* !! Do Nothing !! */ }
1706 | DO EOL                { /* !! Do Nothing !! */ }
1707 | DO COMMA EOL          { /* !! Do Nothing !! */ }
1708 | DO SEMI EOL           { /* !! Do Nothing !! */ }
1709 | THEN EOL              { /* !! Do Nothing !! */ }
1710 | THEN COMMA EOL        { /* !! Do Nothing !! */ }
1711 | THEN SEMI EOL         { /* !! Do Nothing !! */ }
1712 ;
1713
1714 /*
1715 ** -*- TRY CONTROL -*-
1716 */
1717 /* try ... catch ... end control block. */
1718 tryControl :
1719 TRY catchBody CATCH catchBody END               { $$ =new ast::TryCatchExp(@$, *$2, *$4); }
1720 | TRY catchBody END                             {
1721                                                     ast::exps_t* tmp = new ast::exps_t;
1722                                                     #ifdef BUILD_DEBUG_AST
1723                                                         tmp->push_back(new ast::CommentExp(@$, new std::wstring(L"Empty catch body")));
1724                                                     #endif
1725                                                     $$ = new ast::TryCatchExp(@$, *$2, *new ast::SeqExp(@$, *tmp));
1726                                                 }
1727 ;
1728
1729 /*
1730 ** -*- CATCH BODY -*-
1731 */
1732 /* Wich instructions can be used in a catch control. */
1733 catchBody :
1734 expressions                     { $$ = $1; }
1735 | EOL expressions               { $$ = $2; }
1736 | SEMI expressions              { $$ = $2; }
1737 | COMMA expressions             { $$ = $2; }
1738 | EOL                           {
1739                                     ast::exps_t* tmp = new ast::exps_t;
1740                                     #ifdef BUILD_DEBUG_AST
1741                                         tmp->push_back(new ast::CommentExp(@$, new std::wstring(L"Empty catch body")));
1742                                     #endif
1743                                     $$ = new ast::SeqExp(@$, *tmp);
1744                                 }
1745 | /* Epsilon */                 {
1746                                     ast::exps_t* tmp = new ast::exps_t;
1747                                     #ifdef BUILD_DEBUG_AST
1748                                         tmp->push_back(new ast::CommentExp(@$, new std::wstring(L"Empty catch body")));
1749                                     #endif
1750                                     $$ = new ast::SeqExp(@$, *tmp);
1751                                 }
1752 ;
1753
1754 /*
1755 ** -*- RETURN CONTROL -*-
1756 */
1757 /* Make a break in a function or make the variable getting one scope up. */
1758 returnControl :
1759 RETURN                          { $$ = new ast::ReturnExp(@$); }
1760 | RETURN variable   { $$ = new ast::ReturnExp(@$, $2); }
1761 | RETURN functionCall   { $$ = new ast::ReturnExp(@$, $2); }
1762 ;
1763
1764 /*
1765 ** -*- COMMENTS -*-
1766 */
1767 comments :
1768 COMMENT EOL { delete $1; }
1769 | comments COMMENT EOL { delete $2; }
1770 ;
1771
1772 /*
1773 ** -*- LINE END -*-
1774 */
1775 /* Comment can be added also to end a line */
1776 lineEnd :
1777 EOL
1778 | COMMENT EOL { delete $1; }
1779 ;
1780
1781 /*
1782 ** -*- KEYWORDS -*-
1783 */
1784 /* Some token can be used as fields var.if var.then */
1785 keywords :
1786 IF              { $$ = new ast::SimpleVar(@$, symbol::Symbol(L"if")); }
1787 | THEN          { $$ = new ast::SimpleVar(@$, symbol::Symbol(L"then")); }
1788 | ELSE          { $$ = new ast::SimpleVar(@$, symbol::Symbol(L"else")); }
1789 | ELSEIF        { $$ = new ast::SimpleVar(@$, symbol::Symbol(L"elseif")); }
1790 | END           { $$ = new ast::SimpleVar(@$, symbol::Symbol(L"end")); }
1791 | SELECT        { $$ = new ast::SimpleVar(@$, symbol::Symbol(L"select")); }
1792 | SWITCH        { $$ = new ast::SimpleVar(@$, symbol::Symbol(L"switch")); }
1793 | OTHERWISE     { $$ = new ast::SimpleVar(@$, symbol::Symbol(L"otherwise")); }
1794 | CASE          { $$ = new ast::SimpleVar(@$, symbol::Symbol(L"case")); }
1795 | FUNCTION      { $$ = new ast::SimpleVar(@$, symbol::Symbol(L"function")); }
1796 | ENDFUNCTION   { $$ = new ast::SimpleVar(@$, symbol::Symbol(L"endfunction")); }
1797 | HIDDENFUNCTION{ $$ = new ast::SimpleVar(@$, symbol::Symbol(L"#function")); }
1798 | HIDDEN        { $$ = new ast::SimpleVar(@$, symbol::Symbol(L"hidden")); }
1799 | FOR           { $$ = new ast::SimpleVar(@$, symbol::Symbol(L"for")); }
1800 | WHILE         { $$ = new ast::SimpleVar(@$, symbol::Symbol(L"while")); }
1801 | DO            { $$ = new ast::SimpleVar(@$, symbol::Symbol(L"do")); }
1802 | BREAK         { $$ = new ast::SimpleVar(@$, symbol::Symbol(L"break")); }
1803 | TRY           { $$ = new ast::SimpleVar(@$, symbol::Symbol(L"try")); }
1804 | CATCH         { $$ = new ast::SimpleVar(@$, symbol::Symbol(L"catch")); }
1805 | RETURN        { $$ = new ast::SimpleVar(@$, symbol::Symbol(L"return")); }
1806 ;
1807
1808 %%
1809 void yyerror(std::string msg) {
1810     if(!ParserSingleInstance::isStrictMode()
1811        || ParserSingleInstance::getExitStatus() == Parser::Succeded)
1812     {
1813         wchar_t* pstMsg = to_wide_string(msg.c_str());
1814         ParserSingleInstance::PrintError(pstMsg);
1815         ParserSingleInstance::setExitStatus(Parser::Failed);
1816         FREE(pstMsg);
1817     }
1818 }