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