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