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