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