* sdc/SDCC.y, src/SDCCmain.c, src/SDCCglobl.h, doc/sdccman.lyx:
[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                          }
968    | enumerator_list ',' enumerator
969      {
970        symbol *dsym;
971
972        for (dsym=$1; dsym; dsym=dsym->next)
973          {
974            if (strcmp($3->name, dsym->name)==0)
975              {
976                werrorfl($3->fileDef, $3->lineDef, E_DUPLICATE_MEMBER, "enum", $3->name);
977                werrorfl(dsym->fileDef, dsym->lineDef, E_PREVIOUS_DEF);
978              }
979          }
980
981        $3->next = $1 ;
982        $$ = $3  ;
983      }
984    ;
985
986 enumerator
987    : identifier opt_assign_expr
988      {
989        /* make the symbol one level up */
990        $1->level-- ;
991        $1->type = copyLinkChain($2->type);
992        $1->etype= getSpec($1->type);
993        SPEC_ENUM($1->etype) = 1;
994        $$ = $1 ;
995        // do this now, so we can use it for the next enums in the list
996        addSymChain(&$1);
997      }
998    ;
999
1000 opt_assign_expr
1001    :  '='   constant_expr  {
1002                               value *val ;
1003
1004                               val = constExprValue($2,TRUE);
1005                               if (!IS_INT(val->type) && !IS_CHAR(val->type))
1006                                 {
1007                                   werror(E_ENUM_NON_INTEGER);
1008                                   SNPRINTF(lbuff, sizeof(lbuff),
1009                                           "%d",(int) floatFromVal(val));
1010                                   val = constVal(lbuff);
1011                                 }
1012                               $$ = cenum = val ;
1013                            }
1014    |                       {
1015                               if (cenum)  {
1016                                  SNPRINTF(lbuff, sizeof(lbuff),
1017                                           "%d",(int) floatFromVal(cenum)+1);
1018                                  $$ = cenum = constVal(lbuff);
1019                               }
1020                               else {
1021                                  SNPRINTF(lbuff, sizeof(lbuff),
1022                                           "%d",0);
1023                                  $$ = cenum = constVal(lbuff);
1024                               }
1025                            }
1026    ;
1027
1028 declarator
1029    : declarator3                        { $$ = $1 ; }
1030    | pointer declarator3
1031          {
1032              addDecl ($2,0,reverseLink($1));
1033              $$ = $2 ;
1034          }
1035    ;
1036
1037 declarator3
1038    : declarator2_function_attributes    { $$ = $1 ; }
1039    | declarator2                        { $$ = $1 ; }
1040    ;
1041
1042 function_declarator
1043    : declarator2_function_attributes    { $$ = $1; }
1044    | pointer declarator2_function_attributes
1045          {
1046              addDecl ($2,0,reverseLink($1));
1047              $$ = $2 ;
1048          }
1049    ;
1050
1051 declarator2_function_attributes
1052    : function_declarator2                 { $$ = $1 ; }
1053    | function_declarator2 function_attribute  {
1054            // copy the functionAttributes (not the args and hasVargs !!)
1055            struct value *args;
1056            unsigned hasVargs;
1057            sym_link *funcType=$1->type;
1058
1059            while (funcType && !IS_FUNC(funcType))
1060              funcType = funcType->next;
1061
1062            if (!funcType)
1063              werror (E_FUNC_ATTR);
1064            else
1065              {
1066                args=FUNC_ARGS(funcType);
1067                hasVargs=FUNC_HASVARARGS(funcType);
1068
1069                memcpy (&funcType->funcAttrs, &$2->funcAttrs,
1070                    sizeof($2->funcAttrs));
1071
1072                FUNC_ARGS(funcType)=args;
1073                FUNC_HASVARARGS(funcType)=hasVargs;
1074
1075                // just to be sure
1076                memset (&$2->funcAttrs, 0,
1077                    sizeof($2->funcAttrs));
1078
1079                addDecl ($1,0,$2);
1080              }
1081    }
1082    ;
1083
1084 declarator2
1085    : identifier
1086    | '(' declarator ')'     { $$ = $2; }
1087    | declarator3 '[' ']'
1088          {
1089             sym_link   *p;
1090
1091             p = newLink (DECLARATOR);
1092             DCL_TYPE(p) = ARRAY ;
1093             DCL_ELEM(p) = 0     ;
1094             addDecl($1,0,p);
1095          }
1096    | declarator3 '[' constant_expr ']'
1097          {
1098             sym_link   *p ;
1099                         value *tval;
1100
1101             tval = constExprValue($3,TRUE);
1102             /* if it is not a constant then Error  */
1103             p = newLink (DECLARATOR);
1104             DCL_TYPE(p) = ARRAY ;
1105             if ( !tval || (SPEC_SCLS(tval->etype) != S_LITERAL)) {
1106                werror(E_CONST_EXPECTED) ;
1107                /* Assume a single item array to limit the cascade */
1108                /* of additional errors. */
1109                DCL_ELEM(p) = 1;
1110             }
1111             else {
1112                DCL_ELEM(p) = (int) floatFromVal(tval) ;
1113             }
1114             addDecl($1,0,p);
1115          }
1116    ;
1117
1118 function_declarator2
1119    : declarator2 '('  ')'       {  addDecl ($1,FUNCTION,NULL) ;   }
1120    | declarator2 '('            { NestLevel++ ; currBlockno++;  }
1121                      parameter_type_list ')'
1122          {
1123              sym_link *funcType;
1124
1125              addDecl ($1,FUNCTION,NULL) ;
1126
1127              funcType = $1->type;
1128              while (funcType && !IS_FUNC(funcType))
1129                funcType = funcType->next;
1130
1131              assert (funcType);
1132
1133              FUNC_HASVARARGS(funcType) = IS_VARG($4);
1134              FUNC_ARGS(funcType) = reverseVal($4);
1135
1136              /* nest level was incremented to take care of the parms  */
1137              NestLevel-- ;
1138              currBlockno--;
1139
1140              // if this was a pointer (to a function)
1141              if (!IS_FUNC($1->type))
1142                cleanUpLevel(SymbolTab,NestLevel+1);
1143
1144              $$ = $1;
1145          }
1146    | declarator2 '(' identifier_list ')'
1147          {
1148            werror(E_OLD_STYLE,$1->name) ;
1149            /* assume it returns an int */
1150            $1->type = $1->etype = newIntLink();
1151            $$ = $1 ;
1152          }
1153    ;
1154
1155 pointer
1156    : unqualified_pointer { $$ = $1 ;}
1157    | unqualified_pointer type_specifier_list
1158          {
1159              $$ = $1  ;
1160              if (IS_SPEC($2)) {
1161                  DCL_TSPEC($1) = $2;
1162                  DCL_PTR_CONST($1) = SPEC_CONST($2);
1163                  DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1164              }
1165              else
1166                  werror (W_PTR_TYPE_INVALID);
1167          }
1168    | unqualified_pointer pointer
1169          {
1170              $$ = $1 ;
1171              $$->next = $2 ;
1172              DCL_TYPE($2)=port->unqualified_pointer;
1173          }
1174    | unqualified_pointer type_specifier_list pointer
1175          {
1176              $$ = $1 ;
1177              if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
1178                  DCL_PTR_CONST($1) = SPEC_CONST($2);
1179                  DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1180                  switch (SPEC_SCLS($2)) {
1181                  case S_XDATA:
1182                      DCL_TYPE($3) = FPOINTER;
1183                      break;
1184                  case S_IDATA:
1185                      DCL_TYPE($3) = IPOINTER ;
1186                      break;
1187                  case S_PDATA:
1188                      DCL_TYPE($3) = PPOINTER ;
1189                      break;
1190                  case S_DATA:
1191                      DCL_TYPE($3) = POINTER ;
1192                      break;
1193                  case S_CODE:
1194                      DCL_TYPE($3) = CPOINTER ;
1195                      break;
1196                  case S_EEPROM:
1197                      DCL_TYPE($3) = EEPPOINTER;
1198                      break;
1199                  default:
1200                    // this could be just "constant"
1201                    // werror(W_PTR_TYPE_INVALID);
1202                      ;
1203                  }
1204              }
1205              else
1206                  werror (W_PTR_TYPE_INVALID);
1207              $$->next = $3 ;
1208          }
1209    ;
1210
1211 unqualified_pointer
1212    :  '*'
1213       {
1214         $$ = newLink(DECLARATOR);
1215         DCL_TYPE($$)=UPOINTER;
1216       }
1217    ;
1218
1219 type_specifier_list
1220    : type_specifier
1221    //| type_specifier_list type_specifier         {  $$ = mergeSpec ($1,$2, "type_specifier_list"); }
1222    | type_specifier_list type_specifier {
1223      /* if the decl $2 is not a specifier */
1224      /* find the spec and replace it      */
1225      if ( !IS_SPEC($2)) {
1226        sym_link *lnk = $2 ;
1227        while (lnk && !IS_SPEC(lnk->next))
1228          lnk = lnk->next;
1229        lnk->next = mergeSpec($1,lnk->next, "type_specifier_list type_specifier skipped");
1230        $$ = $2 ;
1231      }
1232      else
1233        $$ = mergeSpec($1,$2, "type_specifier_list type_specifier");
1234    }
1235    ;
1236
1237 identifier_list
1238    : identifier
1239    | identifier_list ',' identifier
1240          {
1241            $3->next = $1;
1242            $$ = $3 ;
1243          }
1244    ;
1245
1246 parameter_type_list
1247         : parameter_list
1248         | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1249         ;
1250
1251 parameter_list
1252    : parameter_declaration
1253    | parameter_list ',' parameter_declaration
1254          {
1255             $3->next = $1 ;
1256             $$ = $3 ;
1257          }
1258    ;
1259
1260 parameter_declaration
1261    : type_specifier_list declarator
1262                {
1263                   symbol *loop ;
1264                   pointerTypes($2->type,$1);
1265                   if (options.unsigned_char && SPEC_NOUN($1) == V_CHAR && !($1)->select.s.b_signed)
1266                     SPEC_USIGN($1) = 1;
1267                   addDecl ($2,0,$1);
1268                   for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1269                   addSymChain (&$2);
1270                   $$ = symbolVal($2);
1271                   ignoreTypedefType = 0;
1272                }
1273    | type_name {
1274                   $$ = newValue() ;
1275                   if (options.unsigned_char && SPEC_NOUN($1) == V_CHAR && !($1)->select.s.b_signed)
1276                     SPEC_USIGN($1) = 1;
1277                   $$->type = $1;
1278                   $$->etype = getSpec($$->type);
1279                   ignoreTypedefType = 0;
1280                }
1281    ;
1282
1283 type_name
1284    : type_specifier_list  { $$ = $1; ignoreTypedefType = 0;}
1285    | type_specifier_list abstract_declarator
1286                {
1287                  /* go to the end of the list */
1288                  sym_link *p;
1289                  pointerTypes($2,$1);
1290                  for ( p = $2 ; p && p->next ; p=p->next);
1291                  if (!p) {
1292                    werror(E_SYNTAX_ERROR, yytext);
1293                  } else {
1294                    p->next = $1 ;
1295                  }
1296                  $$ = $2 ;
1297                  ignoreTypedefType = 0;
1298                }
1299    ;
1300
1301 abstract_declarator
1302    : pointer { $$ = reverseLink($1); }
1303    | abstract_declarator2
1304    | pointer abstract_declarator2   { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;
1305           if (IS_PTR($1) && IS_FUNC($2))
1306             DCL_TYPE($1) = CPOINTER;
1307         }
1308    ;
1309
1310 abstract_declarator2
1311    : '(' abstract_declarator ')'    { $$ = $2 ; }
1312    | '[' ']'                        {
1313                                        $$ = newLink (DECLARATOR);
1314                                        DCL_TYPE($$) = ARRAY ;
1315                                        DCL_ELEM($$) = 0     ;
1316                                     }
1317    | '[' constant_expr ']'          {
1318                                        value *val ;
1319                                        $$ = newLink (DECLARATOR);
1320                                        DCL_TYPE($$) = ARRAY ;
1321                                        DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1322                                     }
1323    | abstract_declarator2 '[' ']'   {
1324                                        $$ = newLink (DECLARATOR);
1325                                        DCL_TYPE($$) = ARRAY ;
1326                                        DCL_ELEM($$) = 0     ;
1327                                        $$->next = $1 ;
1328                                     }
1329    | abstract_declarator2 '[' constant_expr ']'
1330                                     {
1331                                        value *val ;
1332                                        $$ = newLink (DECLARATOR);
1333                                        DCL_TYPE($$) = ARRAY ;
1334                                        DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1335                                        $$->next = $1 ;
1336                                     }
1337    | '(' ')'                        { $$ = NULL;}
1338    | '(' parameter_type_list ')'    { $$ = NULL;}
1339    | abstract_declarator2 '(' ')' {
1340      // $1 must be a pointer to a function
1341      sym_link *p=newLink(DECLARATOR);
1342      DCL_TYPE(p) = FUNCTION;
1343      if (!$1) {
1344        // ((void (code *) ()) 0) ()
1345        $1=newLink(DECLARATOR);
1346        DCL_TYPE($1)=CPOINTER;
1347        $$ = $1;
1348      }
1349      $1->next=p;
1350    }
1351    | abstract_declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')' {
1352        sym_link *p=newLink(DECLARATOR);
1353        DCL_TYPE(p) = FUNCTION;
1354
1355        FUNC_HASVARARGS(p) = IS_VARG($4);
1356        FUNC_ARGS(p) = reverseVal($4);
1357
1358        /* nest level was incremented to take care of the parms  */
1359        NestLevel-- ;
1360        currBlockno--;
1361        if (!$1) {
1362          /* ((void (code *) (void)) 0) () */
1363          $1=newLink(DECLARATOR);
1364          DCL_TYPE($1)=CPOINTER;
1365          $$ = $1;
1366        }
1367        $1->next=p;
1368
1369        // remove the symbol args (if any)
1370        cleanUpLevel(SymbolTab,NestLevel+1);
1371    }
1372    ;
1373
1374 initializer
1375    : assignment_expr                { $$ = newiList(INIT_NODE,$1); }
1376    | '{'  initializer_list '}'      { $$ = newiList(INIT_DEEP,revinit($2)); }
1377    | '{'  initializer_list ',' '}'  { $$ = newiList(INIT_DEEP,revinit($2)); }
1378    ;
1379
1380 initializer_list
1381    : initializer
1382    | initializer_list ',' initializer  {  $3->next = $1; $$ = $3; }
1383    ;
1384
1385 statement
1386    : labeled_statement
1387    | compound_statement
1388    | expression_statement
1389    | selection_statement
1390    | iteration_statement
1391    | jump_statement
1392    | critical_statement
1393    | INLINEASM  ';'      {
1394                             ast *ex;
1395                             seqPointNo++;
1396                             ex = newNode(INLINEASM,NULL,NULL);
1397                             ex->values.inlineasm = strdup($1);
1398                             seqPointNo++;
1399                             $$ = ex;
1400                          }
1401    ;
1402
1403 critical
1404    : CRITICAL   {
1405                    inCritical++;
1406                    STACK_PUSH(continueStack,NULL);
1407                    STACK_PUSH(breakStack,NULL);
1408                    $$ = NULL;
1409                 }
1410    ;
1411
1412 critical_statement
1413    : critical statement  {
1414                    STACK_POP(breakStack);
1415                    STACK_POP(continueStack);
1416                    inCritical--;
1417                    $$ = newNode(CRITICAL,$2,NULL);
1418                 }
1419    ;
1420
1421 labeled_statement
1422 //   : identifier ':' statement          {  $$ = createLabel($1,$3);  }
1423    : identifier ':'                    {  $$ = createLabel($1,NULL);
1424                                           $1->isitmp = 0;  }
1425    | CASE constant_expr ':'
1426      {
1427        if (STACK_EMPTY(swStk))
1428          $$ = createCase(NULL,$2,NULL);
1429        else
1430          $$ = createCase(STACK_PEEK(swStk),$2,NULL);
1431      }
1432    | DEFAULT { $<asts>$ = newNode(DEFAULT,NULL,NULL); } ':'
1433      {
1434        if (STACK_EMPTY(swStk))
1435          $$ = createDefault(NULL,$<asts>2,NULL);
1436        else
1437          $$ = createDefault(STACK_PEEK(swStk),$<asts>2,NULL);
1438      }
1439    ;
1440
1441 start_block : '{'
1442               {
1443                 STACK_PUSH(blockNum,currBlockno);
1444                 currBlockno = ++blockNo ;
1445                 ignoreTypedefType = 0;
1446               }
1447             ;
1448
1449 end_block   : '}'     { currBlockno = STACK_POP(blockNum); }
1450             ;
1451
1452 compound_statement
1453    : start_block end_block                    { $$ = createBlock(NULL,NULL); }
1454    | start_block statement_list end_block     { $$ = createBlock(NULL,$2) ;  }
1455    | start_block
1456           declaration_list                    { addSymChain(&$2); }
1457      end_block                                { $$ = createBlock($2,NULL) ;  }
1458    | start_block
1459           declaration_list                    {  addSymChain (&$2); }
1460           statement_list
1461      end_block                                {$$ = createBlock($2,$4)   ;  }
1462    | error ';'                                { $$ = NULL ; }
1463    ;
1464
1465 declaration_list
1466    : declaration
1467      {
1468        /* if this is typedef declare it immediately */
1469        if ( $1 && IS_TYPEDEF($1->etype)) {
1470          allocVariables ($1);
1471          $$ = NULL ;
1472        }
1473        else
1474          $$ = $1 ;
1475        ignoreTypedefType = 0;
1476      }
1477
1478    | declaration_list declaration
1479      {
1480        symbol   *sym;
1481
1482        /* if this is a typedef */
1483        if ($2 && IS_TYPEDEF($2->etype)) {
1484          allocVariables ($2);
1485          $$ = $1 ;
1486        }
1487        else {
1488                                 /* get to the end of the previous decl */
1489          if ( $1 ) {
1490            $$ = sym = $1 ;
1491            while (sym->next)
1492              sym = sym->next ;
1493            sym->next = $2;
1494          }
1495          else
1496            $$ = $2 ;
1497        }
1498        ignoreTypedefType = 0;
1499      }
1500    ;
1501
1502 statement_list
1503    : statement
1504    | statement_list statement          {  $$ = newNode(NULLOP,$1,$2) ;}
1505    ;
1506
1507 expression_statement
1508    : ';'                { $$ = NULL;}
1509    | expr ';'           { $$ = $1; seqPointNo++;}
1510    ;
1511
1512 else_statement
1513    :  ELSE  statement   { $$ = $2  ; }
1514    |                    { $$ = NULL;}
1515    ;
1516
1517
1518 selection_statement
1519    : IF '(' expr ')' { seqPointNo++;} statement else_statement
1520                            {
1521                               noLineno++ ;
1522                               $$ = createIf ($3, $6, $7 );
1523                               noLineno--;
1524                            }
1525    | SWITCH '(' expr ')'   {
1526                               ast *ex ;
1527                               static   int swLabel = 0 ;
1528
1529                               seqPointNo++;
1530                               /* create a node for expression  */
1531                               ex = newNode(SWITCH,$3,NULL);
1532                               STACK_PUSH(swStk,ex);   /* save it in the stack */
1533                               ex->values.switchVals.swNum = swLabel ;
1534
1535                               /* now create the label */
1536                               SNPRINTF(lbuff, sizeof(lbuff),
1537                                        "_swBrk_%d",swLabel++);
1538                               $<sym>$  =  newSymbol(lbuff,NestLevel);
1539                               /* put label in the break stack  */
1540                               STACK_PUSH(breakStack,$<sym>$);
1541                            }
1542      statement             {
1543                               /* get back the switch form the stack  */
1544                               $$ = STACK_POP(swStk)  ;
1545                               $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1546                               STACK_POP(breakStack);
1547                            }
1548         ;
1549
1550 while : WHILE  {  /* create and push the continue , break & body labels */
1551                   static int Lblnum = 0 ;
1552                   /* continue */
1553                   SNPRINTF (lbuff, sizeof(lbuff), "_whilecontinue_%d",Lblnum);
1554                   STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1555                   /* break */
1556                   SNPRINTF (lbuff, sizeof(lbuff), "_whilebreak_%d",Lblnum);
1557                   STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1558                   /* body */
1559                   SNPRINTF (lbuff, sizeof(lbuff), "_whilebody_%d",Lblnum++);
1560                   $$ = newSymbol(lbuff,NestLevel);
1561                }
1562    ;
1563
1564 do : DO {  /* create and push the continue , break & body Labels */
1565            static int Lblnum = 0 ;
1566
1567            /* continue */
1568            SNPRINTF(lbuff, sizeof(lbuff), "_docontinue_%d",Lblnum);
1569            STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1570            /* break */
1571            SNPRINTF(lbuff, sizeof(lbuff), "_dobreak_%d",Lblnum);
1572            STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1573            /* do body */
1574            SNPRINTF(lbuff, sizeof(lbuff), "_dobody_%d",Lblnum++);
1575            $$ = newSymbol (lbuff,NestLevel);
1576         }
1577    ;
1578
1579 for : FOR { /* create & push continue, break & body labels */
1580             static int Lblnum = 0 ;
1581
1582             /* continue */
1583             SNPRINTF(lbuff, sizeof(lbuff), "_forcontinue_%d",Lblnum);
1584             STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1585             /* break    */
1586             SNPRINTF(lbuff, sizeof(lbuff), "_forbreak_%d",Lblnum);
1587             STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1588             /* body */
1589             SNPRINTF(lbuff, sizeof(lbuff), "_forbody_%d",Lblnum);
1590             $$ = newSymbol(lbuff,NestLevel);
1591             /* condition */
1592             SNPRINTF(lbuff, sizeof(lbuff), "_forcond_%d",Lblnum++);
1593             STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1594           }
1595    ;
1596
1597 iteration_statement
1598    : while '(' expr ')' { seqPointNo++;}  statement
1599                          {
1600                            noLineno++ ;
1601                            $$ = createWhile ( $1, STACK_POP(continueStack),
1602                                               STACK_POP(breakStack), $3, $6 );
1603                            $$->lineno = $1->lineDef ;
1604                            noLineno-- ;
1605                          }
1606    | do statement   WHILE '(' expr ')' ';'
1607                         {
1608                           seqPointNo++;
1609                           noLineno++ ;
1610                           $$ = createDo ( $1 , STACK_POP(continueStack),
1611                                           STACK_POP(breakStack), $5, $2);
1612                           $$->lineno = $1->lineDef ;
1613                           noLineno-- ;
1614                         }
1615    | for '(' expr_opt   ';' expr_opt ';' expr_opt ')'  statement
1616                         {
1617                           noLineno++ ;
1618
1619                           /* if break or continue statement present
1620                              then create a general case loop */
1621                           if (STACK_PEEK(continueStack)->isref ||
1622                               STACK_PEEK(breakStack)->isref) {
1623                               $$ = createFor ($1, STACK_POP(continueStack),
1624                                               STACK_POP(breakStack) ,
1625                                               STACK_POP(forStack)   ,
1626                                               $3 , $5 , $7, $9 );
1627                           } else {
1628                               $$ = newNode(FOR,$9,NULL);
1629                               AST_FOR($$,trueLabel) = $1;
1630                               AST_FOR($$,continueLabel) =  STACK_POP(continueStack);
1631                               AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1632                               AST_FOR($$,condLabel)  = STACK_POP(forStack)  ;
1633                               AST_FOR($$,initExpr)   = $3;
1634                               AST_FOR($$,condExpr)   = $5;
1635                               AST_FOR($$,loopExpr)   = $7;
1636                           }
1637
1638                           noLineno-- ;
1639                         }
1640 ;
1641
1642 expr_opt
1643         :                       { $$ = NULL ; seqPointNo++; }
1644         |       expr            { $$ = $1 ; seqPointNo++; }
1645         ;
1646
1647 jump_statement
1648    : GOTO identifier ';'   {
1649                               $2->islbl = 1;
1650                               $$ = newAst_VALUE(symbolVal($2));
1651                               $$ = newNode(GOTO,$$,NULL);
1652                            }
1653    | CONTINUE ';'          {
1654        /* make sure continue is in context */
1655        if (STACK_EMPTY(continueStack) || STACK_PEEK(continueStack) == NULL) {
1656            werror(E_BREAK_CONTEXT);
1657            $$ = NULL;
1658        }
1659        else {
1660            $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));
1661            $$ = newNode(GOTO,$$,NULL);
1662            /* mark the continue label as referenced */
1663            STACK_PEEK(continueStack)->isref = 1;
1664        }
1665    }
1666    | BREAK ';'             {
1667        if (STACK_EMPTY(breakStack) || STACK_PEEK(breakStack) == NULL) {
1668            werror(E_BREAK_CONTEXT);
1669            $$ = NULL;
1670        } else {
1671            $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
1672            $$ = newNode(GOTO,$$,NULL);
1673            STACK_PEEK(breakStack)->isref = 1;
1674        }
1675    }
1676    | RETURN ';'            {
1677        seqPointNo++;
1678        if (inCritical) {
1679            werror(E_INVALID_CRITICAL);
1680            $$ = NULL;
1681        } else {
1682            $$ = newNode(RETURN,NULL,NULL);
1683        }
1684    }
1685    | RETURN expr ';'       {
1686        seqPointNo++;
1687        if (inCritical) {
1688            werror(E_INVALID_CRITICAL);
1689            $$ = NULL;
1690        } else {
1691            $$ = newNode(RETURN,NULL,$2);
1692        }
1693    }
1694    ;
1695
1696 identifier
1697    : IDENTIFIER   { $$ = newSymbol ($1,NestLevel) ; }
1698    ;
1699 %%
1700