Use 'ao-dbg' instead of 's51' to communicate with TeleMetrum
[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) ulFromVal(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) ulFromVal(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 int) ulFromVal(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 ? sym->type : NULL);
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) ulFromVal(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                            $$->bitUnnamed = 1;
930                         }
931    | declarator ':' constant_expr
932                         {
933                           unsigned int bitsize;
934                           bitsize = (unsigned int) ulFromVal(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) ulFromVal(val));
1033                                   val = constVal(lbuff);
1034                                 }
1035                               $$ = cenum = val ;
1036                            }
1037    |                       {
1038                               if (cenum)  {
1039                                  SNPRINTF(lbuff, sizeof(lbuff),
1040                                           "%d", (int) ulFromVal(cenum)+1);
1041                                  $$ = cenum = constVal(lbuff);
1042                               }
1043                               else {
1044                                  $$ = cenum = constCharVal(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             int size;
1122
1123             tval = constExprValue($3, TRUE);
1124             /* if it is not a constant then Error  */
1125             p = newLink (DECLARATOR);
1126             DCL_TYPE(p) = ARRAY;
1127
1128             if (!tval || (SPEC_SCLS(tval->etype) != S_LITERAL))
1129               {
1130                 werror(E_CONST_EXPECTED);
1131                 /* Assume a single item array to limit the cascade */
1132                 /* of additional errors. */
1133                 size = 1;
1134               }
1135             else
1136               {
1137                 if ((size = (int) ulFromVal(tval)) < 0)
1138                   {
1139                     werror(E_NEGATIVE_ARRAY_SIZE, $1->name);
1140                     size = 1;
1141                   }
1142               }
1143             DCL_ELEM(p) = size;
1144             addDecl($1, 0, p);
1145          }
1146    ;
1147
1148 function_declarator2
1149    : declarator2 '('  ')'       {  addDecl ($1,FUNCTION,NULL) ;   }
1150    | declarator2 '('            { NestLevel++ ; currBlockno++;  }
1151                      parameter_type_list ')'
1152          {
1153              sym_link *funcType;
1154
1155              addDecl ($1,FUNCTION,NULL) ;
1156
1157              funcType = $1->type;
1158              while (funcType && !IS_FUNC(funcType))
1159                funcType = funcType->next;
1160
1161              assert (funcType);
1162
1163              FUNC_HASVARARGS(funcType) = IS_VARG($4);
1164              FUNC_ARGS(funcType) = reverseVal($4);
1165
1166              /* nest level was incremented to take care of the parms  */
1167              NestLevel-- ;
1168              currBlockno--;
1169
1170              // if this was a pointer (to a function)
1171              if (!IS_FUNC($1->type))
1172                cleanUpLevel(SymbolTab,NestLevel+1);
1173
1174              $$ = $1;
1175          }
1176    | declarator2 '(' identifier_list ')'
1177          {
1178            werror(E_OLD_STYLE,$1->name) ;
1179            /* assume it returns an int */
1180            $1->type = $1->etype = newIntLink();
1181            $$ = $1 ;
1182          }
1183    ;
1184
1185 pointer
1186    : unqualified_pointer { $$ = $1 ;}
1187    | unqualified_pointer type_specifier_list
1188          {
1189              $$ = $1  ;
1190              if (IS_SPEC($2)) {
1191                  DCL_TSPEC($1) = $2;
1192                  DCL_PTR_CONST($1) = SPEC_CONST($2);
1193                  DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1194                  DCL_PTR_RESTRICT($1) = SPEC_RESTRICT($2);
1195              }
1196              else
1197                  werror (W_PTR_TYPE_INVALID);
1198          }
1199    | unqualified_pointer pointer
1200          {
1201              $$ = $1 ;
1202              $$->next = $2 ;
1203              DCL_TYPE($2)=port->unqualified_pointer;
1204          }
1205    | unqualified_pointer type_specifier_list pointer
1206          {
1207              $$ = $1 ;
1208              if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
1209                  DCL_PTR_CONST($1) = SPEC_CONST($2);
1210                  DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1211                  DCL_PTR_RESTRICT($1) = SPEC_RESTRICT($2);
1212                  switch (SPEC_SCLS($2)) {
1213                  case S_XDATA:
1214                      DCL_TYPE($3) = FPOINTER;
1215                      break;
1216                  case S_IDATA:
1217                      DCL_TYPE($3) = IPOINTER ;
1218                      break;
1219                  case S_PDATA:
1220                      DCL_TYPE($3) = PPOINTER ;
1221                      break;
1222                  case S_DATA:
1223                      DCL_TYPE($3) = POINTER ;
1224                      break;
1225                  case S_CODE:
1226                      DCL_TYPE($3) = CPOINTER ;
1227                      break;
1228                  case S_EEPROM:
1229                      DCL_TYPE($3) = EEPPOINTER;
1230                      break;
1231                  default:
1232                    // this could be just "constant"
1233                    // werror(W_PTR_TYPE_INVALID);
1234                      ;
1235                  }
1236              }
1237              else
1238                  werror (W_PTR_TYPE_INVALID);
1239              $$->next = $3 ;
1240          }
1241    ;
1242
1243 unqualified_pointer
1244    :  '*'
1245       {
1246         $$ = newLink(DECLARATOR);
1247         DCL_TYPE($$)=UPOINTER;
1248       }
1249    ;
1250
1251 type_specifier_list
1252    : type_specifier
1253    //| type_specifier_list type_specifier         {  $$ = mergeSpec ($1,$2, "type_specifier_list"); }
1254    | type_specifier_list type_specifier {
1255      /* if the decl $2 is not a specifier */
1256      /* find the spec and replace it      */
1257      if ( !IS_SPEC($2)) {
1258        sym_link *lnk = $2 ;
1259        while (lnk && !IS_SPEC(lnk->next))
1260          lnk = lnk->next;
1261        lnk->next = mergeSpec($1,lnk->next, "type_specifier_list type_specifier skipped");
1262        $$ = $2 ;
1263      }
1264      else
1265        $$ = mergeSpec($1,$2, "type_specifier_list type_specifier");
1266    }
1267    ;
1268
1269 identifier_list
1270    : identifier
1271    | identifier_list ',' identifier
1272          {
1273            $3->next = $1;
1274            $$ = $3 ;
1275          }
1276    ;
1277
1278 parameter_type_list
1279         : parameter_list
1280         | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1281         ;
1282
1283 parameter_list
1284    : parameter_declaration
1285    | parameter_list ',' parameter_declaration
1286          {
1287             $3->next = $1 ;
1288             $$ = $3 ;
1289          }
1290    ;
1291
1292 parameter_declaration
1293    : type_specifier_list declarator
1294                {
1295                   symbol *loop ;
1296                   pointerTypes($2->type,$1);
1297                   if (options.unsigned_char && SPEC_NOUN($1) == V_CHAR && !($1)->select.s.b_signed)
1298                     SPEC_USIGN($1) = 1;
1299                   addDecl ($2,0,$1);
1300                   for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1301                   addSymChain (&$2);
1302                   $$ = symbolVal($2);
1303                   ignoreTypedefType = 0;
1304                }
1305    | type_name {
1306                   $$ = newValue() ;
1307                   if (options.unsigned_char && SPEC_NOUN($1) == V_CHAR && !($1)->select.s.b_signed)
1308                     SPEC_USIGN($1) = 1;
1309                   $$->type = $1;
1310                   $$->etype = getSpec($$->type);
1311                   ignoreTypedefType = 0;
1312                }
1313    ;
1314
1315 type_name
1316    : type_specifier_list  { $$ = $1; ignoreTypedefType = 0;}
1317    | type_specifier_list abstract_declarator
1318                {
1319                  /* go to the end of the list */
1320                  sym_link *p;
1321                  pointerTypes($2,$1);
1322                  for ( p = $2 ; p && p->next ; p=p->next);
1323                  if (!p) {
1324                    werror(E_SYNTAX_ERROR, yytext);
1325                  } else {
1326                    p->next = $1 ;
1327                  }
1328                  $$ = $2 ;
1329                  ignoreTypedefType = 0;
1330                }
1331    ;
1332
1333 abstract_declarator
1334    : pointer { $$ = reverseLink($1); }
1335    | abstract_declarator2
1336    | pointer abstract_declarator2   { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;
1337           if (IS_PTR($1) && IS_FUNC($2))
1338             DCL_TYPE($1) = CPOINTER;
1339         }
1340    ;
1341
1342 abstract_declarator2
1343    : '(' abstract_declarator ')'    { $$ = $2 ; }
1344    | '[' ']'                        {
1345                                        $$ = newLink (DECLARATOR);
1346                                        DCL_TYPE($$) = ARRAY ;
1347                                        DCL_ELEM($$) = 0     ;
1348                                     }
1349    | '[' constant_expr ']'          {
1350                                        value *val ;
1351                                        $$ = newLink (DECLARATOR);
1352                                        DCL_TYPE($$) = ARRAY ;
1353                                        DCL_ELEM($$) = (int) ulFromVal(val = constExprValue($2,TRUE));
1354                                     }
1355    | abstract_declarator2 '[' ']'   {
1356                                        $$ = newLink (DECLARATOR);
1357                                        DCL_TYPE($$) = ARRAY ;
1358                                        DCL_ELEM($$) = 0     ;
1359                                        $$->next = $1 ;
1360                                     }
1361    | abstract_declarator2 '[' constant_expr ']'
1362                                     {
1363                                        value *val ;
1364                                        $$ = newLink (DECLARATOR);
1365                                        DCL_TYPE($$) = ARRAY ;
1366                                        DCL_ELEM($$) = (int) ulFromVal(val = constExprValue($3,TRUE));
1367                                        $$->next = $1 ;
1368                                     }
1369    | '(' ')'                        { $$ = NULL;}
1370    | '(' parameter_type_list ')'    { $$ = NULL;}
1371    | abstract_declarator2 '(' ')' {
1372      // $1 must be a pointer to a function
1373      sym_link *p=newLink(DECLARATOR);
1374      DCL_TYPE(p) = FUNCTION;
1375      if (!$1) {
1376        // ((void (code *) ()) 0) ()
1377        $1=newLink(DECLARATOR);
1378        DCL_TYPE($1)=CPOINTER;
1379        $$ = $1;
1380      }
1381      $1->next=p;
1382    }
1383    | abstract_declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')' {
1384        sym_link *p=newLink(DECLARATOR);
1385        DCL_TYPE(p) = FUNCTION;
1386
1387        FUNC_HASVARARGS(p) = IS_VARG($4);
1388        FUNC_ARGS(p) = reverseVal($4);
1389
1390        /* nest level was incremented to take care of the parms  */
1391        NestLevel-- ;
1392        currBlockno--;
1393        if (!$1) {
1394          /* ((void (code *) (void)) 0) () */
1395          $1=newLink(DECLARATOR);
1396          DCL_TYPE($1)=CPOINTER;
1397          $$ = $1;
1398        }
1399        $1->next=p;
1400
1401        // remove the symbol args (if any)
1402        cleanUpLevel(SymbolTab,NestLevel+1);
1403    }
1404    ;
1405
1406 initializer
1407    : assignment_expr                { $$ = newiList(INIT_NODE,$1); }
1408    | '{'  initializer_list '}'      { $$ = newiList(INIT_DEEP,revinit($2)); }
1409    | '{'  initializer_list ',' '}'  { $$ = newiList(INIT_DEEP,revinit($2)); }
1410    ;
1411
1412 initializer_list
1413    : initializer
1414    | initializer_list ',' initializer  {  $3->next = $1; $$ = $3; }
1415    ;
1416
1417 statement
1418    : labeled_statement
1419    | compound_statement
1420    | expression_statement
1421    | selection_statement
1422    | iteration_statement
1423    | jump_statement
1424    | critical_statement
1425    | INLINEASM  ';'      {
1426                             ast *ex;
1427                             seqPointNo++;
1428                             ex = newNode(INLINEASM,NULL,NULL);
1429                             ex->values.inlineasm = strdup($1);
1430                             seqPointNo++;
1431                             $$ = ex;
1432                          }
1433    ;
1434
1435 critical
1436    : CRITICAL   {
1437                    inCritical++;
1438                    STACK_PUSH(continueStack,NULL);
1439                    STACK_PUSH(breakStack,NULL);
1440                    $$ = NULL;
1441                 }
1442    ;
1443
1444 critical_statement
1445    : critical statement  {
1446                    STACK_POP(breakStack);
1447                    STACK_POP(continueStack);
1448                    inCritical--;
1449                    $$ = newNode(CRITICAL,$2,NULL);
1450                 }
1451    ;
1452
1453 labeled_statement
1454 //   : identifier ':' statement          {  $$ = createLabel($1,$3);  }
1455    : identifier ':'                    {  $$ = createLabel($1,NULL);
1456                                           $1->isitmp = 0;  }
1457    | CASE constant_expr ':'
1458      {
1459        if (STACK_EMPTY(swStk))
1460          $$ = createCase(NULL,$2,NULL);
1461        else
1462          $$ = createCase(STACK_PEEK(swStk),$2,NULL);
1463      }
1464    | DEFAULT { $<asts>$ = newNode(DEFAULT,NULL,NULL); } ':'
1465      {
1466        if (STACK_EMPTY(swStk))
1467          $$ = createDefault(NULL,$<asts>2,NULL);
1468        else
1469          $$ = createDefault(STACK_PEEK(swStk),$<asts>2,NULL);
1470      }
1471    ;
1472
1473 start_block : '{'
1474               {
1475                 STACK_PUSH(blockNum,currBlockno);
1476                 currBlockno = ++blockNo ;
1477                 ignoreTypedefType = 0;
1478               }
1479             ;
1480
1481 end_block   : '}'     { currBlockno = STACK_POP(blockNum); }
1482             ;
1483
1484 compound_statement
1485    : start_block end_block                    { $$ = createBlock(NULL, NULL); }
1486    | start_block statement_list end_block     { $$ = createBlock(NULL, $2); }
1487    | start_block declaration_list end_block   { $$ = createBlock($2, NULL); }
1488    | start_block
1489           declaration_list statement_list
1490      end_block                                {$$ = createBlock($2, $3); }
1491    | error ';'                                { $$ = NULL ; }
1492    ;
1493
1494 declaration_list
1495    : declaration
1496      {
1497        /* if this is typedef declare it immediately */
1498        if ( $1 && IS_TYPEDEF($1->etype)) {
1499          allocVariables ($1);
1500          $$ = NULL ;
1501        }
1502        else
1503          $$ = $1 ;
1504        ignoreTypedefType = 0;
1505        addSymChain(&$1);
1506      }
1507
1508    | declaration_list declaration
1509      {
1510        symbol   *sym;
1511
1512        /* if this is a typedef */
1513        if ($2 && IS_TYPEDEF($2->etype)) {
1514          allocVariables ($2);
1515          $$ = $1 ;
1516        }
1517        else {
1518                                 /* get to the end of the previous decl */
1519          if ( $1 ) {
1520            $$ = sym = $1 ;
1521            while (sym->next)
1522              sym = sym->next ;
1523            sym->next = $2;
1524          }
1525          else
1526            $$ = $2 ;
1527        }
1528        ignoreTypedefType = 0;
1529        addSymChain(&$2);
1530      }
1531    ;
1532
1533 statement_list
1534    : statement
1535    | statement_list statement          {  $$ = newNode(NULLOP,$1,$2) ;}
1536    ;
1537
1538 expression_statement
1539    : ';'                { $$ = NULL;}
1540    | expr ';'           { $$ = $1; seqPointNo++;}
1541    ;
1542
1543 else_statement
1544    :  ELSE  statement   { $$ = $2  ; }
1545    |                    { $$ = NULL;}
1546    ;
1547
1548
1549 selection_statement
1550    : IF '(' expr ')' { seqPointNo++;} statement else_statement
1551                            {
1552                               noLineno++ ;
1553                               $$ = createIf ($3, $6, $7 );
1554                               $$->lineno = $3->lineno;
1555                               $$->filename = $3->filename;
1556                               noLineno--;
1557                            }
1558    | SWITCH '(' expr ')'   {
1559                               ast *ex ;
1560                               static   int swLabel = 0 ;
1561
1562                               seqPointNo++;
1563                               /* create a node for expression  */
1564                               ex = newNode(SWITCH,$3,NULL);
1565                               STACK_PUSH(swStk,ex);   /* save it in the stack */
1566                               ex->values.switchVals.swNum = swLabel ;
1567
1568                               /* now create the label */
1569                               SNPRINTF(lbuff, sizeof(lbuff),
1570                                        "_swBrk_%d",swLabel++);
1571                               $<sym>$  =  newSymbol(lbuff,NestLevel);
1572                               /* put label in the break stack  */
1573                               STACK_PUSH(breakStack,$<sym>$);
1574                            }
1575      statement             {
1576                               /* get back the switch form the stack  */
1577                               $$ = STACK_POP(swStk)  ;
1578                               $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1579                               STACK_POP(breakStack);
1580                            }
1581         ;
1582
1583 while : WHILE  {  /* create and push the continue , break & body labels */
1584                   static int Lblnum = 0 ;
1585                   /* continue */
1586                   SNPRINTF (lbuff, sizeof(lbuff), "_whilecontinue_%d",Lblnum);
1587                   STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1588                   /* break */
1589                   SNPRINTF (lbuff, sizeof(lbuff), "_whilebreak_%d",Lblnum);
1590                   STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1591                   /* body */
1592                   SNPRINTF (lbuff, sizeof(lbuff), "_whilebody_%d",Lblnum++);
1593                   $$ = newSymbol(lbuff,NestLevel);
1594                }
1595    ;
1596
1597 do : DO {  /* create and push the continue , break & body Labels */
1598            static int Lblnum = 0 ;
1599
1600            /* continue */
1601            SNPRINTF(lbuff, sizeof(lbuff), "_docontinue_%d",Lblnum);
1602            STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1603            /* break */
1604            SNPRINTF(lbuff, sizeof(lbuff), "_dobreak_%d",Lblnum);
1605            STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1606            /* do body */
1607            SNPRINTF(lbuff, sizeof(lbuff), "_dobody_%d",Lblnum++);
1608            $$ = newSymbol (lbuff,NestLevel);
1609         }
1610    ;
1611
1612 for : FOR { /* create & push continue, break & body labels */
1613             static int Lblnum = 0 ;
1614
1615             /* continue */
1616             SNPRINTF(lbuff, sizeof(lbuff), "_forcontinue_%d",Lblnum);
1617             STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1618             /* break    */
1619             SNPRINTF(lbuff, sizeof(lbuff), "_forbreak_%d",Lblnum);
1620             STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1621             /* body */
1622             SNPRINTF(lbuff, sizeof(lbuff), "_forbody_%d",Lblnum);
1623             $$ = newSymbol(lbuff,NestLevel);
1624             /* condition */
1625             SNPRINTF(lbuff, sizeof(lbuff), "_forcond_%d",Lblnum++);
1626             STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1627           }
1628    ;
1629
1630 iteration_statement
1631    : while '(' expr ')' { seqPointNo++;}  statement
1632                          {
1633                            noLineno++ ;
1634                            $$ = createWhile ( $1, STACK_POP(continueStack),
1635                                               STACK_POP(breakStack), $3, $6 );
1636                            $$->lineno = $1->lineDef;
1637                            $$->filename = $1->fileDef;
1638                            noLineno-- ;
1639                          }
1640    | do statement   WHILE '(' expr ')' ';'
1641                         {
1642                           seqPointNo++;
1643                           noLineno++ ;
1644                           $$ = createDo ( $1 , STACK_POP(continueStack),
1645                                           STACK_POP(breakStack), $5, $2);
1646                           $$->lineno = $1->lineDef;
1647                           $$->filename = $1->fileDef;
1648                           noLineno-- ;
1649                         }
1650    | for '(' expr_opt   ';' expr_opt ';' expr_opt ')'  statement
1651                         {
1652                           noLineno++ ;
1653
1654                           /* if break or continue statement present
1655                              then create a general case loop */
1656                           if (STACK_PEEK(continueStack)->isref ||
1657                               STACK_PEEK(breakStack)->isref) {
1658                               $$ = createFor ($1, STACK_POP(continueStack),
1659                                               STACK_POP(breakStack) ,
1660                                               STACK_POP(forStack)   ,
1661                                               $3 , $5 , $7, $9 );
1662                           } else {
1663                               $$ = newNode(FOR,$9,NULL);
1664                               AST_FOR($$,trueLabel) = $1;
1665                               AST_FOR($$,continueLabel) =  STACK_POP(continueStack);
1666                               AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1667                               AST_FOR($$,condLabel)  = STACK_POP(forStack)  ;
1668                               AST_FOR($$,initExpr)   = $3;
1669                               AST_FOR($$,condExpr)   = $5;
1670                               AST_FOR($$,loopExpr)   = $7;
1671                           }
1672
1673                           noLineno-- ;
1674                         }
1675 ;
1676
1677 expr_opt
1678         :                       { $$ = NULL ; seqPointNo++; }
1679         |       expr            { $$ = $1 ; seqPointNo++; }
1680         ;
1681
1682 jump_statement
1683    : GOTO identifier ';'   {
1684                               $2->islbl = 1;
1685                               $$ = newAst_VALUE(symbolVal($2));
1686                               $$ = newNode(GOTO,$$,NULL);
1687                            }
1688    | CONTINUE ';'          {
1689        /* make sure continue is in context */
1690        if (STACK_EMPTY(continueStack) || STACK_PEEK(continueStack) == NULL) {
1691            werror(E_BREAK_CONTEXT);
1692            $$ = NULL;
1693        }
1694        else {
1695            $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));
1696            $$ = newNode(GOTO,$$,NULL);
1697            /* mark the continue label as referenced */
1698            STACK_PEEK(continueStack)->isref = 1;
1699        }
1700    }
1701    | BREAK ';'             {
1702        if (STACK_EMPTY(breakStack) || STACK_PEEK(breakStack) == NULL) {
1703            werror(E_BREAK_CONTEXT);
1704            $$ = NULL;
1705        } else {
1706            $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
1707            $$ = newNode(GOTO,$$,NULL);
1708            STACK_PEEK(breakStack)->isref = 1;
1709        }
1710    }
1711    | RETURN ';'            {
1712        seqPointNo++;
1713        if (inCritical) {
1714            werror(E_INVALID_CRITICAL);
1715            $$ = NULL;
1716        } else {
1717            $$ = newNode(RETURN,NULL,NULL);
1718        }
1719    }
1720    | RETURN expr ';'       {
1721        seqPointNo++;
1722        if (inCritical) {
1723            werror(E_INVALID_CRITICAL);
1724            $$ = NULL;
1725        } else {
1726            $$ = newNode(RETURN,NULL,$2);
1727        }
1728    }
1729    ;
1730
1731 identifier
1732    : IDENTIFIER   { $$ = newSymbol ($1,NestLevel) ; }
1733    ;
1734 %%