work on avr port start by defining the new
[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 extern int yyerror (char *);
35 extern FILE     *yyin;
36 extern char srcLstFname[];
37 int NestLevel = 0 ;     /* current NestLevel       */
38 int stackPtr  = 1 ;     /* stack pointer           */
39 int xstackPtr = 0 ;     /* xstack pointer          */
40 int reentrant = 0 ; 
41 int blockNo   = 0 ;     /* sequential block number  */
42 int currBlockno=0 ;
43 extern int yylex();
44 int yyparse(void);
45 extern int noLineno ;
46 char lbuff[1024];      /* local buffer */
47
48 /* break & continue stacks */
49 STACK_DCL(continueStack  ,symbol *,MAX_NEST_LEVEL)
50 STACK_DCL(breakStack  ,symbol *,MAX_NEST_LEVEL)
51 STACK_DCL(forStack  ,symbol *,MAX_NEST_LEVEL)
52 STACK_DCL(swStk   ,ast   *,MAX_NEST_LEVEL)
53 STACK_DCL(blockNum,int,MAX_NEST_LEVEL*3)
54
55 value *cenum = NULL  ;  /* current enumeration  type chain*/
56
57 %}
58 %union {
59     symbol     *sym ;      /* symbol table pointer       */
60     structdef  *sdef;      /* structure definition       */
61     char       yychar[SDCC_NAME_MAX+1];
62     link       *lnk ;      /* declarator  or specifier   */
63     int        yyint;      /* integer value returned     */
64     value      *val ;      /* for integer constant       */
65     initList   *ilist;     /* initial list               */
66     char       yyinline[MAX_INLINEASM]; /* inlined assembler code */
67     ast       *asts;     /* expression tree            */
68 }
69
70 %token <yychar> IDENTIFIER TYPE_NAME
71 %token <val>   CONSTANT   STRING_LITERAL
72 %token SIZEOF 
73 %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
74 %token AND_OP OR_OP 
75 %token <yyint> MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
76 %token <yyint> SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
77 %token <yyint> XOR_ASSIGN OR_ASSIGN
78 %token TYPEDEF EXTERN STATIC AUTO REGISTER CODE FLASH INTERRUPT SFR AT SBIT
79 %token REENTRANT USING  XDATA DATA IDATA PDATA VAR_ARGS CRITICAL
80 %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID BIT
81 %token STRUCT UNION ENUM ELIPSIS RANGE FAR _XDATA _CODE _GENERIC _NEAR _PDATA _IDATA _FLASH
82 %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN 
83 %token <yyinline> INLINEASM
84 %token IFX ADDRESS_OF GET_VALUE_AT_ADDRESS SPIL UNSPIL GETHBIT
85 %token BITWISEAND UNARYMINUS IPUSH IPOP PCALL  ENDFUNCTION JUMPTABLE
86 %token RRC RLC 
87 %token CAST CALL PARAM NULLOP BLOCK LABEL RECEIVE SEND
88
89 %type <yyint>  Interrupt_storage
90 %type <sym> identifier  declarator  declarator2 enumerator_list enumerator
91 %type <sym> struct_declarator
92 %type <sym> struct_declarator_list  struct_declaration   struct_declaration_list
93 %type <sym> declaration init_declarator_list init_declarator
94 %type <sym> declaration_list identifier_list parameter_identifier_list
95 %type <sym> declarator2_using_reentrant while do for
96 %type <lnk> pointer type_specifier_list type_specifier type_name
97 %type <lnk> storage_class_specifier struct_or_union_specifier
98 %type <lnk> declaration_specifiers  sfr_reg_bit type_specifier2
99 %type <lnk> using_reentrant using_reentrant_interrupt enum_specifier
100 %type <lnk> abstract_declarator abstract_declarator2 far_near_pointer far_near
101 %type <val> parameter_type_list parameter_list parameter_declaration opt_assign_expr
102 %type <sdef> stag opt_stag
103 %type <asts> primary_expr
104 %type <asts> postfix_expr unary_expr cast_expr multiplicative_expr
105 %type <asts> additive_expr shift_expr relational_expr equality_expr
106 %type <asts> and_expr exclusive_or_expr inclusive_or_expr logical_or_expr
107 %type <asts> logical_and_expr conditional_expr assignment_expr constant_expr
108 %type <asts> expr argument_expr_list function_definition expr_opt
109 %type <asts> statement_list statement labeled_statement compound_statement
110 %type <asts> expression_statement selection_statement iteration_statement
111 %type <asts> jump_statement function_body else_statement string_literal
112 %type <ilist> initializer initializer_list
113 %type <yyint> unary_operator  assignment_operator struct_or_union
114
115 %start file
116
117 %%
118
119 file
120    : external_definition       
121    | file external_definition
122    ;
123
124 external_definition
125    : function_definition     { blockNo=0;}
126    | declaration             { 
127                                addSymChain ($1);
128                                allocVariables ($1) ;
129                                cleanUpLevel (SymbolTab,1);
130                              }
131    ;
132
133 function_definition
134    : declarator function_body  {   /* function type not specified */
135                                    /* assume it to be 'int'       */
136                                    addDecl($1,0,newIntLink());
137                                    $$ = createFunction($1,$2); 
138                                } 
139    | declaration_specifiers declarator function_body  
140                                 {   
141                                     pointerTypes($2->type,copyLinkChain($1));
142                                     addDecl($2,0,$1); 
143                                     $$ = createFunction($2,$3);   
144                                 }
145    ;
146
147 using_reentrant
148    : using_reentrant_interrupt
149    | using_reentrant_interrupt using_reentrant { $$ = mergeSpec($1,$2); }
150    ;
151
152 using_reentrant_interrupt
153    :  USING CONSTANT {
154                         $$ = newLink() ;
155                         $$->class = SPECIFIER   ;
156                         SPEC_BNKF($$) = 1;
157                         SPEC_BANK($$) = (int) floatFromVal($2);                       
158                      }
159    |  REENTRANT      {  $$ = newLink ();
160                         $$->class = SPECIFIER   ;
161                         SPEC_RENT($$) = 1;
162                      }
163    |  CRITICAL       {  $$ = newLink ();
164                         $$->class = SPECIFIER   ;
165                         SPEC_CRTCL($$) = 1;
166                      }
167    |  Interrupt_storage
168                      {
169                         $$ = newLink () ;
170                         $$->class = SPECIFIER ;
171                         SPEC_INTN($$) = $1 ;
172                         SPEC_INTRTN($$) = 1;
173                      }
174    ;
175
176 function_body
177    : compound_statement                   
178    | declaration_list compound_statement
179          {
180             werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
181             exit(1);
182          }
183    ;
184
185 primary_expr
186    : identifier      {  $$ = newAst(EX_VALUE,symbolVal($1));  }
187    | CONSTANT        {  $$ = newAst(EX_VALUE,$1);  }
188    | string_literal  
189    | '(' expr ')'    {  $$ = $2 ;                   }
190    ;
191          
192 string_literal
193     : STRING_LITERAL                    { $$ = newAst(EX_VALUE,$1); }
194     ;
195
196 postfix_expr
197    : primary_expr
198    | postfix_expr '[' expr ']'          { $$ = newNode  ('[', $1, $3) ; }
199    | postfix_expr '(' ')'               { $$ = newNode  (CALL,$1,NULL); 
200                                           $$->left->funcName = 1;}
201    | postfix_expr '(' argument_expr_list ')'
202           {        
203             $$ = newNode  (CALL,$1,$3) ; $$->left->funcName = 1;
204           }
205    | postfix_expr '.' identifier       
206                       {    
207                         $3 = newSymbol($3->name,NestLevel);
208                         $3->implicit = 1;
209                         $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst(EX_VALUE,symbolVal($3)));
210 /*                      $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($3))) ;                   */
211                       }
212    | postfix_expr PTR_OP identifier    
213                       { 
214                         $3 = newSymbol($3->name,NestLevel);
215                         $3->implicit = 1;                       
216                         $$ = newNode(PTR_OP,$1,newAst(EX_VALUE,symbolVal($3)));
217                       }
218    | postfix_expr INC_OP   
219                       { $$ = newNode(INC_OP,$1,NULL);}
220    | postfix_expr DEC_OP
221                       { $$ = newNode(DEC_OP,$1,NULL); }
222    ;
223
224 argument_expr_list
225    : assignment_expr 
226    | assignment_expr ',' argument_expr_list { $$ = newNode(PARAM,$1,$3); }
227    ;
228
229 unary_expr
230    : postfix_expr
231    | INC_OP unary_expr        { $$ = newNode(INC_OP,NULL,$2);  }
232    | DEC_OP unary_expr        { $$ = newNode(DEC_OP,NULL,$2);  }
233    | unary_operator cast_expr { $$ = newNode($1,$2,NULL)    ;  }
234    | SIZEOF unary_expr        { $$ = newNode(SIZEOF,NULL,$2);  }
235    | SIZEOF '(' type_name ')' { $$ = newAst(EX_VALUE,sizeofOp($3)); }
236    ;
237               
238 unary_operator
239    : '&'    { $$ = '&' ;}
240    | '*'    { $$ = '*' ;}
241    | '+'    { $$ = '+' ;}
242    | '-'    { $$ = '-' ;}
243    | '~'    { $$ = '~' ;}
244    | '!'    { $$ = '!' ;}
245    ;
246
247 cast_expr
248    : unary_expr
249    | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst(EX_LINK,$2),$4); }
250    ;
251
252 multiplicative_expr
253    : cast_expr
254    | multiplicative_expr '*' cast_expr { $$ = newNode('*',$1,$3);}
255    | multiplicative_expr '/' cast_expr { $$ = newNode('/',$1,$3);}
256    | multiplicative_expr '%' cast_expr { $$ = newNode('%',$1,$3);}
257    ;
258
259 additive_expr
260    : multiplicative_expr
261    | additive_expr '+' multiplicative_expr { $$=newNode('+',$1,$3);}
262    | additive_expr '-' multiplicative_expr { $$=newNode('-',$1,$3);}
263    ;
264
265 shift_expr
266    : additive_expr
267    | shift_expr LEFT_OP additive_expr  { $$ = newNode(LEFT_OP,$1,$3); }
268    | shift_expr RIGHT_OP additive_expr { $$ = newNode(RIGHT_OP,$1,$3); }
269    ;
270
271 relational_expr
272    : shift_expr
273    | relational_expr '<' shift_expr    { $$ = newNode('<',$1,$3); }
274    | relational_expr '>' shift_expr    { $$ = newNode('>',$1,$3); }
275    | relational_expr LE_OP shift_expr  { 
276        /* $$ = newNode(LE_OP,$1,$3); */
277        /* getting 8051 specific here : will change
278           LE_OP operation to "not greater than" i.e.
279           ( a <= b ) === ( ! ( a > b )) */
280        $$ = newNode('!', 
281                     newNode('>', $1 , $3 ),
282                     NULL);
283    }
284    | relational_expr GE_OP shift_expr  { 
285        /* $$ = newNode(GE_OP,$1,$3) ; */
286        /* getting 8051 specific here : will change
287           GE_OP operation to "not less than" i.e.
288           ( a >= b ) === ( ! ( a < b )) */
289        $$ = newNode('!',
290                     newNode('<', $1 , $3 ),
291                     NULL);
292    }
293    ;
294
295 equality_expr
296    : relational_expr
297    | equality_expr EQ_OP relational_expr  { $$ = newNode(EQ_OP,$1,$3);}
298    | equality_expr NE_OP relational_expr  
299           { 
300               /* $$ = newNode(NE_OP,$1,$3); */
301               /* NE_OP changed :            
302                  expr1 != expr2 is equivalent to
303                  (! expr1 == expr2) */
304               $$ = newNode('!',
305                            newNode(EQ_OP,$1,$3),
306                            NULL);
307           }       
308    ;
309
310 and_expr
311    : equality_expr
312    | and_expr '&' equality_expr  { $$ = newNode('&',$1,$3);}
313    ;
314
315 exclusive_or_expr
316    : and_expr
317    | exclusive_or_expr '^' and_expr { $$ = newNode('^',$1,$3);}
318    ;
319
320 inclusive_or_expr
321    : exclusive_or_expr
322    | inclusive_or_expr '|' exclusive_or_expr { $$ = newNode('|',$1,$3);}
323    ;
324
325 logical_and_expr
326    : inclusive_or_expr
327    | logical_and_expr AND_OP inclusive_or_expr 
328                                  { $$ = newNode(AND_OP,$1,$3);}
329    ;
330
331 logical_or_expr
332    : logical_and_expr
333    | logical_or_expr OR_OP logical_and_expr  
334                                  { $$ = newNode(OR_OP,$1,$3); }
335    ;
336
337 conditional_expr
338    : logical_or_expr
339    | logical_or_expr '?' logical_or_expr ':' conditional_expr  
340                      {
341                         $$ = newNode(':',$3,$5) ;
342                         $$ = newNode('?',$1,$$) ;
343                      }                        
344    ;
345
346 assignment_expr
347    : conditional_expr
348    | unary_expr assignment_operator assignment_expr   
349                      { 
350                                  
351                              switch ($2) {
352                              case '=':
353                                      $$ = newNode($2,$1,$3);
354                                      break;
355                              case MUL_ASSIGN:
356                                      $$ = newNode('=',$1,newNode('*',copyAst($1),$3));
357                                      break;
358                              case DIV_ASSIGN:
359                                      $$ = newNode('=',$1,newNode('/',copyAst($1),$3));
360                                      break;
361                              case ADD_ASSIGN:
362                                      $$ = newNode('=',$1,newNode('+',copyAst($1),$3));
363                                      break;
364                              case SUB_ASSIGN:
365                                      $$ = newNode('=',$1,newNode('-',copyAst($1),$3));
366                                      break;
367                              case LEFT_ASSIGN:
368                                      $$ = newNode('=',$1,newNode(LEFT_OP,copyAst($1),$3));
369                                      break;
370                              case RIGHT_ASSIGN:
371                                      $$ = newNode('=',$1,newNode(RIGHT_OP,copyAst($1),$3));
372                                      break;
373                              case AND_ASSIGN:
374                                      $$ = newNode('=',$1,newNode('&',copyAst($1),$3));
375                                      break;
376                              case XOR_ASSIGN:
377                                      $$ = newNode('=',$1,newNode('^',copyAst($1),$3));
378                                      break;
379                              case OR_ASSIGN:
380                                      $$ = newNode('=',$1,newNode('|',copyAst($1),$3));
381                                      break;
382                              default :
383                                      $$ = NULL;
384                              }
385                                      
386                      }
387 ;
388
389 assignment_operator
390    : '='             { $$ = '=' ;}
391    | MUL_ASSIGN
392    | DIV_ASSIGN
393    | MOD_ASSIGN
394    | ADD_ASSIGN
395    | SUB_ASSIGN
396    | LEFT_ASSIGN
397    | RIGHT_ASSIGN
398    | AND_ASSIGN
399    | XOR_ASSIGN
400    | OR_ASSIGN
401    ;
402
403 expr
404    : assignment_expr
405    | expr ',' assignment_expr { $$ = newNode(',',$1,$3);}
406    ;
407
408 constant_expr
409    : conditional_expr 
410    ;
411
412 declaration
413    : declaration_specifiers ';'  { $$ = NULL ; }
414    | declaration_specifiers init_declarator_list ';'
415       {
416          /* add the specifier list to the id */
417          symbol *sym , *sym1;
418
419          for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
420              link *lnk = copyLinkChain($1);
421              /* do the pointer stuff */
422              pointerTypes(sym->type,lnk);
423              addDecl (sym,0,lnk) ;
424          }
425         
426          $$ = sym1 ;
427       }
428    ;
429
430 declaration_specifiers
431    : storage_class_specifier                                            { $$ = $1; }
432    | storage_class_specifier declaration_specifiers { 
433      /* if the decl $2 is not a specifier */
434      /* find the spec and replace it      */
435      if ( !IS_SPEC($2)) {
436        link *lnk = $2 ;
437        while (lnk && !IS_SPEC(lnk->next))
438          lnk = lnk->next;
439        lnk->next = mergeSpec($1,lnk->next);
440        $$ = $2 ;
441      }
442      else
443        $$ = mergeSpec($1,$2); 
444    }
445    | type_specifier                                 { $$ = $1; }
446    | type_specifier declaration_specifiers          { 
447      /* if the decl $2 is not a specifier */
448      /* find the spec and replace it      */
449      if ( !IS_SPEC($2)) {
450        link *lnk = $2 ;
451        while (lnk && !IS_SPEC(lnk->next))
452          lnk = lnk->next;
453        lnk->next = mergeSpec($1,lnk->next);
454        $$ = $2 ;
455      }
456      else
457        $$ = mergeSpec($1,$2); 
458    }
459    ;
460
461 init_declarator_list
462    : init_declarator
463    | init_declarator_list ',' init_declarator      { $3->next = $1 ; $$ = $3;}
464    ;
465
466 init_declarator
467    : declarator                  { $1->ival = NULL ; }
468    | declarator '=' initializer  { $1->ival = $3   ; }
469    ;
470
471
472 storage_class_specifier
473    : TYPEDEF   {
474                   $$ = newLink () ;
475                   $$->class = SPECIFIER ;
476                   SPEC_TYPEDEF($$) = 1 ;
477                }
478    | EXTERN    {
479                   $$ = newLink();
480                   $$->class = SPECIFIER ;
481                   SPEC_EXTR($$) = 1 ;
482                }
483    | STATIC    {
484                   $$ = newLink ();
485                   $$->class = SPECIFIER ;
486                   SPEC_STAT($$) = 1 ;
487                }
488    | AUTO      {
489                   $$ = newLink () ;
490                   $$->class = SPECIFIER ;
491                   SPEC_SCLS($$) = S_AUTO  ;
492                }
493    | REGISTER  {
494                   $$ = newLink ();
495                   $$->class = SPECIFIER ;
496                   SPEC_SCLS($$) = S_REGISTER ;
497                }
498    ;
499
500 Interrupt_storage
501    : INTERRUPT CONSTANT  { $$ = (int) floatFromVal($2) ;  }
502    ;
503
504 type_specifier
505    : type_specifier2
506    | type_specifier2 AT CONSTANT
507         {
508            /* add this to the storage class specifier  */
509            SPEC_ABSA($1) = 1;   /* set the absolute addr flag */
510            /* now get the abs addr from value */
511            SPEC_ADDR($1) = (int) floatFromVal ($3) ;
512         }
513    ;
514
515 type_specifier2
516    : CHAR   {
517                $$=newLink();
518                $$->class = SPECIFIER   ;
519                SPEC_NOUN($$) = V_CHAR  ;
520             }
521    | SHORT  {
522                $$=newLink();
523                $$->class = SPECIFIER   ;
524                SPEC_LONG($$) = 0      ;
525                SPEC_SHORT($$) = 1        ;
526             }
527    | INT    {
528                $$=newLink();
529                $$->class = SPECIFIER   ;
530                SPEC_NOUN($$) = V_INT   ;
531             }
532    | LONG   {
533                $$=newLink();
534                $$->class = SPECIFIER   ;
535                SPEC_LONG($$) = 1       ;
536                SPEC_SHORT($$) = 0;
537             }
538    | SIGNED {
539                $$=newLink();
540                $$->class = SPECIFIER   ;
541                SPEC_USIGN($$) = 0       ;
542             }
543    | UNSIGNED  {
544                $$=newLink();
545                $$->class = SPECIFIER   ;
546                SPEC_USIGN($$) = 1       ;
547             }
548    | VOID   {
549                $$=newLink();
550                $$->class = SPECIFIER   ;
551                SPEC_NOUN($$) = V_VOID  ;
552             }
553    | CONST  {
554                $$=newLink();
555                $$->class = SPECIFIER ;
556                SPEC_SCLS($$) = S_CONSTANT ;
557                SPEC_CONST($$) = 1;
558             }
559    | VOLATILE  {
560                $$=newLink();
561                $$->class = SPECIFIER ;
562                SPEC_VOLATILE($$) = 1 ;
563             }
564    | FLOAT  {
565                $$=newLink();
566                SPEC_NOUN($$) = V_FLOAT;
567                $$->class = SPECIFIER ;
568             }
569    | XDATA     {
570                   $$ = newLink ();
571                   $$->class = SPECIFIER ;
572                   SPEC_SCLS($$) = S_XDATA  ;
573                }
574    | CODE      {
575                   $$ = newLink () ;
576                   $$->class = SPECIFIER  ;
577                   SPEC_SCLS($$) = S_CODE ;                 
578                }
579    | FLASH      {
580                   $$ = newLink () ;
581                   $$->class = SPECIFIER  ;
582                   SPEC_SCLS($$) = S_FLASH ;
583                }
584    | DATA      {
585                   $$ = newLink ();
586                   $$->class = SPECIFIER ;
587                   SPEC_SCLS($$) = S_DATA   ;
588                }
589    | IDATA     {
590                   $$ = newLink ();
591                   $$->class = SPECIFIER ;
592                   SPEC_SCLS($$) = S_IDATA  ;
593                }
594    | PDATA     { 
595                   $$ = newLink ();
596                   $$->class = SPECIFIER ;
597                   SPEC_SCLS($$) = S_PDATA  ;
598                }
599    | BIT    {
600                $$=newLink();
601                $$->class = SPECIFIER   ;
602                SPEC_NOUN($$) = V_BIT   ;
603                SPEC_SCLS($$) = S_BIT   ;
604                SPEC_BLEN($$) = 1;
605                SPEC_BSTR($$) = 0;
606             }
607
608    | struct_or_union_specifier
609    | enum_specifier     {                           
610                            cenum = NULL ;
611                            $$ = $1 ;                              
612                         }
613    | TYPE_NAME    
614          {
615             symbol *sym;
616             link   *p  ;
617
618             sym = findSym(TypedefTab,NULL,$1) ;
619             $$ = p = copyLinkChain(sym->type);
620             SPEC_TYPEDEF(getSpec(p)) = 0;
621          }
622    | sfr_reg_bit
623    ;
624
625 sfr_reg_bit
626    :  SBIT  {
627                $$ = newLink() ;
628                $$->class = SPECIFIER ;
629                SPEC_NOUN($$) = V_SBIT;
630                SPEC_SCLS($$) = S_SBIT;
631             }
632    |  SFR   {
633                $$ = newLink() ;
634                $$->class = SPECIFIER ;
635                SPEC_NOUN($$) = V_CHAR;
636                SPEC_SCLS($$) = S_SFR ;
637                SPEC_USIGN($$) = 1 ;
638             }
639    ;
640
641 struct_or_union_specifier
642    : struct_or_union opt_stag '{' struct_declaration_list '}'
643         {
644            structdef *sdef ;
645
646            /* Create a structdef   */
647            sdef = $2 ;
648            sdef->fields   = reverseSyms($4) ;   /* link the fields */
649            sdef->size  = compStructSize($1,sdef);   /* update size of  */
650
651            /* Create the specifier */
652            $$ = newLink () ;
653            $$->class = SPECIFIER   ;
654            SPEC_NOUN($$) = V_STRUCT;
655            SPEC_STRUCT($$)= sdef ;
656         }
657    | struct_or_union stag
658          {
659             $$ = newLink() ;
660             $$->class = SPECIFIER   ;
661             SPEC_NOUN($$) = V_STRUCT;
662             SPEC_STRUCT($$) = $2 ;
663          }
664    ;
665
666 struct_or_union
667    : STRUCT          { $$ = STRUCT ; }
668    | UNION           { $$ = UNION  ; }
669    ;
670
671 opt_stag
672    : stag
673    |  {  /* synthesize a name add to structtable */
674          $$ = newStruct(genSymName(NestLevel)) ;
675          $$->level = NestLevel ;
676          addSym (StructTab, $$, $$->tag,$$->level,currBlockno) ;
677       }
678    ;
679
680 stag
681    :  identifier  {  /* add name to structure table */
682                      $$ = findSymWithBlock (StructTab,$1,currBlockno);
683                      if (! $$ ) {
684                         $$ = newStruct($1->name) ;
685                         $$->level = NestLevel ;
686                         addSym (StructTab, $$, $$->tag,$$->level,currBlockno) ;                  
687                      }
688                   }
689    ;
690
691 struct_declaration_list
692    : struct_declaration
693    | struct_declaration_list struct_declaration
694        {
695            symbol *sym = $2;
696            /* go to the end of the chain */
697            while (sym->next) sym = sym->next;
698
699            sym->next = $1 ;
700            $$ = $2;
701        }
702    ;
703
704 struct_declaration
705    : type_specifier_list struct_declarator_list ';'
706        {
707            /* add this type to all the symbols */
708            symbol *sym ;
709            for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
710                
711                pointerTypes(sym->type,copyLinkChain($1));
712                if (!sym->type) {
713                    sym->type = copyLinkChain($1);
714                    sym->etype = getSpec(sym->type);
715                }
716                else
717                    addDecl (sym,0,cloneSpec($1));              
718                
719            }
720            $$ = $2;
721        }
722    ;
723
724 struct_declarator_list
725    : struct_declarator
726    | struct_declarator_list ',' struct_declarator
727        {
728            $3->next  = $1 ;
729            $$ = $3 ;
730        }
731    ;
732
733 struct_declarator
734    : declarator
735    | ':' constant_expr  {  
736                            $$ = newSymbol (genSymName(NestLevel),NestLevel) ; 
737                            $$->bitVar = (int) floatFromVal(constExprValue($2,TRUE));
738                         }                        
739    | declarator ':' constant_expr 
740                         { 
741                           $1->bitVar = (int) floatFromVal(constExprValue($3,TRUE));                     
742                         }
743    ;
744
745 enum_specifier
746    : ENUM            '{' enumerator_list '}' {
747                                                 addSymChain ($3);
748                                                 allocVariables(reverseSyms($3)) ;
749                                                 $$ = copyLinkChain(cenum->type);
750                                              }
751    | ENUM identifier '{' enumerator_list '}' {
752                                                 symbol *csym ;
753
754                                                 $2->type = copyLinkChain(cenum->type);
755                                                 $2->etype = getSpec($2->type);
756                                                 /* add this to the enumerator table */
757                                                 if (!(csym=findSym(enumTab,$2,$2->name)) && 
758                                                     (csym && csym->level == $2->level))
759                                                    werror(E_DUPLICATE_TYPEDEF,csym->name);
760
761                                                 addSym ( enumTab,$2,$2->name,$2->level,$2->block);
762                                                 addSymChain ($4);
763                                                 allocVariables (reverseSyms($4));
764                                                 $$ = copyLinkChain(cenum->type);
765                                                 SPEC_SCLS(getSpec($$)) = 0 ;
766                                              }
767    | ENUM identifier                         {
768                                                 symbol *csym ;
769
770                                                 /* check the enumerator table */
771                                                 if ((csym = findSym(enumTab,$2,$2->name)))
772                                                    $$ = copyLinkChain(csym->type);
773                                                 else  {
774                                                    $$ = newLink() ;
775                                                    $$->class = SPECIFIER   ;
776                                                    SPEC_NOUN($$) = V_INT   ;
777                                                 }
778
779                                                 SPEC_SCLS(getSpec($$)) = 0 ;
780                                              }
781    ;
782
783 enumerator_list
784    : enumerator
785    | enumerator_list ',' enumerator {
786                                        $3->next = $1 ;
787                                        $$ = $3  ;
788                                     }
789    ;
790
791 enumerator
792    : identifier opt_assign_expr  {
793                                     /* make the symbol one level up */
794                                     $1->level-- ;
795                                     $1->type = copyLinkChain($2->type); 
796                                     $1->etype= getSpec($1->type);
797                                     SPEC_ENUM($1->etype) = 1;
798                                     $$ = $1 ;
799
800                                  }
801    ;
802
803 opt_assign_expr
804    :  '='   constant_expr  {
805                               value *val ;
806                                                         
807                               val = constExprValue($2,TRUE);                         
808                               $$ = cenum = val ;
809                            }                           
810    |                       {                              
811                               if (cenum)  {
812                                  sprintf(lbuff,"%d",(int) floatFromVal(cenum)+1);
813                                  $$ = cenum = constVal(lbuff);
814                               }
815                               else {
816                                  sprintf(lbuff,"%d",0);
817                                  $$ = cenum = constVal(lbuff);
818                               }   
819                            }
820    ;
821
822 declarator
823    : declarator2_using_reentrant        { $$ = $1; }
824    | pointer declarator2_using_reentrant
825          {
826              addDecl ($2,0,reverseLink($1));
827              $$ = $2 ;
828          }
829    ;
830
831 declarator2_using_reentrant
832    : declarator2                  { $$ = $1 ; } 
833    | declarator2 using_reentrant  { addDecl ($1,0,$2); }     
834    ;
835
836 declarator2
837    : identifier
838    | '(' declarator ')'     { $$ = $2; }
839    | declarator2 '[' ']'
840          {
841             link   *p;
842
843             p = newLink ();
844             DCL_TYPE(p) = ARRAY ;
845             DCL_ELEM(p) = 0     ;
846             addDecl($1,0,p);
847          }
848    | declarator2 '[' constant_expr ']'
849          {
850             link   *p ;
851                         value *tval;
852                         
853             p = (tval = constExprValue($3,TRUE))->etype;
854             /* if it is not a constant then Error  */
855             if ( SPEC_SCLS(p) != S_LITERAL)
856                werror(E_CONST_EXPECTED) ;
857             else {
858                p = newLink ();
859                DCL_TYPE(p) = ARRAY ;
860                DCL_ELEM(p) = (int) floatFromVal(tval) ;
861                addDecl($1,0,p);
862             }                           
863          }
864    | declarator2 '('  ')'       {  addDecl ($1,FUNCTION,NULL) ;   }
865    | declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')'
866          {
867            
868              addDecl ($1,FUNCTION,NULL) ;
869            
870              $1->hasVargs = IS_VARG($4);
871              $1->args = reverseVal($4)  ;
872              
873              /* nest level was incremented to take care of the parms  */
874              NestLevel-- ;
875              currBlockno--;
876              $$ = $1;
877          }
878    | declarator2 '(' parameter_identifier_list ')'
879          {         
880            werror(E_OLD_STYLE,$1->name) ;         
881            
882            /* assume it returns an it */
883            $1->type = $1->etype = newIntLink();
884            $$ = $1 ;
885          }
886    ;
887
888 pointer
889    : far_near_pointer { $$ = $1 ;}
890    | far_near_pointer type_specifier_list   
891          {
892              $$ = $1  ;         
893              DCL_TSPEC($1) = $2;
894          }
895    | far_near_pointer pointer         
896          {
897              $$ = $1 ;          
898              $$->next = $2 ;
899          }
900    | far_near_pointer type_specifier_list pointer
901          {
902              $$ = $1 ;               
903              if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
904                  DCL_PTR_CONST($1) = SPEC_CONST($2);
905                  DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
906                  switch (SPEC_SCLS($2)) {
907                  case S_XDATA:
908                      DCL_TYPE($3) = FPOINTER;
909                      break;
910                  case S_IDATA:
911                      DCL_TYPE($3) = IPOINTER ;
912                      break;
913                  case S_PDATA:
914                      DCL_TYPE($3) = PPOINTER ;
915                      break;
916                  case S_DATA:
917                      DCL_TYPE($3) = POINTER ;
918                      break;
919                  case S_CODE:
920                      DCL_PTR_CONST($3) = 1;
921                      DCL_TYPE($3) = CPOINTER ;
922                  case S_FLASH:
923                      DCL_TYPE($3) = FLPOINTER;
924                      break;
925                  }
926              }
927              else 
928                  werror (W_PTR_TYPE_INVALID);
929              $$->next = $3 ;
930          }
931    ;
932
933 far_near_pointer
934    :  far_near '*'   {
935                         if ($1 == NULL) {
936                            $$ = newLink();
937                            DCL_TYPE($$) = POINTER ;
938                         }
939                         else
940                            $$ = $1 ;
941       }
942    ;
943
944 far_near
945    : _XDATA    { $$ = newLink() ; DCL_TYPE($$) = FPOINTER ; }
946    | _CODE     { $$ = newLink() ; DCL_TYPE($$) = CPOINTER ;  DCL_PTR_CONST($$) = 1;}
947    | _PDATA    { $$ = newLink() ; DCL_TYPE($$) = PPOINTER ; } 
948    | _IDATA    { $$ = newLink() ; DCL_TYPE($$) = IPOINTER ; }
949    | _NEAR     { $$ = NULL ; }
950    | _GENERIC  { $$ = newLink() ; DCL_TYPE($$) = GPOINTER ; } 
951    | _FLASH    { $$ = newLink() ; DCL_TYPE($$) = FLPOINTER ;} 
952    |           { $$ = newLink() ; DCL_TYPE($$) = UPOINTER ; }
953    ;
954
955 type_specifier_list
956    : type_specifier
957    | type_specifier_list type_specifier         {  $$ = mergeSpec ($1,$2); }
958    ;
959
960 parameter_identifier_list
961    : identifier_list
962    | identifier_list ',' ELIPSIS
963    ;
964
965 identifier_list
966    : identifier
967    | identifier_list ',' identifier         
968          {            
969            $3->next = $1;
970            $$ = $3 ;
971          }
972    ;
973
974 parameter_type_list
975         : parameter_list
976         | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
977         ;
978
979 parameter_list
980    : parameter_declaration 
981    | parameter_list ',' parameter_declaration
982          {
983             $3->next = $1 ;
984             $$ = $3 ;       
985          }
986    ;
987
988 parameter_declaration
989    : type_specifier_list declarator 
990                {        
991                   symbol *loop ;
992                   pointerTypes($2->type,$1);
993                   addDecl ($2,0,$1);              
994                   for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
995                   addSymChain ($2);
996                   $$ = symbolVal($2);
997                }
998    | type_name { 
999                   $$ = newValue() ; 
1000                   $$->type = $1;
1001                   $$->etype = getSpec($$->type);
1002                }
1003    ;
1004
1005 type_name
1006    : type_specifier_list  { $$ = $1 ;}
1007    | type_specifier_list abstract_declarator 
1008                {
1009                  /* go to the end of the list */
1010                  link *p;
1011                  pointerTypes($2,$1);
1012                  for ( p = $2 ; p->next ; p=p->next);
1013                   p->next = $1 ;
1014                   $$ = $2 ;
1015                }   
1016    ;
1017
1018 abstract_declarator
1019    : pointer { $$ = reverseLink($1); }
1020    | abstract_declarator2
1021    | pointer abstract_declarator2   { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;} 
1022    ;
1023
1024 abstract_declarator2
1025    : '(' abstract_declarator ')'    { $$ = $2 ; }
1026    | '[' ']'                        {             
1027                                        $$ = newLink ();
1028                                        DCL_TYPE($$) = ARRAY ;
1029                                        DCL_ELEM($$) = 0     ;
1030                                     }
1031    | '[' constant_expr ']'          { 
1032                                        value *val ;
1033                                        $$ = newLink ();
1034                                        DCL_TYPE($$) = ARRAY ;
1035                                        DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1036                                     }
1037    | abstract_declarator2 '[' ']'   {
1038                                        $$ = newLink ();
1039                                        DCL_TYPE($$) = ARRAY ;
1040                                        DCL_ELEM($$) = 0     ;
1041                                        $$->next = $1 ;
1042                                     }
1043    | abstract_declarator2 '[' constant_expr ']'
1044                                     {
1045                                        value *val ;
1046                                        $$ = newLink ();
1047                                        DCL_TYPE($$) = ARRAY ;
1048                                        DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1049                                        $$->next = $1 ;
1050                                     }
1051    | '(' ')'                        { $$ = NULL;}
1052    | '(' parameter_type_list ')'    { $$ = NULL;}   
1053    | abstract_declarator2 '(' ')'
1054    | abstract_declarator2 '(' parameter_type_list ')'
1055    ;
1056
1057 initializer
1058    : assignment_expr                { $$ = newiList(INIT_NODE,$1); }
1059    | '{'  initializer_list '}'      { $$ = newiList(INIT_DEEP,revinit($2)); }
1060    | '{'  initializer_list ',' '}'  { $$ = newiList(INIT_DEEP,revinit($2)); }
1061    ;
1062
1063 initializer_list
1064    : initializer
1065    | initializer_list ',' initializer  {  $3->next = $1; $$ = $3; }
1066    ;
1067
1068 statement
1069    : labeled_statement
1070    | compound_statement
1071    | expression_statement
1072    | selection_statement
1073    | iteration_statement
1074    | jump_statement
1075    | INLINEASM  ';'      {
1076                             ast *ex = newNode(INLINEASM,NULL,NULL);
1077                             ALLOC_ATOMIC(ex->values.inlineasm,strlen($1));
1078                             strcpy(ex->values.inlineasm,$1);                        
1079                             $$ = ex;
1080                          }   
1081    ;
1082
1083 labeled_statement
1084    : identifier ':' statement          {  $$ = createLabel($1,$3);  }   
1085    | CASE constant_expr ':' statement  {  $$ = createCase(STACK_PEEK(swStk),$2,$4); }
1086    | DEFAULT ':' statement             {  $$ = createDefault(STACK_PEEK(swStk),$3); }
1087    ;
1088
1089 start_block : '{' { STACK_PUSH(blockNum,currBlockno); currBlockno = ++blockNo ;  }
1090             ;
1091
1092 end_block   : '}'     { currBlockno = STACK_POP(blockNum); }           
1093             ;
1094
1095 compound_statement
1096    : start_block end_block                    { $$ = createBlock(NULL,NULL); }
1097    | start_block statement_list end_block     { $$ = createBlock(NULL,$2) ;  }
1098    | start_block 
1099           declaration_list                    { addSymChain($2); }
1100      end_block                                { $$ = createBlock($2,NULL) ;  }
1101    | start_block 
1102           declaration_list                    {  addSymChain ($2); }
1103           statement_list   
1104      end_block                                {$$ = createBlock($2,$4)   ;  }
1105    | error ';'                                { $$ = NULL ; }
1106    ;
1107
1108 declaration_list
1109    : declaration        
1110      {
1111        /* if this is typedef declare it immediately */
1112        if ( $1 && IS_TYPEDEF($1->etype)) {
1113          allocVariables ($1);
1114          $$ = NULL ;
1115        }
1116        else
1117          $$ = $1 ;
1118      }
1119
1120    | declaration_list declaration
1121      {
1122        symbol   *sym;
1123        
1124        /* if this is a typedef */
1125        if ($2 && IS_TYPEDEF($2->etype)) {
1126          allocVariables ($2);
1127          $$ = $1 ;
1128        }
1129        else {
1130                                 /* get to the end of the previous decl */
1131          if ( $1 ) {
1132            $$ = sym = $1 ;
1133            while (sym->next)
1134              sym = sym->next ;
1135            sym->next = $2;
1136          } 
1137          else
1138            $$ = $2 ;
1139        }
1140      }
1141    ;
1142
1143 statement_list
1144    : statement
1145    | statement_list statement          {  $$ = newNode(NULLOP,$1,$2) ;}
1146    ;
1147
1148 expression_statement
1149    : ';'                { $$ = NULL;}
1150    | expr ';' 
1151    ;
1152
1153 else_statement
1154    :  ELSE  statement   { $$ = $2  ; }
1155    |                    { $$ = NULL;}
1156    ;
1157
1158   
1159 selection_statement
1160    : IF '(' expr ')'  statement else_statement { noLineno++ ; $$ = createIf ($3, $5, $6 ); noLineno--;}
1161    | SWITCH '(' expr ')'   { 
1162                               ast *ex ;                              
1163                               static   int swLabel = 0 ;
1164
1165                               /* create a node for expression  */
1166                               ex = newNode(SWITCH,$3,NULL);
1167                               STACK_PUSH(swStk,ex);   /* save it in the stack */
1168                               ex->values.switchVals.swNum = swLabel ;
1169                                  
1170                               /* now create the label */
1171                               sprintf(lbuff,"_swBrk_%d",swLabel++);
1172                               $<sym>$  =  newSymbol(lbuff,NestLevel);
1173                               /* put label in the break stack  */
1174                               STACK_PUSH(breakStack,$<sym>$);   
1175                            }
1176      statement             {  
1177                               /* get back the switch form the stack  */
1178                               $$ = STACK_POP(swStk)  ;
1179                               $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1180                               STACK_POP(breakStack);   
1181                            }
1182         ;
1183
1184 while : WHILE  {  /* create and push the continue , break & body labels */
1185                   static int Lblnum = 0 ;
1186                   /* continue */
1187                   sprintf (lbuff,"_whilecontinue_%d",Lblnum);
1188                   STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1189                   /* break */
1190                   sprintf (lbuff,"_whilebreak_%d",Lblnum);
1191                   STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1192                   /* body */
1193                   sprintf (lbuff,"_whilebody_%d",Lblnum++);
1194                   $$ = newSymbol(lbuff,NestLevel);
1195                }
1196
1197 do : DO {  /* create and push the continue , break & body Labels */
1198            static int Lblnum = 0 ;
1199
1200            /* continue */
1201            sprintf(lbuff,"_docontinue_%d",Lblnum);
1202            STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1203            /* break */
1204            sprintf (lbuff,"_dobreak_%d",Lblnum);
1205            STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1206            /* do body */
1207            sprintf (lbuff,"_dobody_%d",Lblnum++);
1208            $$ = newSymbol (lbuff,NestLevel);       
1209         }
1210 for : FOR { /* create & push continue, break & body labels */
1211             static int Lblnum = 0 ;
1212          
1213             /* continue */
1214             sprintf (lbuff,"_forcontinue_%d",Lblnum);
1215             STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1216             /* break    */
1217             sprintf (lbuff,"_forbreak_%d",Lblnum);
1218             STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1219             /* body */
1220             sprintf (lbuff,"_forbody_%d",Lblnum);
1221             $$ = newSymbol(lbuff,NestLevel);
1222             /* condition */
1223             sprintf (lbuff,"_forcond_%d",Lblnum++);
1224             STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1225           }
1226
1227 iteration_statement  
1228    : while '(' expr ')'  statement 
1229                          { 
1230                            noLineno++ ;
1231                            $$ = createWhile ( $1, STACK_POP(continueStack),
1232                                               STACK_POP(breakStack), $3, $5 ); 
1233                            $$->lineno = $1->lineDef ;
1234                            noLineno-- ;
1235                          }
1236    | do statement   WHILE '(' expr ')' ';' 
1237                         { 
1238                           noLineno++ ; 
1239                           $$ = createDo ( $1 , STACK_POP(continueStack), 
1240                                           STACK_POP(breakStack), $5, $2);
1241                           $$->lineno = $1->lineDef ;
1242                           noLineno-- ;
1243                         }                                                 
1244    | for '(' expr_opt   ';' expr_opt ';' expr_opt ')'  statement   
1245                         {
1246                           noLineno++ ;  
1247                           
1248                           /* if break or continue statement present
1249                              then create a general case loop */
1250                           if (STACK_PEEK(continueStack)->isref ||
1251                               STACK_PEEK(breakStack)->isref) {
1252                               $$ = createFor ($1, STACK_POP(continueStack),
1253                                               STACK_POP(breakStack) ,
1254                                               STACK_POP(forStack)   ,
1255                                               $3 , $5 , $7, $9 );
1256                           } else {
1257                               $$ = newNode(FOR,$9,NULL);
1258                               AST_FOR($$,trueLabel) = $1;
1259                               AST_FOR($$,continueLabel) =  STACK_POP(continueStack);
1260                               AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1261                               AST_FOR($$,condLabel)  = STACK_POP(forStack)  ;
1262                               AST_FOR($$,initExpr)   = $3;
1263                               AST_FOR($$,condExpr)   = $5;
1264                               AST_FOR($$,loopExpr)   = $7;
1265                           }
1266                           
1267                           noLineno-- ;
1268                         }
1269 ;
1270
1271 expr_opt
1272         :                       { $$ = NULL ; }
1273         |       expr
1274         ;
1275
1276 jump_statement          
1277    : GOTO identifier ';'   { 
1278                               $2->islbl = 1;
1279                               $$ = newAst(EX_VALUE,symbolVal($2)); 
1280                               $$ = newNode(GOTO,$$,NULL);
1281                            }
1282    | CONTINUE ';'          {  
1283        /* make sure continue is in context */
1284        if (STACK_PEEK(continueStack) == NULL) {
1285            werror(E_BREAK_CONTEXT);
1286            $$ = NULL;
1287        }
1288        else {
1289            $$ = newAst(EX_VALUE,symbolVal(STACK_PEEK(continueStack)));      
1290            $$ = newNode(GOTO,$$,NULL);
1291            /* mark the continue label as referenced */
1292            STACK_PEEK(continueStack)->isref = 1;
1293        }
1294    }
1295    | BREAK ';'             { 
1296        if (STACK_PEEK(breakStack) == NULL) {
1297            werror(E_BREAK_CONTEXT);
1298            $$ = NULL;
1299        } else {
1300            $$ = newAst(EX_VALUE,symbolVal(STACK_PEEK(breakStack)));
1301            $$ = newNode(GOTO,$$,NULL);
1302            STACK_PEEK(breakStack)->isref = 1;
1303        }
1304    }
1305    | RETURN ';'            { $$ = newNode(RETURN,NULL,NULL)    ; }
1306    | RETURN expr ';'       { $$ = newNode(RETURN,NULL,$2) ; } 
1307    ;
1308
1309 identifier
1310    : IDENTIFIER   { $$ = newSymbol ($1,NestLevel) ; }
1311    ;
1312 %%
1313
1314 extern unsigned char *yytext;
1315 extern int column;
1316 extern char *filename;
1317 extern int fatalError;
1318
1319 int yyerror(char *s)
1320 {
1321    fflush(stdout);
1322
1323    if ( yylineno )
1324         fprintf(stderr,"\n%s(%d) %s: token -> '%s' ; column %d\n",
1325                 filename,yylineno,
1326                 s,yytext,column);
1327    fatalError++;
1328    return 0;
1329 }
1330