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