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