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