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