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