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