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