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