undid the hackup of const and volatile, the problem is much bigger
[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_PTR_CONST($3) = 1;
980                      DCL_TYPE($3) = CPOINTER ;
981                      break;
982                  case S_EEPROM:
983                      DCL_TYPE($3) = EEPPOINTER;
984                      break;
985                  default:
986                    // this could be just "constant" 
987                    // werror(W_PTR_TYPE_INVALID);
988                      ;
989                  }
990              }
991              else 
992                  werror (W_PTR_TYPE_INVALID);
993              $$->next = $3 ;
994          }
995    ;
996
997 unqualified_pointer
998    :  '*'   
999       {
1000         $$ = newLink(DECLARATOR);
1001         DCL_TYPE($$)=UPOINTER;
1002       }
1003    ;
1004
1005 type_specifier_list
1006    : type_specifier
1007    //| type_specifier_list type_specifier         {  $$ = mergeSpec ($1,$2, "type_specifier_list"); }
1008    | type_specifier_list type_specifier {
1009      /* if the decl $2 is not a specifier */
1010      /* find the spec and replace it      */
1011      if ( !IS_SPEC($2)) {
1012        sym_link *lnk = $2 ;
1013        while (lnk && !IS_SPEC(lnk->next))
1014          lnk = lnk->next;
1015        lnk->next = mergeSpec($1,lnk->next, "type_specifier_list type_specifier skipped");
1016        $$ = $2 ;
1017      }
1018      else
1019        $$ = mergeSpec($1,$2, "type_specifier_list type_specifier");
1020    }
1021    ;
1022
1023 parameter_identifier_list
1024    : identifier_list
1025    | identifier_list ',' ELIPSIS
1026    ;
1027
1028 identifier_list
1029    : identifier
1030    | identifier_list ',' identifier         
1031          {            
1032            $3->next = $1;
1033            $$ = $3 ;
1034          }
1035    ;
1036
1037 parameter_type_list
1038         : parameter_list
1039         | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1040         ;
1041
1042 parameter_list
1043    : parameter_declaration 
1044    | parameter_list ',' parameter_declaration
1045          {
1046             $3->next = $1 ;
1047             $$ = $3 ;       
1048          }
1049    ;
1050
1051 parameter_declaration
1052    : type_specifier_list declarator 
1053                {        
1054                   symbol *loop ;
1055                   pointerTypes($2->type,$1);
1056                   addDecl ($2,0,$1);              
1057                   for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1058                   addSymChain ($2);
1059                   $$ = symbolVal($2);
1060                }
1061    | type_name { 
1062                   $$ = newValue() ; 
1063                   $$->type = $1;
1064                   $$->etype = getSpec($$->type);
1065                }
1066    ;
1067
1068 type_name
1069    : type_specifier_list  { $$ = $1 ;}
1070    | type_specifier_list abstract_declarator 
1071                {
1072                  /* go to the end of the list */
1073                  sym_link *p;
1074                  pointerTypes($2,$1);
1075                  for ( p = $2 ; p && p->next ; p=p->next);
1076                  if (!p) {
1077                    werror(E_SYNTAX_ERROR, yytext);
1078                  } else {
1079                    p->next = $1 ;
1080                  }
1081                  $$ = $2 ;
1082                }   
1083    ;
1084
1085 abstract_declarator
1086    : pointer { $$ = reverseLink($1); }
1087    | abstract_declarator2
1088    | pointer abstract_declarator2   { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;} 
1089    ;
1090
1091 abstract_declarator2
1092    : '(' abstract_declarator ')'    { $$ = $2 ; }
1093    | '[' ']'                        {             
1094                                        $$ = newLink (DECLARATOR);
1095                                        DCL_TYPE($$) = ARRAY ;
1096                                        DCL_ELEM($$) = 0     ;
1097                                     }
1098    | '[' constant_expr ']'          { 
1099                                        value *val ;
1100                                        $$ = newLink (DECLARATOR);
1101                                        DCL_TYPE($$) = ARRAY ;
1102                                        DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1103                                     }
1104    | abstract_declarator2 '[' ']'   {
1105                                        $$ = newLink (DECLARATOR);
1106                                        DCL_TYPE($$) = ARRAY ;
1107                                        DCL_ELEM($$) = 0     ;
1108                                        $$->next = $1 ;
1109                                     }
1110    | abstract_declarator2 '[' constant_expr ']'
1111                                     {
1112                                        value *val ;
1113                                        $$ = newLink (DECLARATOR);
1114                                        DCL_TYPE($$) = ARRAY ;
1115                                        DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1116                                        $$->next = $1 ;
1117                                     }
1118    | '(' ')'                        { $$ = NULL;}
1119    | '(' parameter_type_list ')'    { $$ = NULL;}   
1120    | abstract_declarator2 '(' ')' {
1121      // $1 must be a pointer to a function
1122      sym_link *p=newLink(DECLARATOR);
1123      DCL_TYPE(p) = FUNCTION;
1124      if (!$1) {
1125        // ((void (code *) ()) 0) ()
1126        $1=newLink(DECLARATOR);
1127        DCL_TYPE($1)=CPOINTER;
1128        $$ = $1;
1129      }
1130      $1->next=p;
1131    }
1132    | abstract_declarator2 '(' parameter_type_list ')' {
1133      if (!IS_VOID($3->etype)) {
1134        // this is nonsense, so let's just burp something
1135        werror(E_TOO_FEW_PARMS);
1136      } else {
1137        // $1 must be a pointer to a function
1138        sym_link *p=newLink(DECLARATOR);
1139        DCL_TYPE(p) = FUNCTION;
1140        if (!$1) {
1141          // ((void (code *) (void)) 0) ()
1142          $1=newLink(DECLARATOR);
1143          DCL_TYPE($1)=CPOINTER;
1144          $$ = $1;
1145        }
1146        $1->next=p;
1147      }
1148    }
1149    ;
1150
1151 initializer
1152    : assignment_expr                { $$ = newiList(INIT_NODE,$1); }
1153    | '{'  initializer_list '}'      { $$ = newiList(INIT_DEEP,revinit($2)); }
1154    | '{'  initializer_list ',' '}'  { $$ = newiList(INIT_DEEP,revinit($2)); }
1155    ;
1156
1157 initializer_list
1158    : initializer
1159    | initializer_list ',' initializer  {  $3->next = $1; $$ = $3; }
1160    ;
1161
1162 statement
1163    : labeled_statement
1164    | compound_statement
1165    | expression_statement
1166    | selection_statement
1167    | iteration_statement
1168    | jump_statement
1169    | INLINEASM  ';'      {
1170                             ast *ex = newNode(INLINEASM,NULL,NULL);
1171                             ex->values.inlineasm = strdup($1);
1172                             $$ = ex;
1173                          } 
1174    ;
1175
1176 labeled_statement
1177 //   : identifier ':' statement          {  $$ = createLabel($1,$3);  }   
1178    : identifier ':'                    {  $$ = createLabel($1,NULL);  }   
1179    | CASE constant_expr ':' statement  {  $$ = createCase(STACK_PEEK(swStk),$2,$4); }
1180    | DEFAULT ':' statement             {  $$ = createDefault(STACK_PEEK(swStk),$3); }
1181    ;
1182
1183 start_block : '{' { STACK_PUSH(blockNum,currBlockno); currBlockno = ++blockNo ;  }
1184             ;
1185
1186 end_block   : '}'     { currBlockno = STACK_POP(blockNum); }           
1187             ;
1188
1189 compound_statement
1190    : start_block end_block                    { $$ = createBlock(NULL,NULL); }
1191    | start_block statement_list end_block     { $$ = createBlock(NULL,$2) ;  }
1192    | start_block 
1193           declaration_list                    { addSymChain($2); }
1194      end_block                                { $$ = createBlock($2,NULL) ;  }
1195    | start_block 
1196           declaration_list                    {  addSymChain ($2); }
1197           statement_list   
1198      end_block                                {$$ = createBlock($2,$4)   ;  }
1199    | error ';'                                { $$ = NULL ; }
1200    ;
1201
1202 declaration_list
1203    : declaration        
1204      {
1205        /* if this is typedef declare it immediately */
1206        if ( $1 && IS_TYPEDEF($1->etype)) {
1207          allocVariables ($1);
1208          $$ = NULL ;
1209        }
1210        else
1211          $$ = $1 ;
1212      }
1213
1214    | declaration_list declaration
1215      {
1216        symbol   *sym;
1217        
1218        /* if this is a typedef */
1219        if ($2 && IS_TYPEDEF($2->etype)) {
1220          allocVariables ($2);
1221          $$ = $1 ;
1222        }
1223        else {
1224                                 /* get to the end of the previous decl */
1225          if ( $1 ) {
1226            $$ = sym = $1 ;
1227            while (sym->next)
1228              sym = sym->next ;
1229            sym->next = $2;
1230          } 
1231          else
1232            $$ = $2 ;
1233        }
1234      }
1235    ;
1236
1237 statement_list
1238    : statement
1239    | statement_list statement          {  $$ = newNode(NULLOP,$1,$2) ;}
1240    ;
1241
1242 expression_statement
1243    : ';'                { $$ = NULL;}
1244    | expr ';' 
1245    ;
1246
1247 else_statement
1248    :  ELSE  statement   { $$ = $2  ; }
1249    |                    { $$ = NULL;}
1250    ;
1251
1252   
1253 selection_statement
1254    : IF '(' expr ')'  statement else_statement { noLineno++ ; $$ = createIf ($3, $5, $6 ); noLineno--;}
1255    | SWITCH '(' expr ')'   { 
1256                               ast *ex ;                              
1257                               static   int swLabel = 0 ;
1258
1259                               /* create a node for expression  */
1260                               ex = newNode(SWITCH,$3,NULL);
1261                               STACK_PUSH(swStk,ex);   /* save it in the stack */
1262                               ex->values.switchVals.swNum = swLabel ;
1263                                  
1264                               /* now create the label */
1265                               SNPRINTF(lbuff, sizeof(lbuff), 
1266                                        "_swBrk_%d",swLabel++);
1267                               $<sym>$  =  newSymbol(lbuff,NestLevel);
1268                               /* put label in the break stack  */
1269                               STACK_PUSH(breakStack,$<sym>$);   
1270                            }
1271      statement             {  
1272                               /* get back the switch form the stack  */
1273                               $$ = STACK_POP(swStk)  ;
1274                               $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1275                               STACK_POP(breakStack);   
1276                            }
1277         ;
1278
1279 while : WHILE  {  /* create and push the continue , break & body labels */
1280                   static int Lblnum = 0 ;
1281                   /* continue */
1282                   SNPRINTF (lbuff, sizeof(lbuff), "_whilecontinue_%d",Lblnum);
1283                   STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1284                   /* break */
1285                   SNPRINTF (lbuff, sizeof(lbuff), "_whilebreak_%d",Lblnum);
1286                   STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1287                   /* body */
1288                   SNPRINTF (lbuff, sizeof(lbuff), "_whilebody_%d",Lblnum++);
1289                   $$ = newSymbol(lbuff,NestLevel);
1290                }
1291    ;
1292
1293 do : DO {  /* create and push the continue , break & body Labels */
1294            static int Lblnum = 0 ;
1295
1296            /* continue */
1297            SNPRINTF(lbuff, sizeof(lbuff), "_docontinue_%d",Lblnum);
1298            STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1299            /* break */
1300            SNPRINTF(lbuff, sizeof(lbuff), "_dobreak_%d",Lblnum);
1301            STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1302            /* do body */
1303            SNPRINTF(lbuff, sizeof(lbuff), "_dobody_%d",Lblnum++);
1304            $$ = newSymbol (lbuff,NestLevel);       
1305         }
1306    ;
1307
1308 for : FOR { /* create & push continue, break & body labels */
1309             static int Lblnum = 0 ;
1310          
1311             /* continue */
1312             SNPRINTF(lbuff, sizeof(lbuff), "_forcontinue_%d",Lblnum);
1313             STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1314             /* break    */
1315             SNPRINTF(lbuff, sizeof(lbuff), "_forbreak_%d",Lblnum);
1316             STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1317             /* body */
1318             SNPRINTF(lbuff, sizeof(lbuff), "_forbody_%d",Lblnum);
1319             $$ = newSymbol(lbuff,NestLevel);
1320             /* condition */
1321             SNPRINTF(lbuff, sizeof(lbuff), "_forcond_%d",Lblnum++);
1322             STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1323           }
1324    ;
1325
1326 iteration_statement  
1327    : while '(' expr ')'  statement 
1328                          { 
1329                            noLineno++ ;
1330                            $$ = createWhile ( $1, STACK_POP(continueStack),
1331                                               STACK_POP(breakStack), $3, $5 ); 
1332                            $$->lineno = $1->lineDef ;
1333                            noLineno-- ;
1334                          }
1335    | do statement   WHILE '(' expr ')' ';' 
1336                         { 
1337                           noLineno++ ; 
1338                           $$ = createDo ( $1 , STACK_POP(continueStack), 
1339                                           STACK_POP(breakStack), $5, $2);
1340                           $$->lineno = $1->lineDef ;
1341                           noLineno-- ;
1342                         }                                                 
1343    | for '(' expr_opt   ';' expr_opt ';' expr_opt ')'  statement   
1344                         {
1345                           noLineno++ ;  
1346                           
1347                           /* if break or continue statement present
1348                              then create a general case loop */
1349                           if (STACK_PEEK(continueStack)->isref ||
1350                               STACK_PEEK(breakStack)->isref) {
1351                               $$ = createFor ($1, STACK_POP(continueStack),
1352                                               STACK_POP(breakStack) ,
1353                                               STACK_POP(forStack)   ,
1354                                               $3 , $5 , $7, $9 );
1355                           } else {
1356                               $$ = newNode(FOR,$9,NULL);
1357                               AST_FOR($$,trueLabel) = $1;
1358                               AST_FOR($$,continueLabel) =  STACK_POP(continueStack);
1359                               AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1360                               AST_FOR($$,condLabel)  = STACK_POP(forStack)  ;
1361                               AST_FOR($$,initExpr)   = $3;
1362                               AST_FOR($$,condExpr)   = $5;
1363                               AST_FOR($$,loopExpr)   = $7;
1364                           }
1365                           
1366                           noLineno-- ;
1367                         }
1368 ;
1369
1370 expr_opt
1371         :                       { $$ = NULL ; }
1372         |       expr
1373         ;
1374
1375 jump_statement          
1376    : GOTO identifier ';'   { 
1377                               $2->islbl = 1;
1378                               $$ = newAst_VALUE(symbolVal($2)); 
1379                               $$ = newNode(GOTO,$$,NULL);
1380                            }
1381    | CONTINUE ';'          {  
1382        /* make sure continue is in context */
1383        if (STACK_PEEK(continueStack) == NULL) {
1384            werror(E_BREAK_CONTEXT);
1385            $$ = NULL;
1386        }
1387        else {
1388            $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));      
1389            $$ = newNode(GOTO,$$,NULL);
1390            /* mark the continue label as referenced */
1391            STACK_PEEK(continueStack)->isref = 1;
1392        }
1393    }
1394    | BREAK ';'             { 
1395        if (STACK_PEEK(breakStack) == NULL) {
1396            werror(E_BREAK_CONTEXT);
1397            $$ = NULL;
1398        } else {
1399            $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
1400            $$ = newNode(GOTO,$$,NULL);
1401            STACK_PEEK(breakStack)->isref = 1;
1402        }
1403    }
1404    | RETURN ';'            { $$ = newNode(RETURN,NULL,NULL)    ; }
1405    | RETURN expr ';'       { $$ = newNode(RETURN,NULL,$2) ; } 
1406    ;
1407
1408 identifier
1409    : IDENTIFIER   { $$ = newSymbol ($1,NestLevel) ; }
1410    ;
1411 %%
1412