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