upper case pragmas are deprecated
[fw/sdcc] / src / SDCC.lex
1 /*-----------------------------------------------------------------------
2   SDCC.lex - lexical analyser for use with sdcc ( a freeware compiler for
3   8/16 bit microcontrollers)
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 D       [0-9]
26 L       [a-zA-Z_]
27 H       [a-fA-F0-9]
28 E       [Ee][+-]?{D}+
29 FS      (f|F|l|L)
30 IS      (u|U|l|L)*
31
32 %{
33 #include <stdio.h>
34 #include <string.h>
35 #include <ctype.h>
36 #include "common.h"
37 #include "newalloc.h"
38 #include "dbuf.h"
39
40 #define TKEYWORD(token) return (isTargetKeyword(yytext) ? token :\
41                                 check_type())
42
43 extern int lineno, column;
44 extern char *filename;
45
46 /* global definitions */
47 char *currFname;
48 int mylineno = 1;
49
50 /* local definitions */
51 static struct dbuf_s asmbuff;
52
53 /* forward declarations */
54 static char *stringLiteral(void);
55 static void count(void);
56 static int process_pragma(char *);
57 static int check_type(void);
58 static int isTargetKeyword(char *s);
59 static int checkCurrFile(char *s);
60 %}
61
62 %x asm
63 %%
64 "_asm"         {
65   count();
66   assert(asmbuff.alloc == 0 && asmbuff.len == 0 && asmbuff.buf == NULL);
67   dbuf_init(&asmbuff, INITIAL_INLINEASM);
68   BEGIN(asm);
69 }
70 <asm>"_endasm" {
71   count();
72   yylval.yyinline = dbuf_c_str(&asmbuff);
73   dbuf_detach(&asmbuff);
74   BEGIN(INITIAL);
75   return (INLINEASM);
76 }
77 <asm>\n        {
78   count();
79   dbuf_append(&asmbuff, yytext, 1);
80 }
81 <asm>.         {
82   dbuf_append(&asmbuff, yytext, 1);
83 }
84 "at"           { count(); TKEYWORD(AT); }
85 "auto"         { count(); return(AUTO); }
86 "bit"          { count(); TKEYWORD(BIT); }
87 "break"        { count(); return(BREAK); }
88 "case"         { count(); return(CASE); }
89 "char"         { count(); return(CHAR); }
90 "code"         { count(); TKEYWORD(CODE); }
91 "const"        { count(); return(CONST); }
92 "continue"     { count(); return(CONTINUE); }
93 "critical"     { count(); TKEYWORD(CRITICAL); }
94 "data"         { count(); TKEYWORD(DATA); }
95 "default"      { count(); return(DEFAULT); }
96 "do"           { count(); return(DO); }
97 "double"       { count(); werror(W_DOUBLE_UNSUPPORTED);return(FLOAT); }
98 "else"         { count(); return(ELSE); }
99 "enum"         { count(); return(ENUM); }
100 "extern"       { count(); return(EXTERN); }
101 "far"          { count(); TKEYWORD(XDATA); }
102 "eeprom"       { count(); TKEYWORD(EEPROM); }
103 "float"        { count(); return(FLOAT); }
104 "flash"        { count(); TKEYWORD(CODE); }
105 "for"          { count(); return(FOR); }
106 "goto"         { count(); return(GOTO); }
107 "idata"        { count(); TKEYWORD(IDATA); }
108 "if"           { count(); return(IF); }
109 "int"          { count(); return(INT); }
110 "interrupt"    { count(); return(INTERRUPT); }
111 "nonbanked"    { count(); TKEYWORD(NONBANKED); }
112 "banked"       { count(); TKEYWORD(BANKED); }
113 "long"         { count(); return(LONG); }
114 "near"         { count(); TKEYWORD(DATA); }
115 "pdata"        { count(); TKEYWORD(PDATA); }
116 "reentrant"    { count(); TKEYWORD(REENTRANT); }
117 "register"     { count(); return(REGISTER); }
118 "return"       { count(); return(RETURN); }
119 "sfr"          { count(); TKEYWORD(SFR); }
120 "sbit"         { count(); TKEYWORD(SBIT); }
121 "short"        { count(); return(SHORT); }
122 "signed"       { count(); return(SIGNED); }
123 "sizeof"       { count(); return(SIZEOF); }
124 "sram"         { count(); TKEYWORD(XDATA); }
125 "static"       { count(); return(STATIC); }
126 "struct"       { count(); return(STRUCT); }
127 "switch"       { count(); return(SWITCH); }
128 "typedef"      { count(); return(TYPEDEF); }
129 "union"        { count(); return(UNION); }
130 "unsigned"     { count(); return(UNSIGNED); }
131 "void"         { count(); return(VOID); }
132 "volatile"     { count(); return(VOLATILE); }
133 "using"        { count(); TKEYWORD(USING); }
134 "_naked"       { count(); TKEYWORD(NAKED); }
135 "while"        { count(); return(WHILE); }
136 "xdata"        { count(); TKEYWORD(XDATA); }
137 "..."          { count(); return(VAR_ARGS); }
138 "__typeof"     { count(); return TYPEOF; }
139 "_JavaNative"  { count(); TKEYWORD(JAVANATIVE); }
140 "_overlay"     { count(); TKEYWORD(OVERLAY); }
141 {L}({L}|{D})*  { count(); return(check_type()); }
142 0[xX]{H}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
143 0{D}+{IS}?     { count(); yylval.val = constVal(yytext); return(CONSTANT); }
144 {D}+{IS}?      { count(); yylval.val = constVal(yytext); return(CONSTANT); }
145 '(\\.|[^\\'])+' { count();yylval.val = charVal (yytext); return(CONSTANT); /* ' make syntax highliter happy */ }
146 {D}+{E}{FS}?   { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
147 {D}*"."{D}+({E})?{FS}?  { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
148 {D}+"."{D}*({E})?{FS}?  { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
149 \"             { count(); yylval.val=strVal(stringLiteral()); return(STRING_LITERAL); }
150 ">>=" { count(); yylval.yyint = RIGHT_ASSIGN ; return(RIGHT_ASSIGN); }
151 "<<=" { count(); yylval.yyint = LEFT_ASSIGN  ; return(LEFT_ASSIGN); }
152 "+="  { count(); yylval.yyint = ADD_ASSIGN   ; return(ADD_ASSIGN); }
153 "-="  { count(); yylval.yyint = SUB_ASSIGN   ; return(SUB_ASSIGN); }
154 "*="  { count(); yylval.yyint = MUL_ASSIGN   ; return(MUL_ASSIGN); }
155 "/="  { count(); yylval.yyint = DIV_ASSIGN   ; return(DIV_ASSIGN); }
156 "%="  { count(); yylval.yyint = MOD_ASSIGN   ; return(MOD_ASSIGN); }
157 "&="  { count(); yylval.yyint = AND_ASSIGN   ; return(AND_ASSIGN); }
158 "^="  { count(); yylval.yyint = XOR_ASSIGN   ; return(XOR_ASSIGN); }
159 "|="  { count(); yylval.yyint = OR_ASSIGN    ; return(OR_ASSIGN); }
160 ">>"           { count(); return(RIGHT_OP); }
161 "<<"           { count(); return(LEFT_OP); }
162 "++"           { count(); return(INC_OP); }
163 "--"           { count(); return(DEC_OP); }
164 "->"           { count(); return(PTR_OP); }
165 "&&"           { count(); return(AND_OP); }
166 "||"           { count(); return(OR_OP); }
167 "<="           { count(); return(LE_OP); }
168 ">="           { count(); return(GE_OP); }
169 "=="           { count(); return(EQ_OP); }
170 "!="           { count(); return(NE_OP); }
171 ";"            { count(); return(';'); }
172 "{"            { count(); NestLevel++ ; ignoreTypedefType = 0; return('{'); }
173 "}"            { count(); NestLevel--; return('}'); }
174 ","            { count(); return(','); }
175 ":"            { count(); return(':'); }
176 "="            { count(); return('='); }
177 "("            { count(); ignoreTypedefType = 0; return('('); }
178 ")"            { count(); return(')'); }
179 "["            { count(); return('['); }
180 "]"            { count(); return(']'); }
181 "."            { count(); return('.'); }
182 "&"            { count(); return('&'); }
183 "!"            { count(); return('!'); }
184 "~"            { count(); return('~'); }
185 "-"            { count(); return('-'); }
186 "+"            { count(); return('+'); }
187 "*"            { count(); return('*'); }
188 "/"            { count(); return('/'); }
189 "%"            { count(); return('%'); }
190 "<"            { count(); return('<'); }
191 ">"            { count(); return('>'); }
192 "^"            { count(); return('^'); }
193 "|"            { count(); return('|'); }
194 "?"            { count(); return('?'); }
195 ^#pragma.*"\n" { count(); process_pragma(yytext); }
196 ^(#line.*"\n")|(#.*"\n") { count(); checkCurrFile(yytext); }
197
198 ^[^(]+"("[0-9]+") : error"[^\n]+ { werror(E_PRE_PROC_FAILED, yytext); count(); }
199 ^[^(]+"("[0-9]+") : warning"[^\n]+ { werror(W_PRE_PROC_WARNING, yytext); count(); }
200 "\r\n"         { count(); }
201 "\n"           { count(); }
202 [ \t\v\f]      { count(); }
203 \\ {
204   int ch = input();
205   if (ch != '\n') {
206     /* that could have been removed by the preprocessor anyway */
207     werror (W_STRAY_BACKSLASH, column);
208     unput(ch);
209   }
210 }
211 .              { count(); }
212 %%
213
214 /* flex 2.5.31 undefines yytext_ptr, so we have to define it again */
215 #ifndef yytext_ptr
216 #define yytext_ptr yytext
217 #endif
218
219
220 static int checkCurrFile (char *s)
221 {
222     int  lNum;
223     char *tptr;
224
225     /* skip '#' character */
226     if (*s++ != '#')
227       return 0;
228
229     /* check if this is a #line
230        this is not standard and can be removed in the future */
231 #define LINE_STR  "line"
232 #define LINE_LEN  ((sizeof LINE_STR) - 1)
233
234     if (strncmp(s, LINE_STR, LINE_LEN) == 0)
235       s += LINE_LEN;
236
237     /* get the line number */
238     lNum = strtol(s, &tptr, 10);
239     if (tptr == s || !isspace(*tptr))
240       return 0;
241     s = tptr;
242
243     /* now see if we have a file name */
244     while (*s != '\"' && *s)
245       s++;
246
247     /* if we don't have a filename then */
248     /* set the current line number to   */
249     /* line number if printFlag is on   */
250     if (!*s) {
251       lineno = mylineno = lNum;
252       return 0;
253     }
254
255     /* if we have a filename then check */
256     /* if it is "standard in" if yes then */
257     /* get the currentfile name info    */
258     s++ ;
259
260     /* in c1mode fullSrcFileName is NULL */
261     if (fullSrcFileName &&
262          strncmp(s, fullSrcFileName, strlen(fullSrcFileName)) == 0) {
263       lineno = mylineno = lNum;
264       currFname = fullSrcFileName;
265     } else {
266         char *sb = s;
267         /* mark the end of the filename */
268         while (*s != '"') s++;
269         *s = '\0';
270         currFname = strdup (sb);
271         lineno = mylineno = lNum;
272     }
273     filename = currFname ;
274     return 0;
275 }
276
277 int column = 0;
278 int plineIdx =0;
279
280 static void count(void)
281 {
282   int i;
283   for (i = 0; yytext[i] != '\0'; i++) {
284     if (yytext[i] == '\n') {
285       column = 0;
286       lineno = ++mylineno;
287     }
288     else
289       if (yytext[i] == '\t')
290         column += 8 - (column % 8);
291       else
292         column++;
293   }
294   /* ECHO; */
295 }
296
297 static int check_type(void)
298 {
299   symbol *sym = findSym(SymbolTab, NULL, yytext);
300
301   /* check if it is in the table as a typedef */
302   if (!ignoreTypedefType && sym && IS_SPEC (sym->etype)
303       && SPEC_TYPEDEF (sym->etype)) {
304     strncpyz(yylval.yychar, yytext, SDCC_NAME_MAX);
305     return (TYPE_NAME);
306   }
307   else {
308     strncpyz (yylval.yychar, yytext, SDCC_NAME_MAX);
309     return(IDENTIFIER);
310   }
311 }
312
313 /*
314  * Change by JTV 2001-05-19 to not concantenate strings
315  * to support ANSI hex and octal escape sequences in string literals
316  */
317
318 static char *stringLiteral(void)
319 {
320 #define STR_BUF_CHUNCK_LEN  1024
321   int ch;
322   static struct dbuf_s dbuf;
323   char buf[2];
324
325   if (dbuf.alloc == 0)
326     dbuf_init(&dbuf, STR_BUF_CHUNCK_LEN);
327   else
328     dbuf_set_size(&dbuf, 0);
329
330   dbuf_append(&dbuf, "\"", 1);
331   /* put into the buffer till we hit the first \" */
332
333   while ((ch = input()) != 0) {
334     switch (ch) {
335     case '\\':
336       /* if it is a \ then escape char's are allowed */
337       ch = input();
338       if (ch == '\n') {
339         /* \<newline> is a continuator */
340         lineno = ++mylineno;
341         column = 0;
342       }
343       else {
344         buf[0] = '\\';
345         buf[1] = ch;
346         dbuf_append(&dbuf, buf, 2); /* get the escape char, no further check */
347       }
348       break; /* carry on */
349
350     case '\n':
351       /* if new line we have a new line break, which is illegal */
352       werror(W_NEWLINE_IN_STRING);
353       dbuf_append(&dbuf, "\n", 1);
354       lineno = ++mylineno;
355       column = 0;
356       break;
357
358     case '"':
359       /* if this is a quote then we have work to do */
360       /* find the next non whitespace character     */
361       /* if that is a double quote then carry on    */
362       dbuf_append(&dbuf, "\"", 1);  /* Pass end of this string or substring to evaluator */
363       while ((ch = input()) && (isspace(ch) || ch == '\\')) {
364         switch (ch) {
365         case '\\':
366           if ((ch = input()) != '\n') {
367             werror(W_STRAY_BACKSLASH, column);
368             unput(ch);
369           }
370           else {
371             lineno = ++mylineno;
372             column = 0;
373           }
374           break;
375
376         case '\n':
377           mylineno++;
378           break;
379         }
380       }
381
382       if (!ch)
383         goto out;
384
385       if (ch != '\"') {
386         unput(ch);
387         goto out;
388       }
389       break;
390
391     default:
392       buf[0] = ch;
393       dbuf_append(&dbuf, buf, 1);  /* Put next substring introducer into output string */
394     }
395   }
396
397 out:
398   return (char *)dbuf_c_str(&dbuf);
399 }
400
401
402 enum pragma_id {
403      P_SAVE = 1,
404      P_RESTORE,
405      P_NOINDUCTION,
406      P_NOINVARIANT,
407      P_INDUCTION,
408      P_STACKAUTO,
409      P_NOJTBOUND,
410      P_NOOVERLAY,
411      P_LESSPEDANTIC,
412      P_NOGCSE,
413      P_CALLEE_SAVES,
414      P_EXCLUDE,
415      P_NOIV,
416      P_LOOPREV,
417      P_OVERLAY_      /* I had a strange conflict with P_OVERLAY while */
418                      /* cross-compiling for MINGW32 with gcc 3.2 */
419 };
420
421
422 /* SAVE/RESTORE stack */
423 #define SAVE_RESTORE_SIZE 128
424
425 STACK_DCL(options_stack, struct options *, SAVE_RESTORE_SIZE)
426 STACK_DCL(optimize_stack, struct optimize *, SAVE_RESTORE_SIZE)
427
428 /*
429  * cloneXxx functions should be updated every time a new set is
430  * added to the options or optimize structure!
431  */
432
433 static struct options *cloneOptions(struct options *opt)
434 {
435   struct options *new_opt;
436
437   new_opt = Safe_malloc(sizeof (struct options));
438
439   /* clone scalar values */
440   *new_opt = *opt;
441
442   /* clone sets */
443   new_opt->calleeSavesSet = setFromSetNonRev(opt->calleeSavesSet);
444   new_opt->excludeRegsSet = setFromSetNonRev(opt->excludeRegsSet);
445   /* not implemented yet: */
446   /* new_opt->olaysSet = setFromSetNonRev(opt->olaysSet); */
447
448   return new_opt;
449 }
450
451 static struct optimize *cloneOptimize(struct optimize *opt)
452 {
453   struct optimize *new_opt;
454
455   new_opt = Safe_malloc(sizeof (struct options));
456
457   /* clone scalar values */
458   *new_opt = *opt;
459
460   return new_opt;
461 }
462
463 static void copyAndFreeOptions(struct options *dest, struct options *src)
464 {
465   /* delete dest sets */
466   deleteSet(&dest->calleeSavesSet);
467   deleteSet(&dest->excludeRegsSet);
468   /* not implemented yet: */
469   /* deleteSet(&dest->olaysSet); */
470
471   /* dopy src to dest */
472   *dest = *src;
473
474   Safe_free(src);
475 }
476
477 static void copyAndFreeOptimize(struct optimize *dest, struct optimize *src)
478 {
479   /* dopy src to dest */
480   *dest = *src;
481
482   Safe_free(src);
483 }
484
485 static void doPragma(int op, char *cp)
486 {
487   switch (op) {
488   case P_SAVE:
489     {
490       STACK_PUSH(options_stack, cloneOptions(&options));
491       STACK_PUSH(optimize_stack, cloneOptimize(&optimize));
492     }
493     break;
494
495   case P_RESTORE:
496     {
497       struct options *optionsp;
498       struct optimize *optimizep;
499
500       optionsp = STACK_POP(options_stack);
501       copyAndFreeOptions(&options, optionsp);
502
503       optimizep = STACK_POP(optimize_stack);
504       copyAndFreeOptimize(&optimize, optimizep);
505     }
506     break;
507
508   case P_NOINDUCTION:
509     optimize.loopInduction = 0;
510     break;
511
512   case P_NOINVARIANT:
513     optimize.loopInvariant = 0;
514     break;
515
516   case P_INDUCTION:
517     optimize.loopInduction = 1;
518     break;
519
520   case P_STACKAUTO:
521     options.stackAuto = 1;
522     break;
523
524   case P_NOJTBOUND:
525     optimize.noJTabBoundary = 1;
526     break;
527
528   case P_NOGCSE:
529     optimize.global_cse = 0;
530     break;
531
532   case P_NOOVERLAY:
533     options.noOverlay = 1;
534     break;
535
536   case P_LESSPEDANTIC:
537     options.lessPedantic = 1;
538     break;
539
540   case P_CALLEE_SAVES:
541     /* append to the functions already listed
542        in callee-saves */
543     setParseWithComma(&options.calleeSavesSet, cp);
544     break;
545
546   case P_EXCLUDE:
547     {
548       deleteSet(&options.excludeRegsSet);
549       setParseWithComma(&options.excludeRegsSet, cp);
550     }
551     break;
552
553   case P_NOIV:
554     options.noiv = 1;
555     break;
556
557   case P_LOOPREV:
558     optimize.noLoopReverse = 1;
559     break;
560
561   case P_OVERLAY_:
562     break; /* notyet */
563   }
564 }
565
566 static int process_pragma(char *s)
567 {
568 #define NELEM(x)    (sizeof (x) / sizeof (x)[0])
569 #define PRAGMA_STR  "#pragma"
570 #define PRAGMA_LEN  ((sizeof PRAGMA_STR) - 1)
571
572   static struct pragma_s
573     {
574       const char *name;
575       enum pragma_id id;
576       char deprecated;
577     } pragma_tbl[] = {
578     { "save",           P_SAVE,         0 },
579     { "restore",        P_RESTORE,      0 },
580     { "noinduction",    P_NOINDUCTION,  0 },
581     { "noinvariant",    P_NOINVARIANT,  0 },
582     { "noloopreverse",  P_LOOPREV,      0 },
583     { "induction",      P_INDUCTION,    0 },
584     { "stackauto",      P_STACKAUTO,    0 },
585     { "nojtbound",      P_NOJTBOUND,    0 },
586     { "nogcse",         P_NOGCSE,       0 },
587     { "nooverlay",      P_NOOVERLAY,    0 },
588     { "callee_saves",   P_CALLEE_SAVES, 0 },
589     { "exclude",        P_EXCLUDE,      0 },
590     { "noiv",           P_NOIV,         0 },
591     { "overlay",        P_OVERLAY_,     0 },
592     { "less_pedantic",  P_LESSPEDANTIC, 0 },
593
594     /*
595      * The following lines are deprecated pragmas,
596      * only for bacward compatibility.
597      * They should be removed in next major release after 1.4.0
598      */
599
600     { "SAVE",           P_SAVE,         1 },
601     { "RESTORE",        P_RESTORE,      1 },
602     { "NOINDUCTION",    P_NOINDUCTION,  1 },
603     { "NOINVARIANT",    P_NOINVARIANT,  1 },
604     { "NOLOOPREVERSE",  P_LOOPREV,      1 },
605     { "INDUCTION",      P_INDUCTION,    1 },
606     { "STACKAUTO",      P_STACKAUTO,    1 },
607     { "NOJTBOUND",      P_NOJTBOUND,    1 },
608     { "NOGCSE",         P_NOGCSE,       1 },
609     { "NOOVERLAY",      P_NOOVERLAY,    1 },
610     { "CALLEE-SAVES",   P_CALLEE_SAVES, 1 },
611     { "EXCLUDE",        P_EXCLUDE,      1 },
612     { "NOIV",           P_NOIV,         1 },
613     { "OVERLAY",        P_OVERLAY_,     1 },
614     { "LESS_PEDANTIC",  P_LESSPEDANTIC, 1 },
615   };
616   char *cp;
617   int i;
618
619   /* find the pragma */
620   while (strncmp(s, PRAGMA_STR, PRAGMA_LEN))
621     s++;
622   s += PRAGMA_LEN;
623
624   /* look for the directive */
625   while(isspace(*s))
626     s++;
627
628   cp = s;
629   /* look for the end of the directive */
630   while ((!isspace(*s)) && (*s != '\n'))
631     s++ ;
632
633   /* First give the port a chance */
634   if (port->process_pragma && !port->process_pragma(cp))
635     return 0;
636
637   for (i = 0; i < NELEM(pragma_tbl); i++)
638     {
639       /* now compare and do what needs to be done */
640       size_t len = strlen(pragma_tbl[i].name);
641
642       if (strncmp(cp, pragma_tbl[i].name, len) == 0)
643         {
644           if (pragma_tbl[i].deprecated != 0)
645             werror(W_DEPRECATED_PRAGMA, pragma_tbl[i].name);
646
647           doPragma(pragma_tbl[i].id, cp + len);
648           return 0;
649         }
650     }
651
652   werror(W_UNKNOWN_PRAGMA, cp);
653   return 0;
654 }
655
656 /* will return 1 if the string is a part
657    of a target specific keyword */
658 static int isTargetKeyword(char *s)
659 {
660   int i;
661
662   if (port->keywords == NULL)
663     return 0;
664   for (i = 0 ; port->keywords[i] ; i++ ) {
665     if (strcmp(port->keywords[i],s) == 0)
666       return 1;
667   }
668
669     return 0;
670 }
671
672 int yywrap(void)
673 {
674   if (!STACK_EMPTY(options_stack) || !STACK_EMPTY(optimize_stack))
675     werror(W_SAVE_RESTORE);
676
677   return 1;
678 }
679
680 int yyerror(char *s)
681 {
682   fflush(stdout);
683
684   if (mylineno && filename) {
685     if(options.vc_err_style)
686       fprintf(stderr, "\n%s(%d) : %s: token -> '%s' ; column %d\n",
687         filename, mylineno, s, yytext, column);
688     else
689       fprintf(stderr, "\n%s:%d: %s: token -> '%s' ; column %d\n",
690         filename, mylineno, s ,yytext, column);
691     fatalError++;
692   } else {
693     /* this comes from an empy file, no problem */
694   }
695   return 0;
696 }