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