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