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