* sim/ucsim/configure.in,
[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                SPEC_BLEN($$) = 1;
706                SPEC_BSTR($$) = 0;
707                ignoreTypedefType = 1;
708             }
709    |  sfr_attributes
710    ;
711
712 sfr_attributes
713    : SFR    {
714                $$ = newLink(SPECIFIER) ;
715                FUNC_REGBANK($$) = 0;
716                SPEC_NOUN($$)    = V_CHAR;
717                SPEC_SCLS($$)    = S_SFR ;
718                SPEC_USIGN($$)   = 1 ;
719                ignoreTypedefType = 1;
720             }
721    | SFR BANKED {
722                $$ = newLink(SPECIFIER) ;
723                FUNC_REGBANK($$) = 1;
724                SPEC_NOUN($$)    = V_CHAR;
725                SPEC_SCLS($$)    = S_SFR ;
726                SPEC_USIGN($$)   = 1 ;
727                ignoreTypedefType = 1;
728             }
729    ;
730
731 struct_or_union_specifier
732    : struct_or_union opt_stag
733         {
734            if (!$2->type)
735              {
736                $2->type = $1;
737              }
738            else
739              {
740                if ($2->type != $1)
741                  werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union");
742              }
743
744         }
745            '{' struct_declaration_list '}'
746         {
747            structdef *sdef ;
748            symbol *sym, *dsym;
749
750            // check for errors in structure members
751            for (sym=$5; sym; sym=sym->next) {
752              if (IS_ABSOLUTE(sym->etype)) {
753                werrorfl(sym->fileDef, sym->lineDef, E_NOT_ALLOWED, "'at'");
754                SPEC_ABSA(sym->etype) = 0;
755              }
756              if (IS_SPEC(sym->etype) && SPEC_SCLS(sym->etype)) {
757                werrorfl(sym->fileDef, sym->lineDef, E_NOT_ALLOWED, "storage class");
758                printTypeChainRaw (sym->type,NULL);
759                SPEC_SCLS(sym->etype) = 0;
760              }
761              for (dsym=sym->next; dsym; dsym=dsym->next) {
762                if (*dsym->name && strcmp(sym->name, dsym->name)==0) {
763                  werrorfl(sym->fileDef, sym->lineDef, E_DUPLICATE_MEMBER, 
764                         $1==STRUCT ? "struct" : "union", sym->name);
765                  werrorfl(dsym->fileDef, dsym->lineDef, E_PREVIOUS_DEF);
766                }
767              }
768            }
769
770            /* Create a structdef   */      
771            sdef = $2 ;
772            sdef->fields   = reverseSyms($5) ;   /* link the fields */
773            sdef->size  = compStructSize($1,sdef);   /* update size of  */
774            promoteAnonStructs ($1, sdef);
775            
776            /* Create the specifier */
777            $$ = newLink (SPECIFIER) ;
778            SPEC_NOUN($$) = V_STRUCT;
779            SPEC_STRUCT($$)= sdef ;
780         }
781    | struct_or_union stag
782          {
783             $$ = newLink(SPECIFIER) ;
784             SPEC_NOUN($$) = V_STRUCT;
785             SPEC_STRUCT($$) = $2;
786
787            if (!$2->type)
788              {
789                $2->type = $1;
790              }
791            else
792              {
793                if ($2->type != $1)
794                  werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union");
795              }
796          }
797    ;
798
799 struct_or_union
800    : STRUCT          { $$ = STRUCT ; }
801    | UNION           { $$ = UNION  ; }
802    ;
803
804 opt_stag
805 : stag
806 |  {  /* synthesize a name add to structtable */
807      $$ = newStruct(genSymName(NestLevel)) ;
808      $$->level = NestLevel ;
809      addSym (StructTab, $$, $$->tag,$$->level,currBlockno, 0);
810 };
811
812 stag
813 :  identifier  {  /* add name to structure table */
814      $$ = findSymWithBlock (StructTab,$1,currBlockno);
815      if (! $$ ) {
816        $$ = newStruct($1->name) ;
817        $$->level = NestLevel ;
818        addSym (StructTab, $$, $$->tag,$$->level,currBlockno,0);
819      }
820 };
821
822
823 struct_declaration_list
824    : struct_declaration
825    | struct_declaration_list struct_declaration
826        {
827            symbol *sym=$2;
828
829            /* go to the end of the chain */
830            while (sym->next) sym=sym->next;
831            sym->next = $1 ;
832          
833            $$ = $2;
834        }
835    ;
836
837 struct_declaration
838    : type_specifier_list struct_declarator_list ';'
839        {
840            /* add this type to all the symbols */
841            symbol *sym ;
842            for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
843                sym_link *btype = copyLinkChain($1);
844                
845                /* make the symbol one level up */
846                sym->level-- ;
847
848                pointerTypes(sym->type,btype);
849                if (!sym->type) {
850                    sym->type = btype;
851                    sym->etype = getSpec(sym->type);
852                }
853                else
854                  addDecl (sym,0,btype);
855                /* make sure the type is complete and sane */
856                checkTypeSanity(sym->etype, sym->name);
857            }
858            ignoreTypedefType = 0;
859            $$ = $2;
860        }
861    ;
862
863 struct_declarator_list
864    : struct_declarator
865    | struct_declarator_list ',' struct_declarator
866        {
867            $3->next  = $1 ;
868            $$ = $3 ;
869        }
870    ;
871
872 struct_declarator
873    : declarator 
874    | ':' constant_expr  {
875                            int bitsize;
876                            $$ = newSymbol (genSymName(NestLevel),NestLevel) ; 
877                            bitsize= (int) floatFromVal(constExprValue($2,TRUE));
878                            if (bitsize > (port->s.int_size * 8)) {
879                              bitsize = port->s.int_size * 8;
880                              werror(E_BITFLD_SIZE, bitsize);
881                            }
882                            if (!bitsize)
883                              bitsize = BITVAR_PAD;
884                            $$->bitVar = bitsize;
885                         }                        
886    | declarator ':' constant_expr 
887                         {
888                           int bitsize;
889                           bitsize= (int) floatFromVal(constExprValue($3,TRUE));
890                           if (bitsize > (port->s.int_size * 8)) {
891                             bitsize = port->s.int_size * 8;
892                             werror(E_BITFLD_SIZE, bitsize);
893                           }
894                           if (!bitsize) {
895                             $$ = newSymbol (genSymName(NestLevel),NestLevel) ; 
896                             $$->bitVar = BITVAR_PAD;
897                             werror(W_BITFLD_NAMED);
898                           }
899                           else
900                             $1->bitVar = bitsize;
901                         }
902    | { $$ = newSymbol ("", NestLevel) ; }
903    
904    ;
905
906 enum_specifier
907    : ENUM            '{' enumerator_list '}' {
908            $$ = newEnumType ($3);       //copyLinkChain(cenum->type);
909            SPEC_SCLS(getSpec($$)) = 0;
910          }
911
912    | ENUM identifier '{' enumerator_list '}' {
913      symbol *csym ;
914      sym_link *enumtype;
915
916      csym=findSym(enumTab,$2,$2->name);
917      if ((csym && csym->level == $2->level))
918        {
919          werrorfl($2->fileDef, $2->lineDef, E_DUPLICATE_TYPEDEF,csym->name);
920          werrorfl(csym->fileDef, csym->lineDef, E_PREVIOUS_DEF);
921        }
922      
923      enumtype = newEnumType ($4);       //copyLinkChain(cenum->type);
924      SPEC_SCLS(getSpec(enumtype)) = 0;
925      $2->type = enumtype;
926      
927      /* add this to the enumerator table */
928      if (!csym)
929        addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
930      $$ = copyLinkChain(enumtype);
931    }
932    | ENUM identifier                         {
933      symbol *csym ;
934      
935      /* check the enumerator table */
936      if ((csym = findSym(enumTab,$2,$2->name)))
937        $$ = copyLinkChain(csym->type);
938      else  {
939        $$ = newLink(SPECIFIER) ;
940        SPEC_NOUN($$) = V_INT   ;
941      }
942    }
943    ;
944
945 enumerator_list
946    : enumerator
947    | enumerator_list ',' {
948                          }
949    | enumerator_list ',' enumerator
950      {
951        symbol *dsym;
952        
953        for (dsym=$1; dsym; dsym=dsym->next)
954          {
955            if (strcmp($3->name, dsym->name)==0)
956              {
957                werrorfl($3->fileDef, $3->lineDef, E_DUPLICATE_MEMBER, "enum", $3->name);
958                werrorfl(dsym->fileDef, dsym->lineDef, E_PREVIOUS_DEF);
959              }
960          }
961        
962        $3->next = $1 ;
963        $$ = $3  ;
964      }
965    ;
966
967 enumerator
968    : identifier opt_assign_expr  
969      {
970        /* make the symbol one level up */
971        $1->level-- ;
972        $1->type = copyLinkChain($2->type); 
973        $1->etype= getSpec($1->type);
974        SPEC_ENUM($1->etype) = 1;
975        $$ = $1 ;
976        // do this now, so we can use it for the next enums in the list
977        addSymChain($1);
978      }
979    ;
980
981 opt_assign_expr
982    :  '='   constant_expr  {
983                               value *val ;
984
985                               val = constExprValue($2,TRUE);
986                               if (!IS_INT(val->type) && !IS_CHAR(val->type))
987                                 {
988                                   werror(E_ENUM_NON_INTEGER);
989                                   SNPRINTF(lbuff, sizeof(lbuff), 
990                                           "%d",(int) floatFromVal(val));
991                                   val = constVal(lbuff);
992                                 }
993                               $$ = cenum = val ;
994                            }                           
995    |                       {                              
996                               if (cenum)  {
997                                  SNPRINTF(lbuff, sizeof(lbuff), 
998                                           "%d",(int) floatFromVal(cenum)+1);
999                                  $$ = cenum = constVal(lbuff);
1000                               }
1001                               else {
1002                                  SNPRINTF(lbuff, sizeof(lbuff), 
1003                                           "%d",0);
1004                                  $$ = cenum = constVal(lbuff);
1005                               }   
1006                            }
1007    ;
1008
1009 declarator
1010    : declarator3                        { $$ = $1 ; } 
1011    | pointer declarator3
1012          {
1013              addDecl ($2,0,reverseLink($1));
1014              $$ = $2 ;
1015          }
1016    ;
1017
1018 declarator3
1019    : declarator2_function_attributes    { $$ = $1 ; }
1020    | declarator2                        { $$ = $1 ; }
1021    ;
1022
1023 function_declarator
1024    : declarator2_function_attributes    { $$ = $1; }
1025    | pointer declarator2_function_attributes
1026          {
1027              addDecl ($2,0,reverseLink($1));
1028              $$ = $2 ;
1029          }
1030    ;
1031    
1032 declarator2_function_attributes
1033    : function_declarator2                 { $$ = $1 ; } 
1034    | function_declarator2 function_attribute  { 
1035            // copy the functionAttributes (not the args and hasVargs !!)
1036            struct value *args;
1037            unsigned hasVargs;
1038            sym_link *funcType=$1->type;
1039
1040            while (funcType && !IS_FUNC(funcType))
1041              funcType = funcType->next;
1042            
1043            if (!funcType)
1044              werror (E_FUNC_ATTR);
1045            else
1046              {
1047                args=FUNC_ARGS(funcType);
1048                hasVargs=FUNC_HASVARARGS(funcType);
1049
1050                memcpy (&funcType->funcAttrs, &$2->funcAttrs, 
1051                    sizeof($2->funcAttrs));
1052
1053                FUNC_ARGS(funcType)=args;
1054                FUNC_HASVARARGS(funcType)=hasVargs;
1055
1056                // just to be sure
1057                memset (&$2->funcAttrs, 0,
1058                    sizeof($2->funcAttrs));
1059            
1060                addDecl ($1,0,$2); 
1061              }
1062    }     
1063    ;
1064
1065 declarator2
1066    : identifier
1067    | '(' declarator ')'     { $$ = $2; }
1068    | declarator3 '[' ']'
1069          {
1070             sym_link   *p;
1071
1072             p = newLink (DECLARATOR);
1073             DCL_TYPE(p) = ARRAY ;
1074             DCL_ELEM(p) = 0     ;
1075             addDecl($1,0,p);
1076          }
1077    | declarator3 '[' constant_expr ']'
1078          {
1079             sym_link   *p ;
1080                         value *tval;
1081                         
1082             tval = constExprValue($3,TRUE);
1083             /* if it is not a constant then Error  */
1084             p = newLink (DECLARATOR);
1085             DCL_TYPE(p) = ARRAY ;
1086             if ( !tval || (SPEC_SCLS(tval->etype) != S_LITERAL)) {
1087                werror(E_CONST_EXPECTED) ;
1088                /* Assume a single item array to limit the cascade */
1089                /* of additional errors. */
1090                DCL_ELEM(p) = 1;
1091             }
1092             else {
1093                DCL_ELEM(p) = (int) floatFromVal(tval) ;
1094             }                           
1095             addDecl($1,0,p);
1096          }
1097    ;
1098
1099 function_declarator2
1100    : declarator2 '('  ')'       {  addDecl ($1,FUNCTION,NULL) ;   }
1101    | declarator2 '('            { NestLevel++ ; currBlockno++;  }
1102                      parameter_type_list ')'
1103          {
1104              sym_link *funcType;
1105            
1106              addDecl ($1,FUNCTION,NULL) ;
1107
1108              funcType = $1->type;
1109              while (funcType && !IS_FUNC(funcType))
1110                funcType = funcType->next;
1111            
1112              assert (funcType);
1113              
1114              FUNC_HASVARARGS(funcType) = IS_VARG($4);
1115              FUNC_ARGS(funcType) = reverseVal($4);
1116              
1117              /* nest level was incremented to take care of the parms  */
1118              NestLevel-- ;
1119              currBlockno--;
1120
1121              // if this was a pointer (to a function)
1122              if (!IS_FUNC($1->type))
1123                cleanUpLevel(SymbolTab,NestLevel+1);
1124              
1125              $$ = $1;
1126          }
1127    | declarator2 '(' parameter_identifier_list ')'
1128          {         
1129            werror(E_OLD_STYLE,$1->name) ;         
1130            /* assume it returns an int */
1131            $1->type = $1->etype = newIntLink();
1132            $$ = $1 ;
1133          }
1134    ;
1135    
1136 pointer
1137    : unqualified_pointer { $$ = $1 ;}
1138    | unqualified_pointer type_specifier_list   
1139          {
1140              $$ = $1  ;
1141              if (IS_SPEC($2)) {
1142                  DCL_TSPEC($1) = $2;
1143                  DCL_PTR_CONST($1) = SPEC_CONST($2);
1144                  DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1145              }
1146              else
1147                  werror (W_PTR_TYPE_INVALID);
1148          }
1149    | unqualified_pointer pointer         
1150          {
1151              $$ = $1 ;          
1152              $$->next = $2 ;
1153              DCL_TYPE($2)=port->unqualified_pointer;
1154          }
1155    | unqualified_pointer type_specifier_list pointer
1156          {
1157              $$ = $1 ;               
1158              if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
1159                  DCL_PTR_CONST($1) = SPEC_CONST($2);
1160                  DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1161                  switch (SPEC_SCLS($2)) {
1162                  case S_XDATA:
1163                      DCL_TYPE($3) = FPOINTER;
1164                      break;
1165                  case S_IDATA:
1166                      DCL_TYPE($3) = IPOINTER ;
1167                      break;
1168                  case S_PDATA:
1169                      DCL_TYPE($3) = PPOINTER ;
1170                      break;
1171                  case S_DATA:
1172                      DCL_TYPE($3) = POINTER ;
1173                      break;
1174                  case S_CODE:
1175                      DCL_TYPE($3) = CPOINTER ;
1176                      break;
1177                  case S_EEPROM:
1178                      DCL_TYPE($3) = EEPPOINTER;
1179                      break;
1180                  default:
1181                    // this could be just "constant" 
1182                    // werror(W_PTR_TYPE_INVALID);
1183                      ;
1184                  }
1185              }
1186              else 
1187                  werror (W_PTR_TYPE_INVALID);
1188              $$->next = $3 ;
1189          }
1190    ;
1191
1192 unqualified_pointer
1193    :  '*'   
1194       {
1195         $$ = newLink(DECLARATOR);
1196         DCL_TYPE($$)=UPOINTER;
1197       }
1198    ;
1199
1200 type_specifier_list
1201    : type_specifier
1202    //| type_specifier_list type_specifier         {  $$ = mergeSpec ($1,$2, "type_specifier_list"); }
1203    | type_specifier_list type_specifier {
1204      /* if the decl $2 is not a specifier */
1205      /* find the spec and replace it      */
1206      if ( !IS_SPEC($2)) {
1207        sym_link *lnk = $2 ;
1208        while (lnk && !IS_SPEC(lnk->next))
1209          lnk = lnk->next;
1210        lnk->next = mergeSpec($1,lnk->next, "type_specifier_list type_specifier skipped");
1211        $$ = $2 ;
1212      }
1213      else
1214        $$ = mergeSpec($1,$2, "type_specifier_list type_specifier");
1215    }
1216    ;
1217
1218 parameter_identifier_list
1219    : identifier_list
1220    | identifier_list ',' ELIPSIS
1221    ;
1222
1223 identifier_list
1224    : identifier
1225    | identifier_list ',' identifier         
1226          {            
1227            $3->next = $1;
1228            $$ = $3 ;
1229          }
1230    ;
1231
1232 parameter_type_list
1233         : parameter_list
1234         | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1235         ;
1236
1237 parameter_list
1238    : parameter_declaration
1239    | parameter_list ',' parameter_declaration
1240          {
1241             $3->next = $1 ;
1242             $$ = $3 ;
1243          }
1244    ;
1245
1246 parameter_declaration
1247    : type_specifier_list declarator 
1248                {        
1249                   symbol *loop ;
1250                   pointerTypes($2->type,$1);
1251                   addDecl ($2,0,$1);              
1252                   for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1253                   addSymChain ($2);
1254                   $$ = symbolVal($2);
1255                   ignoreTypedefType = 0;
1256                }
1257    | type_name { 
1258                   $$ = newValue() ; 
1259                   $$->type = $1;
1260                   $$->etype = getSpec($$->type);
1261                   ignoreTypedefType = 0;
1262                }
1263    ;
1264
1265 type_name
1266    : type_specifier_list  { $$ = $1; ignoreTypedefType = 0;}
1267    | type_specifier_list abstract_declarator 
1268                {
1269                  /* go to the end of the list */
1270                  sym_link *p;
1271                  pointerTypes($2,$1);
1272                  for ( p = $2 ; p && p->next ; p=p->next);
1273                  if (!p) {
1274                    werror(E_SYNTAX_ERROR, yytext);
1275                  } else {
1276                    p->next = $1 ;
1277                  }
1278                  $$ = $2 ;
1279                  ignoreTypedefType = 0;
1280                }   
1281    ;
1282
1283 abstract_declarator
1284    : pointer { $$ = reverseLink($1); }
1285    | abstract_declarator2
1286    | pointer abstract_declarator2   { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;
1287           if (IS_PTR($1) && IS_FUNC($2))
1288             DCL_TYPE($1) = CPOINTER;
1289         } 
1290    ;
1291
1292 abstract_declarator2
1293    : '(' abstract_declarator ')'    { $$ = $2 ; }
1294    | '[' ']'                        {             
1295                                        $$ = newLink (DECLARATOR);
1296                                        DCL_TYPE($$) = ARRAY ;
1297                                        DCL_ELEM($$) = 0     ;
1298                                     }
1299    | '[' constant_expr ']'          { 
1300                                        value *val ;
1301                                        $$ = newLink (DECLARATOR);
1302                                        DCL_TYPE($$) = ARRAY ;
1303                                        DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1304                                     }
1305    | abstract_declarator2 '[' ']'   {
1306                                        $$ = newLink (DECLARATOR);
1307                                        DCL_TYPE($$) = ARRAY ;
1308                                        DCL_ELEM($$) = 0     ;
1309                                        $$->next = $1 ;
1310                                     }
1311    | abstract_declarator2 '[' constant_expr ']'
1312                                     {
1313                                        value *val ;
1314                                        $$ = newLink (DECLARATOR);
1315                                        DCL_TYPE($$) = ARRAY ;
1316                                        DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1317                                        $$->next = $1 ;
1318                                     }
1319    | '(' ')'                        { $$ = NULL;}
1320    | '(' parameter_type_list ')'    { $$ = NULL;}   
1321    | abstract_declarator2 '(' ')' {
1322      // $1 must be a pointer to a function
1323      sym_link *p=newLink(DECLARATOR);
1324      DCL_TYPE(p) = FUNCTION;
1325      if (!$1) {
1326        // ((void (code *) ()) 0) ()
1327        $1=newLink(DECLARATOR);
1328        DCL_TYPE($1)=CPOINTER;
1329        $$ = $1;
1330      }
1331      $1->next=p;
1332    }
1333    | abstract_declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')' {
1334        sym_link *p=newLink(DECLARATOR);
1335        DCL_TYPE(p) = FUNCTION;
1336            
1337        FUNC_HASVARARGS(p) = IS_VARG($4);
1338        FUNC_ARGS(p) = reverseVal($4);
1339              
1340        /* nest level was incremented to take care of the parms  */
1341        NestLevel-- ;
1342        currBlockno--;
1343        p->next = $1;
1344        $$ = p;
1345
1346        // remove the symbol args (if any)
1347        cleanUpLevel(SymbolTab,NestLevel+1);
1348    }
1349    ;
1350
1351 initializer
1352    : assignment_expr                { $$ = newiList(INIT_NODE,$1); }
1353    | '{'  initializer_list '}'      { $$ = newiList(INIT_DEEP,revinit($2)); }
1354    | '{'  initializer_list ',' '}'  { $$ = newiList(INIT_DEEP,revinit($2)); }
1355    ;
1356
1357 initializer_list
1358    : initializer
1359    | initializer_list ',' initializer  {  $3->next = $1; $$ = $3; }
1360    ;
1361
1362 statement
1363    : labeled_statement
1364    | compound_statement
1365    | expression_statement
1366    | selection_statement
1367    | iteration_statement
1368    | jump_statement
1369    | critical_statement
1370    | INLINEASM  ';'      {
1371                             ast *ex;
1372                             seqPointNo++;
1373                             ex = newNode(INLINEASM,NULL,NULL);
1374                             ex->values.inlineasm = strdup($1);
1375                             seqPointNo++;
1376                             $$ = ex;
1377                          } 
1378    ;
1379
1380 critical
1381    : CRITICAL   {
1382                    inCritical++;
1383                    STACK_PUSH(continueStack,NULL);
1384                    STACK_PUSH(breakStack,NULL);
1385                    $$ = NULL;
1386                 }
1387    ;
1388    
1389 critical_statement
1390    : critical statement  {
1391                    STACK_POP(breakStack);
1392                    STACK_POP(continueStack);
1393                    inCritical--;
1394                    $$ = newNode(CRITICAL,$2,NULL);
1395                 }
1396    ;
1397       
1398 labeled_statement
1399 //   : identifier ':' statement          {  $$ = createLabel($1,$3);  }   
1400    : identifier ':'                    {  $$ = createLabel($1,NULL);  }   
1401    | CASE constant_expr ':' statement
1402      {
1403        if (STACK_EMPTY(swStk))
1404          $$ = createCase(NULL,$2,$4);
1405        else
1406          $$ = createCase(STACK_PEEK(swStk),$2,$4);
1407      }
1408    | DEFAULT { $<asts>$ = newNode(DEFAULT,NULL,NULL); } ':' statement
1409      {
1410        if (STACK_EMPTY(swStk))
1411          $$ = createDefault(NULL,$<asts>2,$4);
1412        else
1413          $$ = createDefault(STACK_PEEK(swStk),$<asts>2,$4);
1414      }
1415    ;
1416
1417 start_block : '{'
1418               {
1419                 STACK_PUSH(blockNum,currBlockno);
1420                 currBlockno = ++blockNo ;
1421                 ignoreTypedefType = 0;
1422               }
1423             ;
1424
1425 end_block   : '}'     { currBlockno = STACK_POP(blockNum); }           
1426             ;
1427
1428 compound_statement
1429    : start_block end_block                    { $$ = createBlock(NULL,NULL); }
1430    | start_block statement_list end_block     { $$ = createBlock(NULL,$2) ;  }
1431    | start_block 
1432           declaration_list                    { addSymChain($2); }
1433      end_block                                { $$ = createBlock($2,NULL) ;  }
1434    | start_block 
1435           declaration_list                    {  addSymChain ($2); }
1436           statement_list   
1437      end_block                                {$$ = createBlock($2,$4)   ;  }
1438    | error ';'                                { $$ = NULL ; }
1439    ;
1440
1441 declaration_list
1442    : declaration        
1443      {
1444        /* if this is typedef declare it immediately */
1445        if ( $1 && IS_TYPEDEF($1->etype)) {
1446          allocVariables ($1);
1447          $$ = NULL ;
1448        }
1449        else
1450          $$ = $1 ;
1451        ignoreTypedefType = 0;
1452      }
1453
1454    | declaration_list declaration
1455      {
1456        symbol   *sym;
1457        
1458        /* if this is a typedef */
1459        if ($2 && IS_TYPEDEF($2->etype)) {
1460          allocVariables ($2);
1461          $$ = $1 ;
1462        }
1463        else {
1464                                 /* get to the end of the previous decl */
1465          if ( $1 ) {
1466            $$ = sym = $1 ;
1467            while (sym->next)
1468              sym = sym->next ;
1469            sym->next = $2;
1470          } 
1471          else
1472            $$ = $2 ;
1473        }
1474        ignoreTypedefType = 0;
1475      }
1476    ;
1477
1478 statement_list
1479    : statement
1480    | statement_list statement          {  $$ = newNode(NULLOP,$1,$2) ;}
1481    ;
1482
1483 expression_statement
1484    : ';'                { $$ = NULL;}
1485    | expr ';'           { $$ = $1; seqPointNo++;} 
1486    ;
1487
1488 else_statement
1489    :  ELSE  statement   { $$ = $2  ; }
1490    |                    { $$ = NULL;}
1491    ;
1492
1493   
1494 selection_statement
1495    : IF '(' expr ')' { seqPointNo++;} statement else_statement
1496                            {
1497                               noLineno++ ;
1498                               $$ = createIf ($3, $6, $7 );
1499                               noLineno--;
1500                            }
1501    | SWITCH '(' expr ')'   { 
1502                               ast *ex ;                              
1503                               static   int swLabel = 0 ;
1504
1505                               seqPointNo++;
1506                               /* create a node for expression  */
1507                               ex = newNode(SWITCH,$3,NULL);
1508                               STACK_PUSH(swStk,ex);   /* save it in the stack */
1509                               ex->values.switchVals.swNum = swLabel ;
1510                                  
1511                               /* now create the label */
1512                               SNPRINTF(lbuff, sizeof(lbuff), 
1513                                        "_swBrk_%d",swLabel++);
1514                               $<sym>$  =  newSymbol(lbuff,NestLevel);
1515                               /* put label in the break stack  */
1516                               STACK_PUSH(breakStack,$<sym>$);   
1517                            }
1518      statement             {  
1519                               /* get back the switch form the stack  */
1520                               $$ = STACK_POP(swStk)  ;
1521                               $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1522                               STACK_POP(breakStack);   
1523                            }
1524         ;
1525
1526 while : WHILE  {  /* create and push the continue , break & body labels */
1527                   static int Lblnum = 0 ;
1528                   /* continue */
1529                   SNPRINTF (lbuff, sizeof(lbuff), "_whilecontinue_%d",Lblnum);
1530                   STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1531                   /* break */
1532                   SNPRINTF (lbuff, sizeof(lbuff), "_whilebreak_%d",Lblnum);
1533                   STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1534                   /* body */
1535                   SNPRINTF (lbuff, sizeof(lbuff), "_whilebody_%d",Lblnum++);
1536                   $$ = newSymbol(lbuff,NestLevel);
1537                }
1538    ;
1539
1540 do : DO {  /* create and push the continue , break & body Labels */
1541            static int Lblnum = 0 ;
1542
1543            /* continue */
1544            SNPRINTF(lbuff, sizeof(lbuff), "_docontinue_%d",Lblnum);
1545            STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1546            /* break */
1547            SNPRINTF(lbuff, sizeof(lbuff), "_dobreak_%d",Lblnum);
1548            STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1549            /* do body */
1550            SNPRINTF(lbuff, sizeof(lbuff), "_dobody_%d",Lblnum++);
1551            $$ = newSymbol (lbuff,NestLevel);       
1552         }
1553    ;
1554
1555 for : FOR { /* create & push continue, break & body labels */
1556             static int Lblnum = 0 ;
1557          
1558             /* continue */
1559             SNPRINTF(lbuff, sizeof(lbuff), "_forcontinue_%d",Lblnum);
1560             STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1561             /* break    */
1562             SNPRINTF(lbuff, sizeof(lbuff), "_forbreak_%d",Lblnum);
1563             STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1564             /* body */
1565             SNPRINTF(lbuff, sizeof(lbuff), "_forbody_%d",Lblnum);
1566             $$ = newSymbol(lbuff,NestLevel);
1567             /* condition */
1568             SNPRINTF(lbuff, sizeof(lbuff), "_forcond_%d",Lblnum++);
1569             STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1570           }
1571    ;
1572
1573 iteration_statement  
1574    : while '(' expr ')' { seqPointNo++;}  statement 
1575                          { 
1576                            noLineno++ ;
1577                            $$ = createWhile ( $1, STACK_POP(continueStack),
1578                                               STACK_POP(breakStack), $3, $6 ); 
1579                            $$->lineno = $1->lineDef ;
1580                            noLineno-- ;
1581                          }
1582    | do statement   WHILE '(' expr ')' ';' 
1583                         { 
1584                           seqPointNo++; 
1585                           noLineno++ ; 
1586                           $$ = createDo ( $1 , STACK_POP(continueStack), 
1587                                           STACK_POP(breakStack), $5, $2);
1588                           $$->lineno = $1->lineDef ;
1589                           noLineno-- ;
1590                         }                                                 
1591    | for '(' expr_opt   ';' expr_opt ';' expr_opt ')'  statement   
1592                         {
1593                           noLineno++ ;  
1594                           
1595                           /* if break or continue statement present
1596                              then create a general case loop */
1597                           if (STACK_PEEK(continueStack)->isref ||
1598                               STACK_PEEK(breakStack)->isref) {
1599                               $$ = createFor ($1, STACK_POP(continueStack),
1600                                               STACK_POP(breakStack) ,
1601                                               STACK_POP(forStack)   ,
1602                                               $3 , $5 , $7, $9 );
1603                           } else {
1604                               $$ = newNode(FOR,$9,NULL);
1605                               AST_FOR($$,trueLabel) = $1;
1606                               AST_FOR($$,continueLabel) =  STACK_POP(continueStack);
1607                               AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1608                               AST_FOR($$,condLabel)  = STACK_POP(forStack)  ;
1609                               AST_FOR($$,initExpr)   = $3;
1610                               AST_FOR($$,condExpr)   = $5;
1611                               AST_FOR($$,loopExpr)   = $7;
1612                           }
1613                           
1614                           noLineno-- ;
1615                         }
1616 ;
1617
1618 expr_opt
1619         :                       { $$ = NULL ; seqPointNo++; }
1620         |       expr            { $$ = $1 ; seqPointNo++; }
1621         ;
1622
1623 jump_statement          
1624    : GOTO identifier ';'   { 
1625                               $2->islbl = 1;
1626                               $$ = newAst_VALUE(symbolVal($2)); 
1627                               $$ = newNode(GOTO,$$,NULL);
1628                            }
1629    | CONTINUE ';'          {  
1630        /* make sure continue is in context */
1631        if (STACK_EMPTY(continueStack) || STACK_PEEK(continueStack) == NULL) {
1632            werror(E_BREAK_CONTEXT);
1633            $$ = NULL;
1634        }
1635        else {
1636            $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));      
1637            $$ = newNode(GOTO,$$,NULL);
1638            /* mark the continue label as referenced */
1639            STACK_PEEK(continueStack)->isref = 1;
1640        }
1641    }
1642    | BREAK ';'             { 
1643        if (STACK_EMPTY(breakStack) || STACK_PEEK(breakStack) == NULL) {
1644            werror(E_BREAK_CONTEXT);
1645            $$ = NULL;
1646        } else {
1647            $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
1648            $$ = newNode(GOTO,$$,NULL);
1649            STACK_PEEK(breakStack)->isref = 1;
1650        }
1651    }
1652    | RETURN ';'            {
1653        seqPointNo++;
1654        if (inCritical) {
1655            werror(E_INVALID_CRITICAL);
1656            $$ = NULL;
1657        } else {
1658            $$ = newNode(RETURN,NULL,NULL);
1659        }
1660    }
1661    | RETURN expr ';'       {
1662        seqPointNo++;
1663        if (inCritical) {
1664            werror(E_INVALID_CRITICAL);
1665            $$ = NULL;
1666        } else {
1667            $$ = newNode(RETURN,NULL,$2);
1668        }
1669    }
1670    ;
1671
1672 identifier
1673    : IDENTIFIER   { $$ = newSymbol ($1,NestLevel) ; }
1674    ;
1675 %%
1676