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