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