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