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