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