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