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