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