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