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