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