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