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