c8515cd0a60587787e5ddc51fa9d6a61190006b5
[fw/sdcc] / src / SDCC.y
1 /*-----------------------------------------------------------------------
2
3   SDCC.y - parser definition file for sdcc :
4           Written By : Sandeep Dutta . sandeep.dutta@usa.net (1997)
5
6    This program is free software; you can redistribute it and/or modify it
7    under the terms of the GNU General Public License as published by the
8    Free Software Foundation; either version 2, or (at your option) any
9    later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19    
20    In other words, you are welcome to use, share and improve this program.
21    You are forbidden to forbid anyone else to use, share and improve
22    what you give them.   Help stamp out software-hoarding!  
23 -------------------------------------------------------------------------*/
24 %{
25 #include <stdio.h>
26 #include <stdarg.h> 
27 #include <string.h>
28 #include "SDCCglobl.h"
29 #include "SDCCsymt.h"
30 #include "SDCChasht.h"
31 #include "SDCCval.h"
32 #include "SDCCmem.h"
33 #include "SDCCast.h"
34 #include "port.h"
35 #include "newalloc.h"
36 #include "SDCCerr.h"
37 #include "SDCCutil.h"
38
39 extern int yyerror (char *);
40 extern FILE     *yyin;
41 int NestLevel = 0 ;     /* current NestLevel       */
42 int stackPtr  = 1 ;     /* stack pointer           */
43 int xstackPtr = 0 ;     /* xstack pointer          */
44 int reentrant = 0 ; 
45 int blockNo   = 0 ;     /* sequential block number  */
46 int currBlockno=0 ;
47 extern int yylex();
48 int yyparse(void);
49 extern int noLineno ;
50 char lbuff[1024];      /* local buffer */
51
52 /* break & continue stacks */
53 STACK_DCL(continueStack  ,symbol *,MAX_NEST_LEVEL)
54 STACK_DCL(breakStack  ,symbol *,MAX_NEST_LEVEL)
55 STACK_DCL(forStack  ,symbol *,MAX_NEST_LEVEL)
56 STACK_DCL(swStk   ,ast   *,MAX_NEST_LEVEL)
57 STACK_DCL(blockNum,int,MAX_NEST_LEVEL*3)
58
59 value *cenum = NULL  ;  /* current enumeration  type chain*/
60
61 %}
62 %expect 6
63
64 %union {
65     symbol     *sym ;      /* symbol table pointer       */
66     structdef  *sdef;      /* structure definition       */
67     char       yychar[SDCC_NAME_MAX+1];
68     sym_link       *lnk ;      /* declarator  or specifier   */
69     int        yyint;      /* integer value returned     */
70     value      *val ;      /* for integer constant       */
71     initList   *ilist;     /* initial list               */
72     char       *yyinline; /* inlined assembler code */
73     ast       *asts;     /* expression tree            */
74 }
75
76 %token <yychar> IDENTIFIER TYPE_NAME
77 %token <val>   CONSTANT   STRING_LITERAL
78 %token SIZEOF TYPEOF 
79 %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
80 %token AND_OP OR_OP 
81 %token <yyint> MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
82 %token <yyint> SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
83 %token <yyint> XOR_ASSIGN OR_ASSIGN
84 %token TYPEDEF EXTERN STATIC AUTO REGISTER CODE EEPROM INTERRUPT SFR AT SBIT
85 %token REENTRANT USING  XDATA DATA IDATA PDATA VAR_ARGS CRITICAL NONBANKED BANKED
86 %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID BIT
87 %token STRUCT UNION ENUM ELIPSIS RANGE FAR
88 %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
89 %token NAKED JAVANATIVE OVERLAY
90 %token <yyinline> INLINEASM
91 %token IFX ADDRESS_OF GET_VALUE_AT_ADDRESS SPIL UNSPIL GETHBIT
92 %token BITWISEAND UNARYMINUS IPUSH IPOP PCALL  ENDFUNCTION JUMPTABLE
93 %token RRC RLC 
94 %token CAST CALL PARAM NULLOP BLOCK LABEL RECEIVE SEND ARRAYINIT
95
96 %type <yyint>  Interrupt_storage
97 %type <sym> identifier  declarator  declarator2 enumerator_list enumerator
98 %type <sym> struct_declarator
99 %type <sym> struct_declarator_list  struct_declaration   struct_declaration_list
100 %type <sym> declaration init_declarator_list init_declarator
101 %type <sym> declaration_list identifier_list parameter_identifier_list
102 %type <sym> declarator2_function_attributes while do for
103 %type <lnk> pointer type_specifier_list type_specifier type_name
104 %type <lnk> storage_class_specifier struct_or_union_specifier
105 %type <lnk> declaration_specifiers  sfr_reg_bit type_specifier2
106 %type <lnk> function_attribute function_attributes enum_specifier
107 %type <lnk> abstract_declarator abstract_declarator2 unqualified_pointer
108 %type <val> parameter_type_list parameter_list parameter_declaration opt_assign_expr
109 %type <sdef> stag opt_stag
110 %type <asts> primary_expr
111 %type <asts> postfix_expr unary_expr cast_expr multiplicative_expr
112 %type <asts> additive_expr shift_expr relational_expr equality_expr
113 %type <asts> and_expr exclusive_or_expr inclusive_or_expr logical_or_expr
114 %type <asts> logical_and_expr conditional_expr assignment_expr constant_expr
115 %type <asts> expr argument_expr_list function_definition expr_opt
116 %type <asts> statement_list statement labeled_statement compound_statement
117 %type <asts> expression_statement selection_statement iteration_statement
118 %type <asts> jump_statement function_body else_statement string_literal
119 %type <ilist> initializer initializer_list
120 %type <yyint> unary_operator  assignment_operator struct_or_union
121
122 %start file
123
124 %%
125
126 file
127    : external_definition       
128    | file external_definition
129    ;
130
131 external_definition
132    : function_definition     { 
133                                blockNo=0;
134                              }
135    | declaration             { 
136                                if ($1 && $1->type
137                                 && IS_FUNC($1->type))
138                                {
139                                    /* The only legal storage classes for 
140                                     * a function prototype (declaration)
141                                     * are extern and static. extern is the
142                                     * default. Thus, if this function isn't
143                                     * explicitly marked static, mark it
144                                     * extern.
145                                     */
146                                    if ($1->etype 
147                                     && IS_SPEC($1->etype)
148                                     && !SPEC_STAT($1->etype))
149                                    {
150                                         SPEC_EXTR($1->etype) = 1;
151                                    }
152                                }
153                                addSymChain ($1);
154                                allocVariables ($1) ;
155                                cleanUpLevel (SymbolTab,1);
156                              }
157    ;
158
159 function_definition
160    : declarator function_body  {   /* function type not specified */
161                                    /* assume it to be 'int'       */
162                                    addDecl($1,0,newIntLink());
163                                    $$ = createFunction($1,$2); 
164                                } 
165    | declaration_specifiers declarator function_body  
166                                 {   
167                                     pointerTypes($2->type,copyLinkChain($1));
168                                     addDecl($2,0,$1); 
169                                     $$ = createFunction($2,$3);   
170                                 }
171    ;
172
173 function_attribute
174    : function_attributes
175    | function_attributes function_attribute { $$ = mergeSpec($1,$2,"function_attribute"); }
176    ;
177
178 function_attributes
179    :  USING CONSTANT {
180                         $$ = newLink(SPECIFIER) ;
181                         FUNC_REGBANK($$) = (int) floatFromVal($2);
182                      }
183    |  REENTRANT      {  $$ = newLink (SPECIFIER);
184                         FUNC_ISREENT($$)=1;
185                      }
186    |  CRITICAL       {  $$ = newLink (SPECIFIER);
187                         FUNC_ISCRITICAL($$) = 1;
188                      }
189    |  NAKED          {  $$ = newLink (SPECIFIER);
190                         FUNC_ISNAKED($$)=1;
191                      }
192    |  JAVANATIVE     {  $$ = newLink (SPECIFIER);
193                         FUNC_ISJAVANATIVE($$)=1;
194                      }
195    |  OVERLAY        {  $$ = newLink (SPECIFIER);
196                         FUNC_ISOVERLAY($$)=1;
197                      }
198    |  NONBANKED      {$$ = newLink (SPECIFIER);
199                         FUNC_NONBANKED($$) = 1;
200                         if (FUNC_BANKED($$)) {
201                             werror(W_BANKED_WITH_NONBANKED);
202                         }
203                      }
204    |  BANKED         {$$ = newLink (SPECIFIER);
205                         FUNC_BANKED($$) = 1;
206                         if (FUNC_NONBANKED($$)) {
207                             werror(W_BANKED_WITH_NONBANKED);
208                         }
209                         if (SPEC_STAT($$)) {
210                             werror(W_BANKED_WITH_STATIC);
211                         }
212                      }
213    |  Interrupt_storage
214                      {
215                         $$ = newLink (SPECIFIER) ;
216                         FUNC_INTNO($$) = $1 ;
217                         FUNC_ISISR($$) = 1;
218                      }
219    ;
220
221 function_body
222    : compound_statement                   
223    | declaration_list compound_statement
224          {
225             werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
226             exit(1);
227          }
228    ;
229
230 primary_expr
231    : identifier      {  $$ = newAst_VALUE(symbolVal($1));  }
232    | CONSTANT        {  $$ = newAst_VALUE($1);  }
233    | string_literal  
234    | '(' expr ')'    {  $$ = $2 ;                   }
235    ;
236          
237 string_literal
238     : STRING_LITERAL                    { $$ = newAst_VALUE($1); }
239     ;
240
241 postfix_expr
242    : primary_expr
243    | postfix_expr '[' expr ']'          { $$ = newNode  ('[', $1, $3) ; }
244    | postfix_expr '(' ')'               { $$ = newNode  (CALL,$1,NULL); 
245                                           $$->left->funcName = 1;}
246    | postfix_expr '(' argument_expr_list ')'
247           {        
248             $$ = newNode  (CALL,$1,$3) ; $$->left->funcName = 1;
249           }
250    | postfix_expr '.' identifier       
251                       {    
252                         $3 = newSymbol($3->name,NestLevel);
253                         $3->implicit = 1;
254                         $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($3)));
255 /*                      $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($3))) ;                   */
256                       }
257    | postfix_expr PTR_OP identifier    
258                       { 
259                         $3 = newSymbol($3->name,NestLevel);
260                         $3->implicit = 1;                       
261                         $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($3)));
262                       }
263    | postfix_expr INC_OP   
264                       { $$ = newNode(INC_OP,$1,NULL);}
265    | postfix_expr DEC_OP
266                       { $$ = newNode(DEC_OP,$1,NULL); }
267    ;
268
269 argument_expr_list
270    : assignment_expr 
271    | assignment_expr ',' argument_expr_list { $$ = newNode(PARAM,$1,$3); }
272    ;
273
274 unary_expr
275    : postfix_expr
276    | INC_OP unary_expr        { $$ = newNode(INC_OP,NULL,$2);  }
277    | DEC_OP unary_expr        { $$ = newNode(DEC_OP,NULL,$2);  }
278    | unary_operator cast_expr { $$ = newNode($1,$2,NULL)    ;  }
279    | SIZEOF unary_expr        { $$ = newNode(SIZEOF,NULL,$2);  }
280    | SIZEOF '(' type_name ')' { $$ = newAst_VALUE(sizeofOp($3)); }
281    | TYPEOF unary_expr        { $$ = newNode(TYPEOF,NULL,$2);  }
282    ;
283               
284 unary_operator
285    : '&'    { $$ = '&' ;}
286    | '*'    { $$ = '*' ;}
287    | '+'    { $$ = '+' ;}
288    | '-'    { $$ = '-' ;}
289    | '~'    { $$ = '~' ;}
290    | '!'    { $$ = '!' ;}
291    ;
292
293 cast_expr
294    : unary_expr
295    | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst_LINK($2),$4); }
296    ;
297
298 multiplicative_expr
299    : cast_expr
300    | multiplicative_expr '*' cast_expr { $$ = newNode('*',$1,$3);}
301    | multiplicative_expr '/' cast_expr { $$ = newNode('/',$1,$3);}
302    | multiplicative_expr '%' cast_expr { $$ = newNode('%',$1,$3);}
303    ;
304
305 additive_expr
306    : multiplicative_expr
307    | additive_expr '+' multiplicative_expr { $$=newNode('+',$1,$3);}
308    | additive_expr '-' multiplicative_expr { $$=newNode('-',$1,$3);}
309    ;
310
311 shift_expr
312    : additive_expr
313    | shift_expr LEFT_OP additive_expr  { $$ = newNode(LEFT_OP,$1,$3); }
314    | shift_expr RIGHT_OP additive_expr { $$ = newNode(RIGHT_OP,$1,$3); }
315    ;
316
317 relational_expr
318    : shift_expr
319    | relational_expr '<' shift_expr    { 
320         $$ = (port->lt_nge ? 
321               newNode('!',newNode(GE_OP,$1,$3),NULL) :
322               newNode('<', $1,$3));
323    }
324    | relational_expr '>' shift_expr    { 
325            $$ = (port->gt_nle ? 
326                  newNode('!',newNode(LE_OP,$1,$3),NULL) :
327                  newNode('>',$1,$3));
328    }
329    | relational_expr LE_OP shift_expr  { 
330            $$ = (port->le_ngt ? 
331                  newNode('!', newNode('>', $1 , $3 ), NULL) :
332                  newNode(LE_OP,$1,$3));
333    }
334    | relational_expr GE_OP shift_expr  { 
335            $$ = (port->ge_nlt ? 
336                  newNode('!', newNode('<', $1 , $3 ), NULL) :
337                  newNode(GE_OP,$1,$3));
338    }
339    ;
340
341 equality_expr
342    : relational_expr
343    | equality_expr EQ_OP relational_expr  { 
344     $$ = (port->eq_nne ? 
345           newNode('!',newNode(NE_OP,$1,$3),NULL) : 
346           newNode(EQ_OP,$1,$3));
347    }
348    | equality_expr NE_OP relational_expr { 
349        $$ = (port->ne_neq ? 
350              newNode('!', newNode(EQ_OP,$1,$3), NULL) : 
351              newNode(NE_OP,$1,$3));
352    }       
353    ;
354
355 and_expr
356    : equality_expr
357    | and_expr '&' equality_expr  { $$ = newNode('&',$1,$3);}
358    ;
359
360 exclusive_or_expr
361    : and_expr
362    | exclusive_or_expr '^' and_expr { $$ = newNode('^',$1,$3);}
363    ;
364
365 inclusive_or_expr
366    : exclusive_or_expr
367    | inclusive_or_expr '|' exclusive_or_expr { $$ = newNode('|',$1,$3);}
368    ;
369
370 logical_and_expr
371    : inclusive_or_expr
372    | logical_and_expr AND_OP inclusive_or_expr 
373                                  { $$ = newNode(AND_OP,$1,$3);}
374    ;
375
376 logical_or_expr
377    : logical_and_expr
378    | logical_or_expr OR_OP logical_and_expr  
379                                  { $$ = newNode(OR_OP,$1,$3); }
380    ;
381
382 conditional_expr
383    : logical_or_expr
384    | logical_or_expr '?' logical_or_expr ':' conditional_expr  
385                      {
386                         $$ = newNode(':',$3,$5) ;
387                         $$ = newNode('?',$1,$$) ;
388                      }                        
389    ;
390
391 assignment_expr
392    : conditional_expr
393    | unary_expr assignment_operator assignment_expr   
394                      { 
395                                  
396                              switch ($2) {
397                              case '=':
398                                      $$ = newNode($2,$1,$3);
399                                      break;
400                              case MUL_ASSIGN:
401                                      $$ = newNode('=',$1,newNode('*',removeIncDecOps(copyAst($1)),$3));
402                                      break;
403                              case DIV_ASSIGN:
404                                      $$ = newNode('=',$1,newNode('/',removeIncDecOps(copyAst($1)),$3));
405                                      break;
406                              case MOD_ASSIGN:
407                                      $$ = newNode('=',$1,newNode('%',removeIncDecOps(copyAst($1)),$3));
408                                      break;
409                              case ADD_ASSIGN:
410                                      $$ = newNode('=',$1,newNode('+',removeIncDecOps(copyAst($1)),$3));
411                                      break;
412                              case SUB_ASSIGN:
413                                      $$ = newNode('=',$1,newNode('-',removeIncDecOps(copyAst($1)),$3));
414                                      break;
415                              case LEFT_ASSIGN:
416                                      $$ = newNode('=',$1,newNode(LEFT_OP,removeIncDecOps(copyAst($1)),$3));
417                                      break;
418                              case RIGHT_ASSIGN:
419                                      $$ = newNode('=',$1,newNode(RIGHT_OP,removeIncDecOps(copyAst($1)),$3));
420                                      break;
421                              case AND_ASSIGN:
422                                      $$ = newNode('=',$1,newNode('&',removeIncDecOps(copyAst($1)),$3));
423                                      break;
424                              case XOR_ASSIGN:
425                                      $$ = newNode('=',$1,newNode('^',removeIncDecOps(copyAst($1)),$3));
426                                      break;
427                              case OR_ASSIGN:
428                                      $$ = newNode('=',$1,newNode('|',removeIncDecOps(copyAst($1)),$3));
429                                      break;
430                              default :
431                                      $$ = NULL;
432                              }
433                                      
434                      }
435 ;
436
437 assignment_operator
438    : '='             { $$ = '=' ;}
439    | MUL_ASSIGN
440    | DIV_ASSIGN
441    | MOD_ASSIGN
442    | ADD_ASSIGN
443    | SUB_ASSIGN
444    | LEFT_ASSIGN
445    | RIGHT_ASSIGN
446    | AND_ASSIGN
447    | XOR_ASSIGN
448    | OR_ASSIGN
449    ;
450
451 expr
452    : assignment_expr
453    | expr ',' assignment_expr { $$ = newNode(',',$1,$3);}
454    ;
455
456 constant_expr
457    : conditional_expr 
458    ;
459
460 declaration
461    : declaration_specifiers ';'  { $$ = NULL ; }
462    | declaration_specifiers init_declarator_list ';'
463       {
464          /* add the specifier list to the id */
465          symbol *sym , *sym1;
466
467          for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
468              sym_link *lnk = copyLinkChain($1);
469              /* do the pointer stuff */
470              pointerTypes(sym->type,lnk);
471              addDecl (sym,0,lnk) ;
472          }
473         
474          $$ = sym1 ;
475       }
476    ;
477
478 declaration_specifiers
479    : storage_class_specifier                                            { $$ = $1; }
480    | storage_class_specifier declaration_specifiers { 
481      /* if the decl $2 is not a specifier */
482      /* find the spec and replace it      */
483      if ( !IS_SPEC($2)) {
484        sym_link *lnk = $2 ;
485        while (lnk && !IS_SPEC(lnk->next))
486          lnk = lnk->next;
487        lnk->next = mergeSpec($1,lnk->next, yytext);
488        $$ = $2 ;
489      }
490      else
491        $$ = mergeSpec($1,$2, yytext);
492    }
493    | type_specifier                                 { $$ = $1; }
494    | type_specifier declaration_specifiers          { 
495      /* if the decl $2 is not a specifier */
496      /* find the spec and replace it      */
497      if ( !IS_SPEC($2)) {
498        sym_link *lnk = $2 ;
499        while (lnk && !IS_SPEC(lnk->next))
500          lnk = lnk->next;
501        lnk->next = mergeSpec($1,lnk->next, yytext);
502        $$ = $2 ;
503      }
504      else
505        $$ = mergeSpec($1,$2, yytext);
506    }
507    ;
508
509 init_declarator_list
510    : init_declarator
511    | init_declarator_list ',' init_declarator      { $3->next = $1 ; $$ = $3;}
512    ;
513
514 init_declarator
515    : declarator                  { $1->ival = NULL ; }
516    | declarator '=' initializer  { $1->ival = $3   ; }
517    ;
518
519
520 storage_class_specifier
521    : TYPEDEF   {
522                   $$ = newLink (SPECIFIER) ;
523                   SPEC_TYPEDEF($$) = 1 ;
524                }
525    | EXTERN    {
526                   $$ = newLink(SPECIFIER);
527                   SPEC_EXTR($$) = 1 ;
528                }
529    | STATIC    {
530                   $$ = newLink (SPECIFIER);
531                   SPEC_STAT($$) = 1 ;
532                }
533    | AUTO      {
534                   $$ = newLink (SPECIFIER) ;
535                   SPEC_SCLS($$) = S_AUTO  ;
536                }
537    | REGISTER  {
538                   $$ = newLink (SPECIFIER);
539                   SPEC_SCLS($$) = S_REGISTER ;
540                }
541    ;
542
543 Interrupt_storage
544    : INTERRUPT CONSTANT  { $$ = (int) floatFromVal($2) ;  }
545    ;
546
547 type_specifier
548    : type_specifier2
549    | type_specifier2 AT constant_expr
550         {
551            /* add this to the storage class specifier  */
552            SPEC_ABSA($1) = 1;   /* set the absolute addr flag */
553            /* now get the abs addr from value */
554            SPEC_ADDR($1) = (int) floatFromVal(constExprValue($3,TRUE)) ;
555         }
556    ;
557
558 type_specifier2
559    : CHAR   {
560                $$=newLink(SPECIFIER);
561                SPEC_NOUN($$) = V_CHAR  ;
562             }
563    | SHORT  {
564                $$=newLink(SPECIFIER);
565                $$->select.s._short = 1 ;
566             }
567    | INT    {
568                $$=newLink(SPECIFIER);
569                SPEC_NOUN($$) = V_INT   ;
570             }
571    | LONG   {
572                $$=newLink(SPECIFIER);
573                SPEC_LONG($$) = 1       ;
574             }
575    | SIGNED {
576                $$=newLink(SPECIFIER);
577                $$->select.s._signed = 1;
578             }
579    | UNSIGNED  {
580                $$=newLink(SPECIFIER);
581                SPEC_USIGN($$) = 1      ;
582             }
583    | VOID   {
584                $$=newLink(SPECIFIER);
585                SPEC_NOUN($$) = V_VOID  ;
586             }
587    | CONST  {
588                $$=newLink(SPECIFIER);
589                SPEC_CONST($$) = 1;
590             }
591    | VOLATILE  {
592                $$=newLink(SPECIFIER);
593                SPEC_VOLATILE($$) = 1 ;
594             }
595    | FLOAT  {
596                $$=newLink(SPECIFIER);
597                SPEC_NOUN($$) = V_FLOAT;
598             }
599    | XDATA     {
600                   $$ = newLink (SPECIFIER);
601                   SPEC_SCLS($$) = S_XDATA  ;
602                }
603    | CODE      {
604                   $$ = newLink (SPECIFIER) ;
605                   SPEC_SCLS($$) = S_CODE ;                 
606                }
607    | EEPROM      {
608                   $$ = newLink (SPECIFIER) ;
609                   SPEC_SCLS($$) = S_EEPROM ;
610                }
611    | DATA      {
612                   $$ = newLink (SPECIFIER);
613                   SPEC_SCLS($$) = S_DATA   ;
614                }
615    | IDATA     {
616                   $$ = newLink (SPECIFIER);
617                   SPEC_SCLS($$) = S_IDATA  ;
618                }
619    | PDATA     { 
620                   $$ = newLink (SPECIFIER);
621                   SPEC_SCLS($$) = S_PDATA  ;
622                }
623    | BIT    {
624                $$=newLink(SPECIFIER);
625                SPEC_NOUN($$) = V_BIT   ;
626                SPEC_SCLS($$) = S_BIT   ;
627                SPEC_BLEN($$) = 1;
628                SPEC_BSTR($$) = 0;
629             }
630
631    | struct_or_union_specifier
632    | enum_specifier     {                           
633                            cenum = NULL ;
634                            $$ = $1 ;                              
635                         }
636    | TYPE_NAME    
637          {
638             symbol *sym;
639             sym_link   *p  ;
640             sym = findSym(TypedefTab,NULL,$1) ;
641             $$ = p = copyLinkChain(sym->type);
642             SPEC_TYPEDEF(getSpec(p)) = 0;
643          }
644    | sfr_reg_bit
645    ;
646
647 sfr_reg_bit
648    :  SBIT  {
649                $$ = newLink(SPECIFIER) ;
650                SPEC_NOUN($$) = V_SBIT;
651                SPEC_SCLS($$) = S_SBIT;
652             }
653    |  SFR   {
654                $$ = newLink(SPECIFIER) ;
655                SPEC_NOUN($$) = V_CHAR;
656                SPEC_SCLS($$) = S_SFR ;
657                SPEC_USIGN($$) = 1 ;
658             }
659    ;
660
661 struct_or_union_specifier
662    : struct_or_union opt_stag '{' struct_declaration_list '}'
663         {
664            structdef *sdef ;
665
666            /* Create a structdef   */
667            sdef = $2 ;
668            sdef->fields   = reverseSyms($4) ;   /* link the fields */
669            sdef->size  = compStructSize($1,sdef);   /* update size of  */
670
671            /* Create the specifier */
672            $$ = newLink (SPECIFIER) ;
673            SPEC_NOUN($$) = V_STRUCT;
674            SPEC_STRUCT($$)= sdef ;
675         }
676    | struct_or_union stag
677          {
678             $$ = newLink(SPECIFIER) ;
679             SPEC_NOUN($$) = V_STRUCT;
680             SPEC_STRUCT($$) = $2 ;
681          }
682    ;
683
684 struct_or_union
685    : STRUCT          { $$ = STRUCT ; }
686    | UNION           { $$ = UNION  ; }
687    ;
688
689 opt_stag
690 : stag
691 |  {  /* synthesize a name add to structtable */
692      $$ = newStruct(genSymName(NestLevel)) ;
693      $$->level = NestLevel ;
694      addSym (StructTab, $$, $$->tag,$$->level,currBlockno, 0);
695 };
696
697 stag
698 :  identifier  {  /* add name to structure table */
699      $$ = findSymWithBlock (StructTab,$1,currBlockno);
700      if (! $$ ) {
701        $$ = newStruct($1->name) ;
702        $$->level = NestLevel ;
703        addSym (StructTab, $$, $$->tag,$$->level,currBlockno,0);
704      }
705 };
706
707
708 struct_declaration_list
709    : struct_declaration
710    | struct_declaration_list struct_declaration
711        {
712            symbol *sym = $2;
713            /* go to the end of the chain */
714            while (sym->next) sym = sym->next;
715
716            sym->next = $1 ;
717            $$ = $2;
718        }
719    ;
720
721 struct_declaration
722    : type_specifier_list struct_declarator_list ';'
723        {
724            /* add this type to all the symbols */
725            symbol *sym ;
726            for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
727                
728                /* make the symbol one level up */
729                sym->level-- ;
730
731                pointerTypes(sym->type,copyLinkChain($1));
732                if (!sym->type) {
733                    sym->type = copyLinkChain($1);
734                    sym->etype = getSpec(sym->type);
735                }
736                else
737                  addDecl (sym,0,copyLinkChain($1));
738                /* make sure the type is complete and sane */
739                checkTypeSanity(sym->etype, sym->name);
740            }
741            $$ = $2;
742        }
743    ;
744
745 struct_declarator_list
746    : struct_declarator
747    | struct_declarator_list ',' struct_declarator
748        {
749            $3->next  = $1 ;
750            $$ = $3 ;
751        }
752    ;
753
754 struct_declarator
755    : declarator 
756    | ':' constant_expr  {  
757                            $$ = newSymbol (genSymName(NestLevel),NestLevel) ; 
758                            $$->bitVar = (int) floatFromVal(constExprValue($2,TRUE));
759                         }                        
760    | declarator ':' constant_expr 
761                         { 
762                           $1->bitVar = (int) floatFromVal(constExprValue($3,TRUE));                     
763                         }
764    ;
765
766 enum_specifier
767    : ENUM            '{' enumerator_list '}' {
768                                                 //addSymChain ($3);
769                                                 //allocVariables(reverseSyms($3)) ;
770                                                 $$ = copyLinkChain(cenum->type);
771                                              }
772    | ENUM identifier '{' enumerator_list '}' {
773                                                 symbol *csym ;
774
775                                                 $2->type = copyLinkChain(cenum->type);
776                                                 $2->etype = getSpec($2->type);
777                                                 /* add this to the enumerator table */
778                                                 if (!(csym=findSym(enumTab,$2,$2->name)) && 
779                                                     (csym && csym->level == $2->level))
780                                                    werror(E_DUPLICATE_TYPEDEF,csym->name);
781
782                                                 addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
783                                                 //addSymChain ($4);
784                                                 //allocVariables (reverseSyms($4));
785                                                 $$ = copyLinkChain(cenum->type);
786                                                 SPEC_SCLS(getSpec($$)) = 0 ;
787                                              }
788    | ENUM identifier                         {
789                                                 symbol *csym ;
790
791                                                 /* check the enumerator table */
792                                                 if ((csym = findSym(enumTab,$2,$2->name)))
793                                                    $$ = copyLinkChain(csym->type);
794                                                 else  {
795                                                    $$ = newLink(SPECIFIER) ;
796                                                    SPEC_NOUN($$) = V_INT   ;
797                                                 }
798
799                                                 SPEC_SCLS(getSpec($$)) = 0 ;
800                                              }
801    ;
802
803 enumerator_list
804    : enumerator
805    | enumerator_list ',' {
806                          }
807    | enumerator_list ',' enumerator {
808                                        $3->next = $1 ;
809                                        $$ = $3  ;
810                                     }
811    ;
812
813 enumerator
814    : identifier opt_assign_expr  
815      {
816        /* make the symbol one level up */
817        $1->level-- ;
818        $1->type = copyLinkChain($2->type); 
819        $1->etype= getSpec($1->type);
820        SPEC_ENUM($1->etype) = 1;
821        $$ = $1 ;
822        // do this now, so we can use it for the next enums in the list
823        addSymChain($1);
824      }
825    ;
826
827 opt_assign_expr
828    :  '='   constant_expr  {
829                               value *val ;
830                                                         
831                               val = constExprValue($2,TRUE);                         
832                               $$ = cenum = val ;
833                            }                           
834    |                       {                              
835                               if (cenum)  {
836                                  SNPRINTF(lbuff, sizeof(lbuff), 
837                                           "%d",(int) floatFromVal(cenum)+1);
838                                  $$ = cenum = constVal(lbuff);
839                               }
840                               else {
841                                  SNPRINTF(lbuff, sizeof(lbuff), 
842                                           "%d",0);
843                                  $$ = cenum = constVal(lbuff);
844                               }   
845                            }
846    ;
847
848 declarator
849    : declarator2_function_attributes    { $$ = $1; }
850    | pointer declarator2_function_attributes
851          {
852              addDecl ($2,0,reverseLink($1));
853              $$ = $2 ;
854          }
855    ;
856
857 declarator2_function_attributes
858    : declarator2                  { $$ = $1 ; } 
859    | declarator2 function_attribute  { 
860        // copy the functionAttributes (not the args and hasVargs !!)
861        sym_link *funcType=$1->etype;
862        struct value *args=FUNC_ARGS(funcType);
863        unsigned hasVargs=FUNC_HASVARARGS(funcType);
864
865        memcpy (&funcType->funcAttrs, &$2->funcAttrs, 
866                sizeof($2->funcAttrs));
867
868        FUNC_ARGS(funcType)=args;
869        FUNC_HASVARARGS(funcType)=hasVargs;
870
871        // just to be sure
872        memset (&$2->funcAttrs, 0,
873                sizeof($2->funcAttrs));
874        
875        addDecl ($1,0,$2); 
876    }     
877    ;
878
879 declarator2
880    : identifier
881    | '(' declarator ')'     { $$ = $2; }
882    | declarator2 '[' ']'
883          {
884             sym_link   *p;
885
886             p = newLink (DECLARATOR);
887             DCL_TYPE(p) = ARRAY ;
888             DCL_ELEM(p) = 0     ;
889             addDecl($1,0,p);
890          }
891    | declarator2 '[' constant_expr ']'
892          {
893             sym_link   *p ;
894                         value *tval;
895                         
896             p = (tval = constExprValue($3,TRUE))->etype;
897             /* if it is not a constant then Error  */
898             if ( SPEC_SCLS(p) != S_LITERAL)
899                werror(E_CONST_EXPECTED) ;
900             else {
901                p = newLink (DECLARATOR);
902                DCL_TYPE(p) = ARRAY ;
903                DCL_ELEM(p) = (int) floatFromVal(tval) ;
904                addDecl($1,0,p);
905             }                           
906          }
907    | declarator2 '('  ')'       {  addDecl ($1,FUNCTION,NULL) ;   }
908    | declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')'
909          {
910            
911              addDecl ($1,FUNCTION,NULL) ;
912            
913              FUNC_HASVARARGS($1->type) = IS_VARG($4);
914              FUNC_ARGS($1->type) = reverseVal($4);
915              
916              /* nest level was incremented to take care of the parms  */
917              NestLevel-- ;
918              currBlockno--;
919
920              // if this was a pointer (to a function)
921              if (IS_PTR($1->type)) {
922                // move the args and hasVargs to the function
923                FUNC_ARGS($1->etype)=FUNC_ARGS($1->type);
924                FUNC_HASVARARGS($1->etype)=FUNC_HASVARARGS($1->type);
925                memset (&$1->type->funcAttrs, 0,
926                        sizeof($1->type->funcAttrs));
927                // remove the symbol args (if any)
928                cleanUpLevel(SymbolTab,NestLevel+1);
929              }
930              
931              $$ = $1;
932          }
933    | declarator2 '(' parameter_identifier_list ')'
934          {         
935            werror(E_OLD_STYLE,$1->name) ;         
936            
937            /* assume it returns an int */
938            $1->type = $1->etype = newIntLink();
939            $$ = $1 ;
940          }
941    ;
942
943 pointer
944    : unqualified_pointer { $$ = $1 ;}
945    | unqualified_pointer type_specifier_list   
946          {
947              $$ = $1  ;         
948              DCL_TSPEC($1) = $2;
949          }
950    | unqualified_pointer pointer         
951          {
952              $$ = $1 ;          
953              $$->next = $2 ;
954              DCL_TYPE($2)=port->unqualified_pointer;
955          }
956    | unqualified_pointer type_specifier_list pointer
957          {
958              $$ = $1 ;               
959              if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
960                  DCL_PTR_CONST($1) = SPEC_CONST($2);
961                  DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
962                  switch (SPEC_SCLS($2)) {
963                  case S_XDATA:
964                      DCL_TYPE($3) = FPOINTER;
965                      break;
966                  case S_IDATA:
967                      DCL_TYPE($3) = IPOINTER ;
968                      break;
969                  case S_PDATA:
970                      DCL_TYPE($3) = PPOINTER ;
971                      break;
972                  case S_DATA:
973                      DCL_TYPE($3) = POINTER ;
974                      break;
975                  case S_CODE:
976                      DCL_TYPE($3) = CPOINTER ;
977                      break;
978                  case S_EEPROM:
979                      DCL_TYPE($3) = EEPPOINTER;
980                      break;
981                  default:
982                    // this could be just "constant" 
983                    // werror(W_PTR_TYPE_INVALID);
984                      ;
985                  }
986              }
987              else 
988                  werror (W_PTR_TYPE_INVALID);
989              $$->next = $3 ;
990          }
991    ;
992
993 unqualified_pointer
994    :  '*'   
995       {
996         $$ = newLink(DECLARATOR);
997         DCL_TYPE($$)=UPOINTER;
998       }
999    ;
1000
1001 type_specifier_list
1002    : type_specifier
1003    //| type_specifier_list type_specifier         {  $$ = mergeSpec ($1,$2, "type_specifier_list"); }
1004    | type_specifier_list type_specifier {
1005      /* if the decl $2 is not a specifier */
1006      /* find the spec and replace it      */
1007      if ( !IS_SPEC($2)) {
1008        sym_link *lnk = $2 ;
1009        while (lnk && !IS_SPEC(lnk->next))
1010          lnk = lnk->next;
1011        lnk->next = mergeSpec($1,lnk->next, "type_specifier_list");
1012        $$ = $2 ;
1013      }
1014      else
1015        $$ = mergeSpec($1,$2, "type_specifier_list");
1016    }
1017    ;
1018
1019 parameter_identifier_list
1020    : identifier_list
1021    | identifier_list ',' ELIPSIS
1022    ;
1023
1024 identifier_list
1025    : identifier
1026    | identifier_list ',' identifier         
1027          {            
1028            $3->next = $1;
1029            $$ = $3 ;
1030          }
1031    ;
1032
1033 parameter_type_list
1034         : parameter_list
1035         | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1036         ;
1037
1038 parameter_list
1039    : parameter_declaration 
1040    | parameter_list ',' parameter_declaration
1041          {
1042             $3->next = $1 ;
1043             $$ = $3 ;       
1044          }
1045    ;
1046
1047 parameter_declaration
1048    : type_specifier_list declarator 
1049                {        
1050                   symbol *loop ;
1051                   pointerTypes($2->type,$1);
1052                   addDecl ($2,0,$1);              
1053                   for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1054                   addSymChain ($2);
1055                   $$ = symbolVal($2);
1056                }
1057    | type_name { 
1058                   $$ = newValue() ; 
1059                   $$->type = $1;
1060                   $$->etype = getSpec($$->type);
1061                }
1062    ;
1063
1064 type_name
1065    : type_specifier_list  { $$ = $1 ;}
1066    | type_specifier_list abstract_declarator 
1067                {
1068                  /* go to the end of the list */
1069                  sym_link *p;
1070                  pointerTypes($2,$1);
1071                  for ( p = $2 ; p && p->next ; p=p->next);
1072                  if (!p) {
1073                    werror(E_SYNTAX_ERROR, yytext);
1074                  } else {
1075                    p->next = $1 ;
1076                  }
1077                  $$ = $2 ;
1078                }   
1079    ;
1080
1081 abstract_declarator
1082    : pointer { $$ = reverseLink($1); }
1083    | abstract_declarator2
1084    | pointer abstract_declarator2   { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;} 
1085    ;
1086
1087 abstract_declarator2
1088    : '(' abstract_declarator ')'    { $$ = $2 ; }
1089    | '[' ']'                        {             
1090                                        $$ = newLink (DECLARATOR);
1091                                        DCL_TYPE($$) = ARRAY ;
1092                                        DCL_ELEM($$) = 0     ;
1093                                     }
1094    | '[' constant_expr ']'          { 
1095                                        value *val ;
1096                                        $$ = newLink (DECLARATOR);
1097                                        DCL_TYPE($$) = ARRAY ;
1098                                        DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1099                                     }
1100    | abstract_declarator2 '[' ']'   {
1101                                        $$ = newLink (DECLARATOR);
1102                                        DCL_TYPE($$) = ARRAY ;
1103                                        DCL_ELEM($$) = 0     ;
1104                                        $$->next = $1 ;
1105                                     }
1106    | abstract_declarator2 '[' constant_expr ']'
1107                                     {
1108                                        value *val ;
1109                                        $$ = newLink (DECLARATOR);
1110                                        DCL_TYPE($$) = ARRAY ;
1111                                        DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1112                                        $$->next = $1 ;
1113                                     }
1114    | '(' ')'                        { $$ = NULL;}
1115    | '(' parameter_type_list ')'    { $$ = NULL;}   
1116    | abstract_declarator2 '(' ')' {
1117      // $1 must be a pointer to a function
1118      sym_link *p=newLink(DECLARATOR);
1119      DCL_TYPE(p) = FUNCTION;
1120      if (!$1) {
1121        // ((void (code *) ()) 0) ()
1122        $1=newLink(DECLARATOR);
1123        DCL_TYPE($1)=CPOINTER;
1124        $$ = $1;
1125      }
1126      $1->next=p;
1127    }
1128    | abstract_declarator2 '(' parameter_type_list ')' {
1129      if (!IS_VOID($3->etype)) {
1130        // this is nonsense, so let's just burp something
1131        werror(E_TOO_FEW_PARMS);
1132      } else {
1133        // $1 must be a pointer to a function
1134        sym_link *p=newLink(DECLARATOR);
1135        DCL_TYPE(p) = FUNCTION;
1136        if (!$1) {
1137          // ((void (code *) (void)) 0) ()
1138          $1=newLink(DECLARATOR);
1139          DCL_TYPE($1)=CPOINTER;
1140          $$ = $1;
1141        }
1142        $1->next=p;
1143      }
1144    }
1145    ;
1146
1147 initializer
1148    : assignment_expr                { $$ = newiList(INIT_NODE,$1); }
1149    | '{'  initializer_list '}'      { $$ = newiList(INIT_DEEP,revinit($2)); }
1150    | '{'  initializer_list ',' '}'  { $$ = newiList(INIT_DEEP,revinit($2)); }
1151    ;
1152
1153 initializer_list
1154    : initializer
1155    | initializer_list ',' initializer  {  $3->next = $1; $$ = $3; }
1156    ;
1157
1158 statement
1159    : labeled_statement
1160    | compound_statement
1161    | expression_statement
1162    | selection_statement
1163    | iteration_statement
1164    | jump_statement
1165    | INLINEASM  ';'      {
1166                             ast *ex = newNode(INLINEASM,NULL,NULL);
1167                             ex->values.inlineasm = strdup($1);
1168                             $$ = ex;
1169                          } 
1170    ;
1171
1172 labeled_statement
1173 //   : identifier ':' statement          {  $$ = createLabel($1,$3);  }   
1174    : identifier ':'                    {  $$ = createLabel($1,NULL);  }   
1175    | CASE constant_expr ':' statement  {  $$ = createCase(STACK_PEEK(swStk),$2,$4); }
1176    | DEFAULT ':' statement             {  $$ = createDefault(STACK_PEEK(swStk),$3); }
1177    ;
1178
1179 start_block : '{' { STACK_PUSH(blockNum,currBlockno); currBlockno = ++blockNo ;  }
1180             ;
1181
1182 end_block   : '}'     { currBlockno = STACK_POP(blockNum); }           
1183             ;
1184
1185 compound_statement
1186    : start_block end_block                    { $$ = createBlock(NULL,NULL); }
1187    | start_block statement_list end_block     { $$ = createBlock(NULL,$2) ;  }
1188    | start_block 
1189           declaration_list                    { addSymChain($2); }
1190      end_block                                { $$ = createBlock($2,NULL) ;  }
1191    | start_block 
1192           declaration_list                    {  addSymChain ($2); }
1193           statement_list   
1194      end_block                                {$$ = createBlock($2,$4)   ;  }
1195    | error ';'                                { $$ = NULL ; }
1196    ;
1197
1198 declaration_list
1199    : declaration        
1200      {
1201        /* if this is typedef declare it immediately */
1202        if ( $1 && IS_TYPEDEF($1->etype)) {
1203          allocVariables ($1);
1204          $$ = NULL ;
1205        }
1206        else
1207          $$ = $1 ;
1208      }
1209
1210    | declaration_list declaration
1211      {
1212        symbol   *sym;
1213        
1214        /* if this is a typedef */
1215        if ($2 && IS_TYPEDEF($2->etype)) {
1216          allocVariables ($2);
1217          $$ = $1 ;
1218        }
1219        else {
1220                                 /* get to the end of the previous decl */
1221          if ( $1 ) {
1222            $$ = sym = $1 ;
1223            while (sym->next)
1224              sym = sym->next ;
1225            sym->next = $2;
1226          } 
1227          else
1228            $$ = $2 ;
1229        }
1230      }
1231    ;
1232
1233 statement_list
1234    : statement
1235    | statement_list statement          {  $$ = newNode(NULLOP,$1,$2) ;}
1236    ;
1237
1238 expression_statement
1239    : ';'                { $$ = NULL;}
1240    | expr ';' 
1241    ;
1242
1243 else_statement
1244    :  ELSE  statement   { $$ = $2  ; }
1245    |                    { $$ = NULL;}
1246    ;
1247
1248   
1249 selection_statement
1250    : IF '(' expr ')'  statement else_statement { noLineno++ ; $$ = createIf ($3, $5, $6 ); noLineno--;}
1251    | SWITCH '(' expr ')'   { 
1252                               ast *ex ;                              
1253                               static   int swLabel = 0 ;
1254
1255                               /* create a node for expression  */
1256                               ex = newNode(SWITCH,$3,NULL);
1257                               STACK_PUSH(swStk,ex);   /* save it in the stack */
1258                               ex->values.switchVals.swNum = swLabel ;
1259                                  
1260                               /* now create the label */
1261                               SNPRINTF(lbuff, sizeof(lbuff), 
1262                                        "_swBrk_%d",swLabel++);
1263                               $<sym>$  =  newSymbol(lbuff,NestLevel);
1264                               /* put label in the break stack  */
1265                               STACK_PUSH(breakStack,$<sym>$);   
1266                            }
1267      statement             {  
1268                               /* get back the switch form the stack  */
1269                               $$ = STACK_POP(swStk)  ;
1270                               $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1271                               STACK_POP(breakStack);   
1272                            }
1273         ;
1274
1275 while : WHILE  {  /* create and push the continue , break & body labels */
1276                   static int Lblnum = 0 ;
1277                   /* continue */
1278                   SNPRINTF (lbuff, sizeof(lbuff), "_whilecontinue_%d",Lblnum);
1279                   STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1280                   /* break */
1281                   SNPRINTF (lbuff, sizeof(lbuff), "_whilebreak_%d",Lblnum);
1282                   STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1283                   /* body */
1284                   SNPRINTF (lbuff, sizeof(lbuff), "_whilebody_%d",Lblnum++);
1285                   $$ = newSymbol(lbuff,NestLevel);
1286                }
1287    ;
1288
1289 do : DO {  /* create and push the continue , break & body Labels */
1290            static int Lblnum = 0 ;
1291
1292            /* continue */
1293            SNPRINTF(lbuff, sizeof(lbuff), "_docontinue_%d",Lblnum);
1294            STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1295            /* break */
1296            SNPRINTF(lbuff, sizeof(lbuff), "_dobreak_%d",Lblnum);
1297            STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1298            /* do body */
1299            SNPRINTF(lbuff, sizeof(lbuff), "_dobody_%d",Lblnum++);
1300            $$ = newSymbol (lbuff,NestLevel);       
1301         }
1302    ;
1303
1304 for : FOR { /* create & push continue, break & body labels */
1305             static int Lblnum = 0 ;
1306          
1307             /* continue */
1308             SNPRINTF(lbuff, sizeof(lbuff), "_forcontinue_%d",Lblnum);
1309             STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1310             /* break    */
1311             SNPRINTF(lbuff, sizeof(lbuff), "_forbreak_%d",Lblnum);
1312             STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1313             /* body */
1314             SNPRINTF(lbuff, sizeof(lbuff), "_forbody_%d",Lblnum);
1315             $$ = newSymbol(lbuff,NestLevel);
1316             /* condition */
1317             SNPRINTF(lbuff, sizeof(lbuff), "_forcond_%d",Lblnum++);
1318             STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1319           }
1320    ;
1321
1322 iteration_statement  
1323    : while '(' expr ')'  statement 
1324                          { 
1325                            noLineno++ ;
1326                            $$ = createWhile ( $1, STACK_POP(continueStack),
1327                                               STACK_POP(breakStack), $3, $5 ); 
1328                            $$->lineno = $1->lineDef ;
1329                            noLineno-- ;
1330                          }
1331    | do statement   WHILE '(' expr ')' ';' 
1332                         { 
1333                           noLineno++ ; 
1334                           $$ = createDo ( $1 , STACK_POP(continueStack), 
1335                                           STACK_POP(breakStack), $5, $2);
1336                           $$->lineno = $1->lineDef ;
1337                           noLineno-- ;
1338                         }                                                 
1339    | for '(' expr_opt   ';' expr_opt ';' expr_opt ')'  statement   
1340                         {
1341                           noLineno++ ;  
1342                           
1343                           /* if break or continue statement present
1344                              then create a general case loop */
1345                           if (STACK_PEEK(continueStack)->isref ||
1346                               STACK_PEEK(breakStack)->isref) {
1347                               $$ = createFor ($1, STACK_POP(continueStack),
1348                                               STACK_POP(breakStack) ,
1349                                               STACK_POP(forStack)   ,
1350                                               $3 , $5 , $7, $9 );
1351                           } else {
1352                               $$ = newNode(FOR,$9,NULL);
1353                               AST_FOR($$,trueLabel) = $1;
1354                               AST_FOR($$,continueLabel) =  STACK_POP(continueStack);
1355                               AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1356                               AST_FOR($$,condLabel)  = STACK_POP(forStack)  ;
1357                               AST_FOR($$,initExpr)   = $3;
1358                               AST_FOR($$,condExpr)   = $5;
1359                               AST_FOR($$,loopExpr)   = $7;
1360                           }
1361                           
1362                           noLineno-- ;
1363                         }
1364 ;
1365
1366 expr_opt
1367         :                       { $$ = NULL ; }
1368         |       expr
1369         ;
1370
1371 jump_statement          
1372    : GOTO identifier ';'   { 
1373                               $2->islbl = 1;
1374                               $$ = newAst_VALUE(symbolVal($2)); 
1375                               $$ = newNode(GOTO,$$,NULL);
1376                            }
1377    | CONTINUE ';'          {  
1378        /* make sure continue is in context */
1379        if (STACK_PEEK(continueStack) == NULL) {
1380            werror(E_BREAK_CONTEXT);
1381            $$ = NULL;
1382        }
1383        else {
1384            $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));      
1385            $$ = newNode(GOTO,$$,NULL);
1386            /* mark the continue label as referenced */
1387            STACK_PEEK(continueStack)->isref = 1;
1388        }
1389    }
1390    | BREAK ';'             { 
1391        if (STACK_PEEK(breakStack) == NULL) {
1392            werror(E_BREAK_CONTEXT);
1393            $$ = NULL;
1394        } else {
1395            $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
1396            $$ = newNode(GOTO,$$,NULL);
1397            STACK_PEEK(breakStack)->isref = 1;
1398        }
1399    }
1400    | RETURN ';'            { $$ = newNode(RETURN,NULL,NULL)    ; }
1401    | RETURN expr ';'       { $$ = newNode(RETURN,NULL,$2) ; } 
1402    ;
1403
1404 identifier
1405    : IDENTIFIER   { $$ = newSymbol ($1,NestLevel) ; }
1406    ;
1407 %%
1408