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