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