]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - tools/elftosb/elftosb2/elftosb_parser.y
merged tx6dl-devel into denx master branch
[karo-tx-uboot.git] / tools / elftosb / elftosb2 / elftosb_parser.y
1 /*
2  * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
3  * See included license file for license details.
4  */
5
6 /* write header with token defines */
7 %defines
8
9 /* make it reentrant */
10 %pure-parser
11
12 /* put more info in error messages */
13 %error-verbose
14
15 /* enable location processing */
16 %locations
17
18 %{
19 #include "ElftosbLexer.h"
20 #include "ElftosbAST.h"
21 #include "Logging.h"
22 #include "Blob.h"
23 #include "format_string.h"
24 #include "Value.h"
25 #include "ConversionController.h"
26
27 using namespace elftosb;
28
29 //! Our special location type.
30 #define YYLTYPE token_loc_t
31
32 // this indicates that we're using our own type. it should be unset automatically
33 // but that's not working for some reason with the .hpp file.
34 #if defined(YYLTYPE_IS_TRIVIAL)
35         #undef YYLTYPE_IS_TRIVIAL
36         #define YYLTYPE_IS_TRIVIAL 0
37 #endif
38
39 //! Default location action
40 #define YYLLOC_DEFAULT(Current, Rhs, N) \
41         do {            \
42                 if (N)  \
43                 {               \
44                         (Current).m_firstLine = YYRHSLOC(Rhs, 1).m_firstLine;   \
45                         (Current).m_lastLine = YYRHSLOC(Rhs, N).m_lastLine;             \
46                 }               \
47                 else    \
48                 {               \
49                         (Current).m_firstLine = (Current).m_lastLine = YYRHSLOC(Rhs, 0).m_lastLine;     \
50                 }               \
51         } while (0)
52
53 //! Forward declaration of yylex().
54 static int yylex(YYSTYPE * lvalp, YYLTYPE * yylloc, ElftosbLexer * lexer);
55
56 // Forward declaration of error handling function.
57 static void yyerror(YYLTYPE * yylloc, ElftosbLexer * lexer, CommandFileASTNode ** resultAST, const char * error);
58
59 %}
60
61 /* symbol types */
62 %union {
63         int m_num;
64         elftosb::SizedIntegerValue * m_int;
65         Blob * m_blob;
66         std::string * m_str;
67         elftosb::ASTNode * m_ast;       // must use full name here because this is put into *.tab.hpp
68 }
69
70 /* extra parameters for the parser and lexer */
71 %parse-param    {ElftosbLexer * lexer}
72 %parse-param    {CommandFileASTNode ** resultAST}
73 %lex-param              {ElftosbLexer * lexer}
74
75 /* token definitions */
76 %token <m_str> TOK_IDENT                        "identifier"
77 %token <m_str> TOK_STRING_LITERAL       "string"
78 %token <m_int> TOK_INT_LITERAL          "integer"
79 %token <m_str> TOK_SECTION_NAME         "section name"
80 %token <m_str> TOK_SOURCE_NAME          "source name"
81 %token <m_blob> TOK_BLOB                        "binary object"
82 %token '('
83 %token ')'
84 %token '{'
85 %token '}'
86 %token '['
87 %token ']'
88 %token '='
89 %token ','
90 %token ';'
91 %token ':'
92 %token '>'
93 %token '.'
94 %token TOK_DOT_DOT                              ".."
95 %token '~'
96 %token '&'
97 %token '|'
98 %token '<'
99 %token '>'
100 %token '!'
101 %token TOK_AND                                  "&&"
102 %token TOK_OR                                   "||"
103 %token TOK_GEQ                                  ">="
104 %token TOK_LEQ                                  "<="
105 %token TOK_EQ                                   "=="
106 %token TOK_NEQ                                  "!="
107 %token TOK_POWER                                "**"
108 %token TOK_LSHIFT                               "<<"
109 %token TOK_RSHIFT                               ">>"
110 %token <m_int> TOK_INT_SIZE             "integer size"
111 %token TOK_OPTIONS              "options"
112 %token TOK_CONSTANTS    "constants"
113 %token TOK_SOURCES              "sources"
114 %token TOK_FILTERS              "filters"
115 %token TOK_SECTION              "section"
116 %token TOK_EXTERN               "extern"
117 %token TOK_FROM                 "from"
118 %token TOK_RAW                  "raw"
119 %token TOK_LOAD                 "load"
120 %token TOK_JUMP                 "jump"
121 %token TOK_CALL                 "call"
122 %token TOK_MODE                 "mode"
123 %token TOK_IF                   "if"
124 %token TOK_ELSE                 "else"
125 %token TOK_DEFINED              "defined"
126 %token TOK_INFO                 "info"
127 %token TOK_WARNING              "warning"
128 %token TOK_ERROR                "error"
129 %token TOK_SIZEOF               "sizeof"
130 %token TOK_DCD                  "dcd"
131 %token TOK_HAB                  "hab"
132 %token TOK_IVT                  "ivt"
133
134 /* operator precedence */
135 %left "&&" "||"
136 %left '>' '<' ">=" "<=" "==" "!="
137 %left '|'
138 %left '^'
139 %left '&'
140 %left "<<" ">>"
141 %left "**"
142 %left '+' '-'
143 %left '*' '/' '%'
144 %left '.'
145 %right UNARY_OP
146
147 /* nonterminal types - most nonterminal symbols are subclasses of ASTNode */
148 %type <m_ast> command_file blocks_list pre_section_block options_block const_def_list const_def_list_elem
149 %type <m_ast> const_def const_expr expr int_const_expr unary_expr int_value constants_block
150 %type <m_ast> sources_block source_def_list source_def_list_elem source_def
151 %type <m_ast> section_defs section_def section_contents full_stmt_list full_stmt_list_elem
152 %type <m_ast> basic_stmt load_stmt call_stmt from_stmt load_data load_target call_target
153 %type <m_ast> address_or_range load_target_opt call_arg_opt basic_stmt_list basic_stmt_list_elem
154 %type <m_ast> source_attr_list source_attr_list_elem source_attrs_opt
155 %type <m_ast> section_list section_list_elem symbol_ref mode_stmt
156 %type <m_ast> section_options_opt source_attr_list_opt
157 %type <m_ast> if_stmt else_opt message_stmt
158 %type <m_ast> bool_expr ivt_def assignment_list_opt
159
160 %type <m_num> call_or_jump dcd_opt
161
162 %destructor { delete $$; } TOK_IDENT TOK_STRING_LITERAL TOK_SECTION_NAME TOK_SOURCE_NAME TOK_BLOB TOK_INT_SIZE TOK_INT_LITERAL
163
164 %%
165
166 command_file    :       blocks_list section_defs
167                                                 {
168                                                         CommandFileASTNode * commandFile = new CommandFileASTNode();
169                                                         commandFile->setBlocks(dynamic_cast<ListASTNode*>($1));
170                                                         commandFile->setSections(dynamic_cast<ListASTNode*>($2));
171                                                         commandFile->setLocation(@1, @2);
172                                                         *resultAST = commandFile;
173                                                 }
174                                 ;
175
176 blocks_list             :       pre_section_block
177                                                 {
178                                                         ListASTNode * list = new ListASTNode();
179                                                         list->appendNode($1);
180                                                         $$ = list;
181                                                 }
182                                 |       blocks_list pre_section_block
183                                                 {
184                                                         dynamic_cast<ListASTNode*>($1)->appendNode($2);
185                                                         $$ = $1;
186                                                 }
187                                 ;
188
189 pre_section_block
190                                 :       options_block                   { $$ = $1; }
191                                 |       constants_block                 { $$ = $1; }
192                                 |       sources_block                   { $$ = $1; }
193                                 ;
194
195 options_block           :       "options" '{' const_def_list '}'
196                                                         {
197                                                                 $$ = new OptionsBlockASTNode(dynamic_cast<ListASTNode *>($3));
198                                                         }
199                                         ;
200
201 constants_block         :       "constants" '{' const_def_list '}'
202                                                         {
203                                                                 $$ = new ConstantsBlockASTNode(dynamic_cast<ListASTNode *>($3));
204                                                         }
205                                         ;
206
207 const_def_list          :       const_def_list_elem
208                                                         {
209                                                                 ListASTNode * list = new ListASTNode();
210                                                                 list->appendNode($1);
211                                                                 $$ = list;
212                                                         }
213                                         |       const_def_list const_def_list_elem
214                                                         {
215                                                                 dynamic_cast<ListASTNode*>($1)->appendNode($2);
216                                                                 $$ = $1;
217                                                         }
218                                         ;
219
220 const_def_list_elem     :       const_def ';'           { $$ = $1; }
221                                         |       /* empty */                     { $$ = NULL; }
222                                         ;
223
224 const_def                       :       TOK_IDENT '=' const_expr
225                                                         {
226                                                                 $$ = new AssignmentASTNode($1, $3);
227                                                                 $$->setLocation(@1, @3);
228                                                         }
229                                         ;
230
231 sources_block   :       "sources" '{' source_def_list '}'
232                                                 {
233                                                         $$ = new SourcesBlockASTNode(dynamic_cast<ListASTNode *>($3));
234                                                 }
235                                 ;
236
237 source_def_list :       source_def_list_elem
238                                                 {
239                                                         ListASTNode * list = new ListASTNode();
240                                                         list->appendNode($1);
241                                                         $$ = list;
242                                                 }
243                                 |       source_def_list source_def_list_elem
244                                                 {
245                                                         dynamic_cast<ListASTNode*>($1)->appendNode($2);
246                                                         $$ = $1;
247                                                 }
248                                 ;
249
250 source_def_list_elem
251                                 :               source_def source_attrs_opt ';'
252                                                         {
253                                                                 // tell the lexer that this is the name of a source file
254                                                                 SourceDefASTNode * node = dynamic_cast<SourceDefASTNode*>($1);
255                                                                 if ($2)
256                                                                 {
257                                                                         node->setAttributes(dynamic_cast<ListASTNode*>($2));
258                                                                 }
259                                                                 node->setLocation(node->getLocation(), @3);
260                                                                 lexer->addSourceName(node->getName());
261                                                                 $$ = $1;
262                                                         }
263                                 |               /* empty */             { $$ = NULL; }
264                                 ;
265
266 source_def              :               TOK_IDENT '=' TOK_STRING_LITERAL
267                                                         {
268                                                                 $$ = new PathSourceDefASTNode($1, $3);
269                                                                 $$->setLocation(@1, @3);
270                                                         }
271                                 |               TOK_IDENT '=' "extern" '(' int_const_expr ')'
272                                                         {
273                                                                 $$ = new ExternSourceDefASTNode($1, dynamic_cast<ExprASTNode*>($5));
274                                                                 $$->setLocation(@1, @6);
275                                                         }
276                                 ;
277
278 source_attrs_opt
279                                 :               '(' source_attr_list ')'                { $$ = $2; }
280                                 |               /* empty */                                             { $$ = NULL; }
281                                 ;
282
283 source_attr_list
284                                 :               source_attr_list_elem
285                                                         {
286                                                                 ListASTNode * list = new ListASTNode();
287                                                                 list->appendNode($1);
288                                                                 $$ = list;
289                                                         }
290                                 |               source_attr_list ',' source_attr_list_elem
291                                                         {
292                                                                 dynamic_cast<ListASTNode*>($1)->appendNode($3);
293                                                                 $$ = $1;
294                                                         }
295                                 ;
296                                                 
297 source_attr_list_elem
298                                 :               TOK_IDENT '=' const_expr
299                                                         {
300                                                                 $$ = new AssignmentASTNode($1, $3);
301                                                                 $$->setLocation(@1, @3);
302                                                         }
303                                 ;
304
305 section_defs    :               section_def
306                                                         {
307                                                                 ListASTNode * list = new ListASTNode();
308                                                                 list->appendNode($1);
309                                                                 $$ = list;
310                                                         }
311                                 |               section_defs section_def
312                                                         {
313                                                                 dynamic_cast<ListASTNode*>($1)->appendNode($2);
314                                                                 $$ = $1;
315                                                         }
316                                 ;
317
318 section_def             :               "section" '(' int_const_expr section_options_opt ')' section_contents
319                                                         {
320                                                                 SectionContentsASTNode * sectionNode = dynamic_cast<SectionContentsASTNode*>($6);
321                                                                 if (sectionNode)
322                                                                 {
323                                                                         ExprASTNode * exprNode = dynamic_cast<ExprASTNode*>($3);
324                                                                         sectionNode->setSectionNumberExpr(exprNode);
325                                                                         sectionNode->setOptions(dynamic_cast<ListASTNode*>($4));
326                                                                         sectionNode->setLocation(@1, sectionNode->getLocation());
327                                                                 }
328                                                                 $$ = $6;
329                                                         }
330                                 ;
331
332 section_options_opt
333                                 :               ';' source_attr_list_opt
334                                                         {
335                                                                 $$ = $2;
336                                                         }
337                                 |               /* empty */
338                                                         {
339                                                                 $$ = NULL;
340                                                         }
341                                 ;
342
343 source_attr_list_opt
344                                 :               source_attr_list
345                                                         {
346                                                                 $$ = $1;
347                                                         }
348                                 |               /* empty */
349                                                         {
350                                                                 $$ = NULL;
351                                                         }
352                                 ;
353
354 section_contents
355                                 :               "<=" load_data ';'
356                                                         {
357                                                                 DataSectionContentsASTNode * dataSection = new DataSectionContentsASTNode($2);
358                                                                 dataSection->setLocation(@1, @3);
359                                                                 $$ = dataSection;
360                                                         }
361                                 |               '{' full_stmt_list '}'
362                                                         {
363                                                                 ListASTNode * listNode = dynamic_cast<ListASTNode*>($2);
364                                                                 $$ = new BootableSectionContentsASTNode(listNode);
365                                                                 $$->setLocation(@1, @3);
366                                                         }
367                                 ;
368
369 full_stmt_list  :               full_stmt_list_elem
370                                                         {
371                                                                 ListASTNode * list = new ListASTNode();
372                                                                 list->appendNode($1);
373                                                                 $$ = list;
374                                                         }
375                                 |               full_stmt_list full_stmt_list_elem
376                                                         {
377                                                                 dynamic_cast<ListASTNode*>($1)->appendNode($2);
378                                                                 $$ = $1;
379                                                         }
380                                 ;
381
382 full_stmt_list_elem
383                                 :               basic_stmt ';'          { $$ = $1; }
384                                 |               from_stmt                       { $$ = $1; }
385                                 |               if_stmt                         { $$ = $1; }
386                                 |               /* empty */                     { $$ = NULL; }
387                                 ;
388
389 basic_stmt_list :               basic_stmt_list_elem
390                                                         {
391                                                                 ListASTNode * list = new ListASTNode();
392                                                                 list->appendNode($1);
393                                                                 $$ = list;
394                                                         }
395                                 |               basic_stmt_list basic_stmt_list_elem
396                                                         {
397                                                                 dynamic_cast<ListASTNode*>($1)->appendNode($2);
398                                                                 $$ = $1;
399                                                         }
400                                 ;
401
402 basic_stmt_list_elem
403                                 :               basic_stmt ';'          { $$ = $1; }
404                                 |               if_stmt                         { $$ = $1; }
405                                 |               /* empty */                     { $$ = NULL; }
406                                 ;
407
408 basic_stmt              :               load_stmt               { $$ = $1; }
409                                 |               call_stmt               { $$ = $1; }
410                                 |               mode_stmt               { $$ = $1; }
411                                 |               message_stmt    { $$ = $1; }
412                                 ;
413
414 load_stmt               :               "load" dcd_opt load_data load_target_opt
415                                                         {
416                                                                 LoadStatementASTNode * stmt = new LoadStatementASTNode();
417                                                                 stmt->setData($3);
418                                                                 stmt->setTarget($4);
419                                                                 // set dcd load flag if the "dcd" keyword was present.
420                                                                 if ($2)
421                                                                 {
422                                                                         stmt->setDCDLoad(true);
423                                                                 }
424                                                                 // set char locations for the statement
425                                                                 if ($4)
426                                                                 {
427                                                                         stmt->setLocation(@1, @4);
428                                                                 }
429                                                                 else
430                                                                 {
431                                                                         stmt->setLocation(@1, @3);
432                                                                 }
433                                                                 $$ = stmt;
434                                                         }
435                                 ;
436
437 dcd_opt                 :               "dcd"
438                                                         {
439                                                                 if (!elftosb::g_enableHABSupport)
440                                                                 {
441                                                                         yyerror(&yylloc, lexer, resultAST, "HAB features not supported with the selected family");
442                                                                         YYABORT;
443                                                                 }
444                                                                 
445                                                                 $$ = 1;
446                                                         }
447                                 |               /* empty */                     { $$ = 0; }
448
449 load_data               :               int_const_expr
450                                                         {
451                                                                 $$ = $1;
452                                                         }
453                                 |               TOK_STRING_LITERAL
454                                                         {
455                                                                 $$ = new StringConstASTNode($1);
456                                                                 $$->setLocation(@1);
457                                                         }
458                                 |               TOK_SOURCE_NAME
459                                                         {
460                                                                 $$ = new SourceASTNode($1);
461                                                                 $$->setLocation(@1);
462                                                         }
463                                 |               section_list
464                                                         {
465                                                                 $$ = new SectionMatchListASTNode(dynamic_cast<ListASTNode*>($1));
466                                                                 $$->setLocation(@1);
467                                                         }
468                                 |               section_list "from" TOK_SOURCE_NAME
469                                                         {
470                                                                 $$ = new SectionMatchListASTNode(dynamic_cast<ListASTNode*>($1), $3);
471                                                                 $$->setLocation(@1, @3);
472                                                         }
473                                 |               TOK_SOURCE_NAME '[' section_list ']'
474                                                         {
475                                                                 $$ = new SectionMatchListASTNode(dynamic_cast<ListASTNode*>($3), $1);
476                                                                 $$->setLocation(@1, @4);
477                                                         }
478                                 |               TOK_BLOB
479                                                         {
480                                                                 $$ = new BlobConstASTNode($1);
481                                                                 $$->setLocation(@1);
482                                                         }
483                                 |               ivt_def
484                                                         {
485                                                         }
486                                 ;
487
488 section_list    :               section_list_elem
489                                                         {
490                                                                 ListASTNode * list = new ListASTNode();
491                                                                 list->appendNode($1);
492                                                                 $$ = list;
493                                                         }
494                                 |               section_list ',' section_list_elem
495                                                         {
496                                                                 dynamic_cast<ListASTNode*>($1)->appendNode($3);
497                                                                 $$ = $1;
498                                                         }
499                                 ;
500
501 section_list_elem
502                                 :               TOK_SECTION_NAME
503                                                         {
504                                                                 $$ = new SectionASTNode($1, SectionASTNode::kInclude);
505                                                                 $$->setLocation(@1);
506                                                         }
507                                 |               '~' TOK_SECTION_NAME
508                                                         {
509                                                                 $$ = new SectionASTNode($2, SectionASTNode::kExclude);
510                                                                 $$->setLocation(@1, @2);
511                                                         }
512                                 ;
513
514 load_target_opt :               '>' load_target
515                                                         {
516                                                                 $$ = $2;
517                                                         }
518                                 |               /* empty */
519                                                         {
520                                                                 $$ = new NaturalLocationASTNode();
521 //                                                              $$->setLocation();
522                                                         }
523                                 ;
524
525 load_target             :               '.'
526                                                         {
527                                                                 $$ = new NaturalLocationASTNode();
528                                                                 $$->setLocation(@1);
529                                                         }
530                                 |               address_or_range
531                                                         {
532                                                                 $$ = $1;
533                                                         }
534                                 ;
535
536 ivt_def                 :               "ivt" '(' assignment_list_opt ')'
537                                                         {
538                                                                 IVTConstASTNode * ivt = new IVTConstASTNode();
539                                                                 if ($3)
540                                                                 {
541                                                                         ivt->setFieldAssignments(dynamic_cast<ListASTNode*>($3));
542                                                                 }
543                                                                 ivt->setLocation(@1, @4);
544                                                                 $$ = ivt;
545                                                         }
546                                 ;
547
548 assignment_list_opt     :       source_attr_list                { $$ = $1; }
549                                         |       /* empty */                             { $$ = NULL; }
550                                         ;
551
552 call_stmt               :               call_or_jump call_target call_arg_opt
553                                                         {
554                                                                 CallStatementASTNode * stmt = new CallStatementASTNode();
555                                                                 switch ($1)
556                                                                 {
557                                                                         case 1:
558                                                                                 stmt->setCallType(CallStatementASTNode::kCallType);
559                                                                                 break;
560                                                                         case 2:
561                                                                                 stmt->setCallType(CallStatementASTNode::kJumpType);
562                                                                                 break;
563                                                                         default:
564                                                                                 yyerror(&yylloc, lexer, resultAST, "invalid call_or_jump value");
565                                                                                 YYABORT;
566                                                                                 break;
567                                                                 }
568                                                                 stmt->setTarget($2);
569                                                                 stmt->setArgument($3);
570                                                                 stmt->setIsHAB(false);
571                                                                 if ($3)
572                                                                 {
573                                                                         stmt->setLocation(@1, @3);
574                                                                 }
575                                                                 else
576                                                                 {
577                                                                         stmt->setLocation(@1, @2);
578                                                                 }
579                                                                 $$ = stmt;
580                                                         }
581                                 |               "hab" call_or_jump address_or_range call_arg_opt
582                                                         {
583                                                                 if (!elftosb::g_enableHABSupport)
584                                                                 {
585                                                                         yyerror(&yylloc, lexer, resultAST, "HAB features not supported with the selected family");
586                                                                         YYABORT;
587                                                                 }
588                                                                 
589                                                                 CallStatementASTNode * stmt = new CallStatementASTNode();
590                                                                 switch ($2)
591                                                                 {
592                                                                         case 1:
593                                                                                 stmt->setCallType(CallStatementASTNode::kCallType);
594                                                                                 break;
595                                                                         case 2:
596                                                                                 stmt->setCallType(CallStatementASTNode::kJumpType);
597                                                                                 break;
598                                                                         default:
599                                                                                 yyerror(&yylloc, lexer, resultAST, "invalid call_or_jump value");
600                                                                                 YYABORT;
601                                                                                 break;
602                                                                 }
603                                                                 stmt->setTarget($3);
604                                                                 stmt->setArgument($4);
605                                                                 stmt->setIsHAB(true);
606                                                                 if ($4)
607                                                                 {
608                                                                         stmt->setLocation(@1, @4);
609                                                                 }
610                                                                 else
611                                                                 {
612                                                                         stmt->setLocation(@1, @3);
613                                                                 }
614                                                                 $$ = stmt;
615                                                         }
616                                 ;
617
618 call_or_jump    :               "call"          { $$ = 1; }
619                                 |               "jump"          { $$ = 2; }
620                                 ;
621
622 call_target             :               TOK_SOURCE_NAME
623                                                         {
624                                                                 $$ = new SymbolASTNode(NULL, $1);
625                                                                 $$->setLocation(@1);
626                                                         }
627                                 |               int_const_expr
628                                                         {
629                                                                 $$ = new AddressRangeASTNode($1, NULL);
630                                                                 $$->setLocation($1);
631                                                         }
632                                 ;
633
634 call_arg_opt    :               '(' int_const_expr ')'          { $$ = $2; }
635                                 |               '(' ')'                                         { $$ = NULL; }
636                                 |               /* empty */                                     { $$ = NULL; }
637                                 ;
638
639 from_stmt               :               "from" TOK_SOURCE_NAME '{' basic_stmt_list '}'
640                                                         {
641                                                                 $$ = new FromStatementASTNode($2, dynamic_cast<ListASTNode*>($4));
642                                                                 $$->setLocation(@1, @5);
643                                                         }
644                                 ;
645
646 mode_stmt               :               "mode" int_const_expr
647                                                         {
648                                                                 $$ = new ModeStatementASTNode(dynamic_cast<ExprASTNode*>($2));
649                                                                 $$->setLocation(@1, @2);
650                                                         }
651                                 ;
652
653 message_stmt    :               "info" TOK_STRING_LITERAL
654                                                         {
655                                                                 $$ = new MessageStatementASTNode(MessageStatementASTNode::kInfo, $2);
656                                                                 $$->setLocation(@1, @2);
657                                                         }
658                                 |               "warning" TOK_STRING_LITERAL
659                                                         {
660                                                                 $$ = new MessageStatementASTNode(MessageStatementASTNode::kWarning, $2);
661                                                                 $$->setLocation(@1, @2);
662                                                         }
663                                 |               "error" TOK_STRING_LITERAL
664                                                         {
665                                                                 $$ = new MessageStatementASTNode(MessageStatementASTNode::kError, $2);
666                                                                 $$->setLocation(@1, @2);
667                                                         }
668                                 ;
669
670 if_stmt                 :               "if" bool_expr '{' full_stmt_list '}' else_opt
671                                                         {
672                                                                 IfStatementASTNode * ifStmt = new IfStatementASTNode();
673                                                                 ifStmt->setConditionExpr(dynamic_cast<ExprASTNode*>($2));
674                                                                 ifStmt->setIfStatements(dynamic_cast<ListASTNode*>($4));
675                                                                 ifStmt->setElseStatements(dynamic_cast<ListASTNode*>($6));
676                                                                 ifStmt->setLocation(@1, @6);
677                                                                 $$ = ifStmt;
678                                                         }
679                                 ;
680
681 else_opt                :               "else" '{' full_stmt_list '}'
682                                                         {
683                                                                 $$ = $3;
684                                                         }
685                                 |               "else" if_stmt
686                                                         {
687                                                                 ListASTNode * list = new ListASTNode();
688                                                                 list->appendNode($2);
689                                                                 $$ = list;
690                                                                 $$->setLocation(@1, @2);
691                                                         }
692                                 |               /* empty */                     { $$ = NULL; }
693                                 ;
694
695 address_or_range        :       int_const_expr
696                                                         {
697                                                                 $$ = new AddressRangeASTNode($1, NULL);
698                                                                 $$->setLocation($1);
699                                                         }
700                                         |       int_const_expr ".." int_const_expr
701                                                         {
702                                                                 $$ = new AddressRangeASTNode($1, $3);
703                                                                 $$->setLocation(@1, @3);
704                                                         }
705                                         ;
706
707 const_expr              :       bool_expr
708                                                         {
709                                                                 $$ = $1;
710                                                         }
711                                 |       TOK_STRING_LITERAL
712                                                         {
713                                                                 $$ = new StringConstASTNode($1);
714                                                                 $$->setLocation(@1);
715                                                         }
716                                 ;
717
718 bool_expr               :       int_const_expr
719                                                 {
720                                                         $$ = $1;
721                                                 }
722                                 |       bool_expr '<' bool_expr
723                                                 {
724                                                         ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
725                                                         ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
726                                                         $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kLessThan, right);
727                                                         $$->setLocation(@1, @3);
728                                                 }
729                                 |       bool_expr '>' bool_expr
730                                                 {
731                                                         ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
732                                                         ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
733                                                         $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kGreaterThan, right);
734                                                         $$->setLocation(@1, @3);
735                                                 }
736                                 |       bool_expr ">=" bool_expr
737                                                 {
738                                                         ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
739                                                         ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
740                                                         $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kGreaterThanEqual, right);
741                                                         $$->setLocation(@1, @3);
742                                                 }
743                                 |       bool_expr "<=" bool_expr
744                                                 {
745                                                         ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
746                                                         ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
747                                                         $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kLessThanEqual, right);
748                                                         $$->setLocation(@1, @3);
749                                                 }
750                                 |       bool_expr "==" bool_expr
751                                                 {
752                                                         ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
753                                                         ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
754                                                         $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kEqual, right);
755                                                         $$->setLocation(@1, @3);
756                                                 }
757                                 |       bool_expr "!=" bool_expr
758                                                 {
759                                                         ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
760                                                         ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
761                                                         $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kNotEqual, right);
762                                                         $$->setLocation(@1, @3);
763                                                 }
764                                 |       bool_expr "&&" bool_expr
765                                                 {
766                                                         ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
767                                                         ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
768                                                         $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kBooleanAnd, right);
769                                                         $$->setLocation(@1, @3);
770                                                 }
771                                 |       bool_expr "||" bool_expr
772                                                 {
773                                                         ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
774                                                         ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
775                                                         $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kBooleanOr, right);
776                                                         $$->setLocation(@1, @3);
777                                                 }
778                                 |       '!' bool_expr %prec UNARY_OP
779                                                 {
780                                                         $$ = new BooleanNotExprASTNode(dynamic_cast<ExprASTNode*>($2));
781                                                         $$->setLocation(@1, @2);
782                                                 }
783                                 |       TOK_IDENT '(' TOK_SOURCE_NAME ')'
784                                                 {
785                                                         $$ = new SourceFileFunctionASTNode($1, $3);
786                                                         $$->setLocation(@1, @4);
787                                                 }
788                                 |       '(' bool_expr ')'
789                                                 {
790                                                         $$ = $2;
791                                                         $$->setLocation(@1, @3);
792                                                 }
793                                 |       "defined" '(' TOK_IDENT ')'
794                                                 {
795                                                         $$ = new DefinedOperatorASTNode($3);
796                                                         $$->setLocation(@1, @4);
797                                                 }
798                                 ;
799
800 int_const_expr  :       expr                            { $$ = $1; }
801                                 ;
802
803 symbol_ref              :       TOK_SOURCE_NAME ':' TOK_IDENT
804                                                         {
805                                                                 $$ = new SymbolASTNode($3, $1);
806                                                                 $$->setLocation(@1, @3);
807                                                         }
808                                 |       ':' TOK_IDENT
809                                                         {
810                                                                 $$ = new SymbolASTNode($2);
811                                                                 $$->setLocation(@1, @2);
812                                                         }
813                                 ;
814
815
816 expr                    :               int_value
817                                                         {
818                                                                 $$ = $1;
819                                                         }
820                                 |               TOK_IDENT
821                                                         {
822                                                                 $$ = new VariableExprASTNode($1);
823                                                                 $$->setLocation(@1);
824                                                         }
825                                 |               symbol_ref
826                                                         {
827                                                                 $$ = new SymbolRefExprASTNode(dynamic_cast<SymbolASTNode*>($1));
828                                                                 $$->setLocation(@1);
829                                                         }
830 /*                              |               expr '..' expr
831                                                         {
832                                                                 ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
833                                                                 ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
834                                                                 $$ = new RangeExprASTNode(left, right);
835                                                         }
836 */                              |               expr '+' expr
837                                                         {
838                                                                 ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
839                                                                 ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
840                                                                 $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kAdd, right);
841                                                                 $$->setLocation(@1, @3);
842                                                         }
843                                 |               expr '-' expr
844                                                         {
845                                                                 ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
846                                                                 ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
847                                                                 $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kSubtract, right);
848                                                                 $$->setLocation(@1, @3);
849                                                         }
850                                 |               expr '*' expr
851                                                         {
852                                                                 ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
853                                                                 ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
854                                                                 $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kMultiply, right);
855                                                                 $$->setLocation(@1, @3);
856                                                         }
857                                 |               expr '/' expr
858                                                         {
859                                                                 ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
860                                                                 ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
861                                                                 $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kDivide, right);
862                                                                 $$->setLocation(@1, @3);
863                                                         }
864                                 |               expr '%' expr
865                                                         {
866                                                                 ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
867                                                                 ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
868                                                                 $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kModulus, right);
869                                                                 $$->setLocation(@1, @3);
870                                                         }
871                                 |               expr "**" expr
872                                                         {
873                                                                 ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
874                                                                 ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
875                                                                 $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kPower, right);
876                                                                 $$->setLocation(@1, @3);
877                                                         }
878                                 |               expr '&' expr
879                                                         {
880                                                                 ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
881                                                                 ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
882                                                                 $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kBitwiseAnd, right);
883                                                                 $$->setLocation(@1, @3);
884                                                         }
885                                 |               expr '|' expr
886                                                         {
887                                                                 ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
888                                                                 ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
889                                                                 $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kBitwiseOr, right);
890                                                                 $$->setLocation(@1, @3);
891                                                         }
892                                 |               expr '^' expr
893                                                         {
894                                                                 ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
895                                                                 ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
896                                                                 $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kBitwiseXor, right);
897                                                                 $$->setLocation(@1, @3);
898                                                         }
899                                 |               expr "<<" expr
900                                                         {
901                                                                 ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
902                                                                 ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
903                                                                 $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kShiftLeft, right);
904                                                                 $$->setLocation(@1, @3);
905                                                         }
906                                 |               expr ">>" expr
907                                                         {
908                                                                 ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
909                                                                 ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
910                                                                 $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kShiftRight, right);
911                                                                 $$->setLocation(@1, @3);
912                                                         }
913                                 |               unary_expr
914                                                         {
915                                                                 $$ = $1;
916                                                         }
917                                 |               expr '.' TOK_INT_SIZE   
918                                                         {
919                                                                 $$ = new IntSizeExprASTNode(dynamic_cast<ExprASTNode*>($1), $3->getWordSize());
920                                                                 $$->setLocation(@1, @3);
921                                                         }
922                                 |               '(' expr ')'
923                                                         {
924                                                                 $$ = $2;
925                                                                 $$->setLocation(@1, @3);
926                                                         }
927                                 |       "sizeof" '(' symbol_ref ')'
928                                                 {
929                                                         $$ = new SizeofOperatorASTNode(dynamic_cast<SymbolASTNode*>($3));
930                                                         $$->setLocation(@1, @4);
931                                                 }
932                                 |       "sizeof" '(' TOK_IDENT ')'
933                                                 {
934                                                         $$ = new SizeofOperatorASTNode($3);
935                                                         $$->setLocation(@1, @4);
936                                                 }
937                                 |       "sizeof" '(' TOK_SOURCE_NAME ')'
938                                                 {
939                                                         $$ = new SizeofOperatorASTNode($3);
940                                                         $$->setLocation(@1, @4);
941                                                 }
942                                 ;
943
944 unary_expr              :               '+' expr %prec UNARY_OP
945                                                         {
946                                                                 $$ = $2;
947                                                         }
948                                 |               '-' expr %prec UNARY_OP
949                                                         {
950                                                                 $$ = new NegativeExprASTNode(dynamic_cast<ExprASTNode*>($2));
951                                                                 $$->setLocation(@1, @2);
952                                                         }
953                                 ;
954
955 int_value               :               TOK_INT_LITERAL
956                                                         {
957                                                                 $$ = new IntConstExprASTNode($1->getValue(), $1->getWordSize());
958                                                                 $$->setLocation(@1);
959                                                         }
960                                 ;
961
962 %%
963
964 /* code goes here */
965
966 static int yylex(YYSTYPE * lvalp, YYLTYPE * yylloc, ElftosbLexer * lexer)
967 {
968         int token = lexer->yylex();
969         *yylloc = lexer->getLocation();
970         lexer->getSymbolValue(lvalp);
971         return token;
972 }
973
974 static void yyerror(YYLTYPE * yylloc, ElftosbLexer * lexer, CommandFileASTNode ** resultAST, const char * error)
975 {
976         throw syntax_error(format_string("line %d: %s\n", yylloc->m_firstLine, error));
977 }
978