some more on the const, volatile and now also static issue
[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, "storage_class_specifier declaration_specifiers - skipped");
488        $$ = $2 ;
489      }
490      else
491        $$ = mergeSpec($1,$2, "storage_class_specifier declaration_specifiers");
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, "type_specifier declaration_specifiers - skipped");
502        $$ = $2 ;
503      }
504      else
505        $$ = mergeSpec($1,$2, "type_specifier declaration_specifiers");
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                   if (port->mem.code_ro) {
607                     SPEC_CONST($$) = 1;
608                   }
609                }
610    | EEPROM      {
611                   $$ = newLink (SPECIFIER) ;
612                   SPEC_SCLS($$) = S_EEPROM ;
613                }
614    | DATA      {
615                   $$ = newLink (SPECIFIER);
616                   SPEC_SCLS($$) = S_DATA   ;
617                }
618    | IDATA     {
619                   $$ = newLink (SPECIFIER);
620                   SPEC_SCLS($$) = S_IDATA  ;
621                }
622    | PDATA     { 
623                   $$ = newLink (SPECIFIER);
624                   SPEC_SCLS($$) = S_PDATA  ;
625                }
626    | BIT    {
627                $$=newLink(SPECIFIER);
628                SPEC_NOUN($$) = V_BIT   ;
629                SPEC_SCLS($$) = S_BIT   ;
630                SPEC_BLEN($$) = 1;
631                SPEC_BSTR($$) = 0;
632             }
633
634    | struct_or_union_specifier
635    | enum_specifier     {                           
636                            cenum = NULL ;
637                            $$ = $1 ;                              
638                         }
639    | TYPE_NAME    
640          {
641             symbol *sym;
642             sym_link   *p  ;
643             sym = findSym(TypedefTab,NULL,$1) ;
644             $$ = p = copyLinkChain(sym->type);
645             SPEC_TYPEDEF(getSpec(p)) = 0;
646          }
647    | sfr_reg_bit
648    ;
649
650 sfr_reg_bit
651    :  SBIT  {
652                $$ = newLink(SPECIFIER) ;
653                SPEC_NOUN($$) = V_SBIT;
654                SPEC_SCLS($$) = S_SBIT;
655             }
656    |  SFR   {
657                $$ = newLink(SPECIFIER) ;
658                SPEC_NOUN($$) = V_CHAR;
659                SPEC_SCLS($$) = S_SFR ;
660                SPEC_USIGN($$) = 1 ;
661             }
662    ;
663
664 struct_or_union_specifier
665    : struct_or_union opt_stag '{' struct_declaration_list '}'
666         {
667            structdef *sdef ;
668
669            /* Create a structdef   */
670            sdef = $2 ;
671            sdef->fields   = reverseSyms($4) ;   /* link the fields */
672            sdef->size  = compStructSize($1,sdef);   /* update size of  */
673
674            /* Create the specifier */
675            $$ = newLink (SPECIFIER) ;
676            SPEC_NOUN($$) = V_STRUCT;
677            SPEC_STRUCT($$)= sdef ;
678         }
679    | struct_or_union stag
680          {
681             $$ = newLink(SPECIFIER) ;
682             SPEC_NOUN($$) = V_STRUCT;
683             SPEC_STRUCT($$) = $2 ;
684          }
685    ;
686
687 struct_or_union
688    : STRUCT          { $$ = STRUCT ; }
689    | UNION           { $$ = UNION  ; }
690    ;
691
692 opt_stag
693 : stag
694 |  {  /* synthesize a name add to structtable */
695      $$ = newStruct(genSymName(NestLevel)) ;
696      $$->level = NestLevel ;
697      addSym (StructTab, $$, $$->tag,$$->level,currBlockno, 0);
698 };
699
700 stag
701 :  identifier  {  /* add name to structure table */
702      $$ = findSymWithBlock (StructTab,$1,currBlockno);
703      if (! $$ ) {
704        $$ = newStruct($1->name) ;
705        $$->level = NestLevel ;
706        addSym (StructTab, $$, $$->tag,$$->level,currBlockno,0);
707      }
708 };
709
710
711 struct_declaration_list
712    : struct_declaration
713    | struct_declaration_list struct_declaration
714        {
715            symbol *sym = $2;
716            /* go to the end of the chain */
717            while (sym->next) sym = sym->next;
718
719            sym->next = $1 ;
720            $$ = $2;
721        }
722    ;
723
724 struct_declaration
725    : type_specifier_list struct_declarator_list ';'
726        {
727            /* add this type to all the symbols */
728            symbol *sym ;
729            for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
730                
731                /* make the symbol one level up */
732                sym->level-- ;
733
734                pointerTypes(sym->type,copyLinkChain($1));
735                if (!sym->type) {
736                    sym->type = copyLinkChain($1);
737                    sym->etype = getSpec(sym->type);
738                }
739                else
740                  addDecl (sym,0,copyLinkChain($1));
741                /* make sure the type is complete and sane */
742                checkTypeSanity(sym->etype, sym->name);
743            }
744            $$ = $2;
745        }
746    ;
747
748 struct_declarator_list
749    : struct_declarator
750    | struct_declarator_list ',' struct_declarator
751        {
752            $3->next  = $1 ;
753            $$ = $3 ;
754        }
755    ;
756
757 struct_declarator
758    : declarator 
759    | ':' constant_expr  {  
760                            $$ = newSymbol (genSymName(NestLevel),NestLevel) ; 
761                            $$->bitVar = (int) floatFromVal(constExprValue($2,TRUE));
762                         }                        
763    | declarator ':' constant_expr 
764                         { 
765                           $1->bitVar = (int) floatFromVal(constExprValue($3,TRUE));                     
766                         }
767    ;
768
769 enum_specifier
770    : ENUM            '{' enumerator_list '}' {
771                                                 //addSymChain ($3);
772                                                 //allocVariables(reverseSyms($3)) ;
773                                                 $$ = copyLinkChain(cenum->type);
774                                              }
775    | ENUM identifier '{' enumerator_list '}' {
776                                                 symbol *csym ;
777
778                                                 $2->type = copyLinkChain(cenum->type);
779                                                 $2->etype = getSpec($2->type);
780                                                 /* add this to the enumerator table */
781                                                 if (!(csym=findSym(enumTab,$2,$2->name)) && 
782                                                     (csym && csym->level == $2->level))
783                                                    werror(E_DUPLICATE_TYPEDEF,csym->name);
784
785                                                 addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
786                                                 //addSymChain ($4);
787                                                 //allocVariables (reverseSyms($4));
788                                                 $$ = copyLinkChain(cenum->type);
789                                                 SPEC_SCLS(getSpec($$)) = 0 ;
790                                              }
791    | ENUM identifier                         {
792                                                 symbol *csym ;
793
794                                                 /* check the enumerator table */
795                                                 if ((csym = findSym(enumTab,$2,$2->name)))
796                                                    $$ = copyLinkChain(csym->type);
797                                                 else  {
798                                                    $$ = newLink(SPECIFIER) ;
799                                                    SPEC_NOUN($$) = V_INT   ;
800                                                 }
801
802                                                 SPEC_SCLS(getSpec($$)) = 0 ;
803                                              }
804    ;
805
806 enumerator_list
807    : enumerator
808    | enumerator_list ',' {
809                          }
810    | enumerator_list ',' enumerator {
811                                        $3->next = $1 ;
812                                        $$ = $3  ;
813                                     }
814    ;
815
816 enumerator
817    : identifier opt_assign_expr  
818      {
819        /* make the symbol one level up */
820        $1->level-- ;
821        $1->type = copyLinkChain($2->type); 
822        $1->etype= getSpec($1->type);
823        SPEC_ENUM($1->etype) = 1;
824        $$ = $1 ;
825        // do this now, so we can use it for the next enums in the list
826        addSymChain($1);
827      }
828    ;
829
830 opt_assign_expr
831    :  '='   constant_expr  {
832                               value *val ;
833                                                         
834                               val = constExprValue($2,TRUE);                         
835                               $$ = cenum = val ;
836                            }                           
837    |                       {                              
838                               if (cenum)  {
839                                  SNPRINTF(lbuff, sizeof(lbuff), 
840                                           "%d",(int) floatFromVal(cenum)+1);
841                                  $$ = cenum = constVal(lbuff);
842                               }
843                               else {
844                                  SNPRINTF(lbuff, sizeof(lbuff), 
845                                           "%d",0);
846                                  $$ = cenum = constVal(lbuff);
847                               }   
848                            }
849    ;
850
851 declarator
852    : declarator2_function_attributes    { $$ = $1; }
853    | pointer declarator2_function_attributes
854          {
855              addDecl ($2,0,reverseLink($1));
856              $$ = $2 ;
857          }
858    ;
859
860 declarator2_function_attributes
861    : declarator2                  { $$ = $1 ; } 
862    | declarator2 function_attribute  { 
863        // copy the functionAttributes (not the args and hasVargs !!)
864        sym_link *funcType=$1->etype;
865        struct value *args=FUNC_ARGS(funcType);
866        unsigned hasVargs=FUNC_HASVARARGS(funcType);
867
868        memcpy (&funcType->funcAttrs, &$2->funcAttrs, 
869                sizeof($2->funcAttrs));
870
871        FUNC_ARGS(funcType)=args;
872        FUNC_HASVARARGS(funcType)=hasVargs;
873
874        // just to be sure
875        memset (&$2->funcAttrs, 0,
876                sizeof($2->funcAttrs));
877        
878        addDecl ($1,0,$2); 
879    }     
880    ;
881
882 declarator2
883    : identifier
884    | '(' declarator ')'     { $$ = $2; }
885    | declarator2 '[' ']'
886          {
887             sym_link   *p;
888
889             p = newLink (DECLARATOR);
890             DCL_TYPE(p) = ARRAY ;
891             DCL_ELEM(p) = 0     ;
892             addDecl($1,0,p);
893          }
894    | declarator2 '[' constant_expr ']'
895          {
896             sym_link   *p ;
897                         value *tval;
898                         
899             p = (tval = constExprValue($3,TRUE))->etype;
900             /* if it is not a constant then Error  */
901             if ( SPEC_SCLS(p) != S_LITERAL)
902                werror(E_CONST_EXPECTED) ;
903             else {
904                p = newLink (DECLARATOR);
905                DCL_TYPE(p) = ARRAY ;
906                DCL_ELEM(p) = (int) floatFromVal(tval) ;
907                addDecl($1,0,p);
908             }                           
909          }
910    | declarator2 '('  ')'       {  addDecl ($1,FUNCTION,NULL) ;   }
911    | declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')'
912          {
913            
914              addDecl ($1,FUNCTION,NULL) ;
915            
916              FUNC_HASVARARGS($1->type) = IS_VARG($4);
917              FUNC_ARGS($1->type) = reverseVal($4);
918              
919              /* nest level was incremented to take care of the parms  */
920              NestLevel-- ;
921              currBlockno--;
922
923              // if this was a pointer (to a function)
924              if (IS_PTR($1->type)) {
925                // move the args and hasVargs to the function
926                FUNC_ARGS($1->etype)=FUNC_ARGS($1->type);
927                FUNC_HASVARARGS($1->etype)=FUNC_HASVARARGS($1->type);
928                memset (&$1->type->funcAttrs, 0,
929                        sizeof($1->type->funcAttrs));
930                // remove the symbol args (if any)
931                cleanUpLevel(SymbolTab,NestLevel+1);
932              }
933              
934              $$ = $1;
935          }
936    | declarator2 '(' parameter_identifier_list ')'
937          {         
938            werror(E_OLD_STYLE,$1->name) ;         
939            
940            /* assume it returns an int */
941            $1->type = $1->etype = newIntLink();
942            $$ = $1 ;
943          }
944    ;
945
946 pointer
947    : unqualified_pointer { $$ = $1 ;}
948    | unqualified_pointer type_specifier_list   
949          {
950              $$ = $1  ;         
951              DCL_TSPEC($1) = $2;
952          }
953    | unqualified_pointer pointer         
954          {
955              $$ = $1 ;          
956              $$->next = $2 ;
957              DCL_TYPE($2)=port->unqualified_pointer;
958          }
959    | unqualified_pointer type_specifier_list pointer
960          {
961              $$ = $1 ;               
962              if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
963                  DCL_PTR_CONST($1) = SPEC_CONST($2);
964                  DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
965                  switch (SPEC_SCLS($2)) {
966                  case S_XDATA:
967                      DCL_TYPE($3) = FPOINTER;
968                      break;
969                  case S_IDATA:
970                      DCL_TYPE($3) = IPOINTER ;
971                      break;
972                  case S_PDATA:
973                      DCL_TYPE($3) = PPOINTER ;
974                      break;
975                  case S_DATA:
976                      DCL_TYPE($3) = POINTER ;
977                      break;
978                  case S_CODE:
979                      DCL_TYPE($3) = CPOINTER ;
980                      break;
981                  case S_EEPROM:
982                      DCL_TYPE($3) = EEPPOINTER;
983                      break;
984                  default:
985                    // this could be just "constant" 
986                    // werror(W_PTR_TYPE_INVALID);
987                      ;
988                  }
989              }
990              else 
991                  werror (W_PTR_TYPE_INVALID);
992              $$->next = $3 ;
993          }
994    ;
995
996 unqualified_pointer
997    :  '*'   
998       {
999         $$ = newLink(DECLARATOR);
1000         DCL_TYPE($$)=UPOINTER;
1001       }
1002    ;
1003
1004 type_specifier_list
1005    : type_specifier
1006    //| type_specifier_list type_specifier         {  $$ = mergeSpec ($1,$2, "type_specifier_list"); }
1007    | type_specifier_list type_specifier {
1008      /* if the decl $2 is not a specifier */
1009      /* find the spec and replace it      */
1010      if ( !IS_SPEC($2)) {
1011        sym_link *lnk = $2 ;
1012        while (lnk && !IS_SPEC(lnk->next))
1013          lnk = lnk->next;
1014        lnk->next = mergeSpec($1,lnk->next, "type_specifier_list type_specifier skipped");
1015        $$ = $2 ;
1016      }
1017      else
1018        $$ = mergeSpec($1,$2, "type_specifier_list type_specifier");
1019    }
1020    ;
1021
1022 parameter_identifier_list
1023    : identifier_list
1024    | identifier_list ',' ELIPSIS
1025    ;
1026
1027 identifier_list
1028    : identifier
1029    | identifier_list ',' identifier         
1030          {            
1031            $3->next = $1;
1032            $$ = $3 ;
1033          }
1034    ;
1035
1036 parameter_type_list
1037         : parameter_list
1038         | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1039         ;
1040
1041 parameter_list
1042    : parameter_declaration 
1043    | parameter_list ',' parameter_declaration
1044          {
1045             $3->next = $1 ;
1046             $$ = $3 ;       
1047          }
1048    ;
1049
1050 parameter_declaration
1051    : type_specifier_list declarator 
1052                {        
1053                   symbol *loop ;
1054                   pointerTypes($2->type,$1);
1055                   addDecl ($2,0,$1);              
1056                   for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1057                   addSymChain ($2);
1058                   $$ = symbolVal($2);
1059                }
1060    | type_name { 
1061                   $$ = newValue() ; 
1062                   $$->type = $1;
1063                   $$->etype = getSpec($$->type);
1064                }
1065    ;
1066
1067 type_name
1068    : type_specifier_list  { $$ = $1 ;}
1069    | type_specifier_list abstract_declarator 
1070                {
1071                  /* go to the end of the list */
1072                  sym_link *p;
1073                  pointerTypes($2,$1);
1074                  for ( p = $2 ; p && p->next ; p=p->next);
1075                  if (!p) {
1076                    werror(E_SYNTAX_ERROR, yytext);
1077                  } else {
1078                    p->next = $1 ;
1079                  }
1080                  $$ = $2 ;
1081                }   
1082    ;
1083
1084 abstract_declarator
1085    : pointer { $$ = reverseLink($1); }
1086    | abstract_declarator2
1087    | pointer abstract_declarator2   { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;} 
1088    ;
1089
1090 abstract_declarator2
1091    : '(' abstract_declarator ')'    { $$ = $2 ; }
1092    | '[' ']'                        {             
1093                                        $$ = newLink (DECLARATOR);
1094                                        DCL_TYPE($$) = ARRAY ;
1095                                        DCL_ELEM($$) = 0     ;
1096                                     }
1097    | '[' constant_expr ']'          { 
1098                                        value *val ;
1099                                        $$ = newLink (DECLARATOR);
1100                                        DCL_TYPE($$) = ARRAY ;
1101                                        DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1102                                     }
1103    | abstract_declarator2 '[' ']'   {
1104                                        $$ = newLink (DECLARATOR);
1105                                        DCL_TYPE($$) = ARRAY ;
1106                                        DCL_ELEM($$) = 0     ;
1107                                        $$->next = $1 ;
1108                                     }
1109    | abstract_declarator2 '[' constant_expr ']'
1110                                     {
1111                                        value *val ;
1112                                        $$ = newLink (DECLARATOR);
1113                                        DCL_TYPE($$) = ARRAY ;
1114                                        DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1115                                        $$->next = $1 ;
1116                                     }
1117    | '(' ')'                        { $$ = NULL;}
1118    | '(' parameter_type_list ')'    { $$ = NULL;}   
1119    | abstract_declarator2 '(' ')' {
1120      // $1 must be a pointer to a function
1121      sym_link *p=newLink(DECLARATOR);
1122      DCL_TYPE(p) = FUNCTION;
1123      if (!$1) {
1124        // ((void (code *) ()) 0) ()
1125        $1=newLink(DECLARATOR);
1126        DCL_TYPE($1)=CPOINTER;
1127        $$ = $1;
1128      }
1129      $1->next=p;
1130    }
1131    | abstract_declarator2 '(' parameter_type_list ')' {
1132      if (!IS_VOID($3->etype)) {
1133        // this is nonsense, so let's just burp something
1134        werror(E_TOO_FEW_PARMS);
1135      } else {
1136        // $1 must be a pointer to a function
1137        sym_link *p=newLink(DECLARATOR);
1138        DCL_TYPE(p) = FUNCTION;
1139        if (!$1) {
1140          // ((void (code *) (void)) 0) ()
1141          $1=newLink(DECLARATOR);
1142          DCL_TYPE($1)=CPOINTER;
1143          $$ = $1;
1144        }
1145        $1->next=p;
1146      }
1147    }
1148    ;
1149
1150 initializer
1151    : assignment_expr                { $$ = newiList(INIT_NODE,$1); }
1152    | '{'  initializer_list '}'      { $$ = newiList(INIT_DEEP,revinit($2)); }
1153    | '{'  initializer_list ',' '}'  { $$ = newiList(INIT_DEEP,revinit($2)); }
1154    ;
1155
1156 initializer_list
1157    : initializer
1158    | initializer_list ',' initializer  {  $3->next = $1; $$ = $3; }
1159    ;
1160
1161 statement
1162    : labeled_statement
1163    | compound_statement
1164    | expression_statement
1165    | selection_statement
1166    | iteration_statement
1167    | jump_statement
1168    | INLINEASM  ';'      {
1169                             ast *ex = newNode(INLINEASM,NULL,NULL);
1170                             ex->values.inlineasm = strdup($1);
1171                             $$ = ex;
1172                          } 
1173    ;
1174
1175 labeled_statement
1176 //   : identifier ':' statement          {  $$ = createLabel($1,$3);  }   
1177    : identifier ':'                    {  $$ = createLabel($1,NULL);  }   
1178    | CASE constant_expr ':' statement  {  $$ = createCase(STACK_PEEK(swStk),$2,$4); }
1179    | DEFAULT ':' statement             {  $$ = createDefault(STACK_PEEK(swStk),$3); }
1180    ;
1181
1182 start_block : '{' { STACK_PUSH(blockNum,currBlockno); currBlockno = ++blockNo ;  }
1183             ;
1184
1185 end_block   : '}'     { currBlockno = STACK_POP(blockNum); }           
1186             ;
1187
1188 compound_statement
1189    : start_block end_block                    { $$ = createBlock(NULL,NULL); }
1190    | start_block statement_list end_block     { $$ = createBlock(NULL,$2) ;  }
1191    | start_block 
1192           declaration_list                    { addSymChain($2); }
1193      end_block                                { $$ = createBlock($2,NULL) ;  }
1194    | start_block 
1195           declaration_list                    {  addSymChain ($2); }
1196           statement_list   
1197      end_block                                {$$ = createBlock($2,$4)   ;  }
1198    | error ';'                                { $$ = NULL ; }
1199    ;
1200
1201 declaration_list
1202    : declaration        
1203      {
1204        /* if this is typedef declare it immediately */
1205        if ( $1 && IS_TYPEDEF($1->etype)) {
1206          allocVariables ($1);
1207          $$ = NULL ;
1208        }
1209        else
1210          $$ = $1 ;
1211      }
1212
1213    | declaration_list declaration
1214      {
1215        symbol   *sym;
1216        
1217        /* if this is a typedef */
1218        if ($2 && IS_TYPEDEF($2->etype)) {
1219          allocVariables ($2);
1220          $$ = $1 ;
1221        }
1222        else {
1223                                 /* get to the end of the previous decl */
1224          if ( $1 ) {
1225            $$ = sym = $1 ;
1226            while (sym->next)
1227              sym = sym->next ;
1228            sym->next = $2;
1229          } 
1230          else
1231            $$ = $2 ;
1232        }
1233      }
1234    ;
1235
1236 statement_list
1237    : statement
1238    | statement_list statement          {  $$ = newNode(NULLOP,$1,$2) ;}
1239    ;
1240
1241 expression_statement
1242    : ';'                { $$ = NULL;}
1243    | expr ';' 
1244    ;
1245
1246 else_statement
1247    :  ELSE  statement   { $$ = $2  ; }
1248    |                    { $$ = NULL;}
1249    ;
1250
1251   
1252 selection_statement
1253    : IF '(' expr ')'  statement else_statement { noLineno++ ; $$ = createIf ($3, $5, $6 ); noLineno--;}
1254    | SWITCH '(' expr ')'   { 
1255                               ast *ex ;                              
1256                               static   int swLabel = 0 ;
1257
1258                               /* create a node for expression  */
1259                               ex = newNode(SWITCH,$3,NULL);
1260                               STACK_PUSH(swStk,ex);   /* save it in the stack */
1261                               ex->values.switchVals.swNum = swLabel ;
1262                                  
1263                               /* now create the label */
1264                               SNPRINTF(lbuff, sizeof(lbuff), 
1265                                        "_swBrk_%d",swLabel++);
1266                               $<sym>$  =  newSymbol(lbuff,NestLevel);
1267                               /* put label in the break stack  */
1268                               STACK_PUSH(breakStack,$<sym>$);   
1269                            }
1270      statement             {  
1271                               /* get back the switch form the stack  */
1272                               $$ = STACK_POP(swStk)  ;
1273                               $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1274                               STACK_POP(breakStack);   
1275                            }
1276         ;
1277
1278 while : WHILE  {  /* create and push the continue , break & body labels */
1279                   static int Lblnum = 0 ;
1280                   /* continue */
1281                   SNPRINTF (lbuff, sizeof(lbuff), "_whilecontinue_%d",Lblnum);
1282                   STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1283                   /* break */
1284                   SNPRINTF (lbuff, sizeof(lbuff), "_whilebreak_%d",Lblnum);
1285                   STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1286                   /* body */
1287                   SNPRINTF (lbuff, sizeof(lbuff), "_whilebody_%d",Lblnum++);
1288                   $$ = newSymbol(lbuff,NestLevel);
1289                }
1290    ;
1291
1292 do : DO {  /* create and push the continue , break & body Labels */
1293            static int Lblnum = 0 ;
1294
1295            /* continue */
1296            SNPRINTF(lbuff, sizeof(lbuff), "_docontinue_%d",Lblnum);
1297            STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1298            /* break */
1299            SNPRINTF(lbuff, sizeof(lbuff), "_dobreak_%d",Lblnum);
1300            STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1301            /* do body */
1302            SNPRINTF(lbuff, sizeof(lbuff), "_dobody_%d",Lblnum++);
1303            $$ = newSymbol (lbuff,NestLevel);       
1304         }
1305    ;
1306
1307 for : FOR { /* create & push continue, break & body labels */
1308             static int Lblnum = 0 ;
1309          
1310             /* continue */
1311             SNPRINTF(lbuff, sizeof(lbuff), "_forcontinue_%d",Lblnum);
1312             STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1313             /* break    */
1314             SNPRINTF(lbuff, sizeof(lbuff), "_forbreak_%d",Lblnum);
1315             STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1316             /* body */
1317             SNPRINTF(lbuff, sizeof(lbuff), "_forbody_%d",Lblnum);
1318             $$ = newSymbol(lbuff,NestLevel);
1319             /* condition */
1320             SNPRINTF(lbuff, sizeof(lbuff), "_forcond_%d",Lblnum++);
1321             STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1322           }
1323    ;
1324
1325 iteration_statement  
1326    : while '(' expr ')'  statement 
1327                          { 
1328                            noLineno++ ;
1329                            $$ = createWhile ( $1, STACK_POP(continueStack),
1330                                               STACK_POP(breakStack), $3, $5 ); 
1331                            $$->lineno = $1->lineDef ;
1332                            noLineno-- ;
1333                          }
1334    | do statement   WHILE '(' expr ')' ';' 
1335                         { 
1336                           noLineno++ ; 
1337                           $$ = createDo ( $1 , STACK_POP(continueStack), 
1338                                           STACK_POP(breakStack), $5, $2);
1339                           $$->lineno = $1->lineDef ;
1340                           noLineno-- ;
1341                         }                                                 
1342    | for '(' expr_opt   ';' expr_opt ';' expr_opt ')'  statement   
1343                         {
1344                           noLineno++ ;  
1345                           
1346                           /* if break or continue statement present
1347                              then create a general case loop */
1348                           if (STACK_PEEK(continueStack)->isref ||
1349                               STACK_PEEK(breakStack)->isref) {
1350                               $$ = createFor ($1, STACK_POP(continueStack),
1351                                               STACK_POP(breakStack) ,
1352                                               STACK_POP(forStack)   ,
1353                                               $3 , $5 , $7, $9 );
1354                           } else {
1355                               $$ = newNode(FOR,$9,NULL);
1356                               AST_FOR($$,trueLabel) = $1;
1357                               AST_FOR($$,continueLabel) =  STACK_POP(continueStack);
1358                               AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1359                               AST_FOR($$,condLabel)  = STACK_POP(forStack)  ;
1360                               AST_FOR($$,initExpr)   = $3;
1361                               AST_FOR($$,condExpr)   = $5;
1362                               AST_FOR($$,loopExpr)   = $7;
1363                           }
1364                           
1365                           noLineno-- ;
1366                         }
1367 ;
1368
1369 expr_opt
1370         :                       { $$ = NULL ; }
1371         |       expr
1372         ;
1373
1374 jump_statement          
1375    : GOTO identifier ';'   { 
1376                               $2->islbl = 1;
1377                               $$ = newAst_VALUE(symbolVal($2)); 
1378                               $$ = newNode(GOTO,$$,NULL);
1379                            }
1380    | CONTINUE ';'          {  
1381        /* make sure continue is in context */
1382        if (STACK_PEEK(continueStack) == NULL) {
1383            werror(E_BREAK_CONTEXT);
1384            $$ = NULL;
1385        }
1386        else {
1387            $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));      
1388            $$ = newNode(GOTO,$$,NULL);
1389            /* mark the continue label as referenced */
1390            STACK_PEEK(continueStack)->isref = 1;
1391        }
1392    }
1393    | BREAK ';'             { 
1394        if (STACK_PEEK(breakStack) == NULL) {
1395            werror(E_BREAK_CONTEXT);
1396            $$ = NULL;
1397        } else {
1398            $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
1399            $$ = newNode(GOTO,$$,NULL);
1400            STACK_PEEK(breakStack)->isref = 1;
1401        }
1402    }
1403    | RETURN ';'            { $$ = newNode(RETURN,NULL,NULL)    ; }
1404    | RETURN expr ';'       { $$ = newNode(RETURN,NULL,$2) ; } 
1405    ;
1406
1407 identifier
1408    : IDENTIFIER   { $$ = newSymbol ($1,NestLevel) ; }
1409    ;
1410 %%
1411