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