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