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