]> git.draconx.ca Git - gob-dx.git/blob - src/lexer.l
Release 2.0.12
[gob-dx.git] / src / lexer.l
1 /* GOB C Preprocessor
2  * Copyright (C) 1999 the Free Software Foundation.
3  *
4  * Author: George Lebl
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any 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, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19  * USA.
20  */
21 %{
22
23 #include "config.h"
24 #include <stdlib.h>
25 #include <string.h>
26 #include <ctype.h>
27 #include <glib.h>
28
29 #include "treefuncs.h"
30 #include "parse.h"
31 #include "main.h"
32 #include "util.h"
33
34 static int parenth_depth = 0;
35 static int before_comment
36 /* New flex is on drugs */
37 #if defined(FLEX_SCANNER) && ! defined(INITIAL)
38         = 0;
39 #else
40         = INITIAL;
41 #endif
42 static gboolean class_after_c = FALSE;
43 static int code_type = CCODE;
44 static int before_string;
45 static int property_paren_depth = 0;
46
47 /* GTK+ doc stuff */
48 static char *gtk_doc_func = NULL; /* current gtk-doc func */
49 GHashTable *gtk_doc_hash = NULL;
50
51 static GString *cbuf = NULL;
52 int ccode_line = 1;
53
54 GList *include_files = NULL;
55 /* 0 no, 1 means yes, 2+ means don't even start looking anymore */
56 static int look_for_includes = 0;
57
58 int line_no = 1;
59 /* last filename parsed from a #line directive */
60 char *hline_filename = NULL;
61
62 static void
63 clear_cbuf(void)
64 {
65         if(!cbuf) {
66                 cbuf = g_string_new(NULL);
67         } else {
68                 cbuf = g_string_assign(cbuf, "");
69         }
70 }
71
72 static void
73 add_to_cbuf(char *s)
74 {
75         if(!cbuf) {
76                 cbuf = g_string_new(s);
77         } else {
78                 cbuf = g_string_append(cbuf,s);
79         }
80 }
81
82 static void
83 add_gtk_doc_func(void)
84 {
85         if(!gtk_doc_func)
86                 return;
87
88         if(!gtk_doc_hash)
89                 gtk_doc_hash = g_hash_table_new(g_str_hash, g_str_equal);
90         g_hash_table_insert(gtk_doc_hash, gtk_doc_func, g_strdup(cbuf->str));
91         clear_cbuf();
92
93         gtk_doc_func = NULL;
94 }
95
96 /* Ugly warning avoiding */
97 #ifdef FLEX_SCANNER
98 int yylex(void);
99 #endif
100
101 %}
102
103 %x COMMENT
104 %x C_CODE
105 %x CODE_STRING
106 %x CLASS_CODE
107 %x CLASS_STRING
108 %x CLASS_CODE_I
109 %x PROPERTY_CODE
110 %x PROPERTY_CODE_I
111 %x GTK_DOC_BEFORE_NAME
112 %x GTK_DOC
113 %x GTK_DOC_LINE
114
115
116
117 %%
118
119 %{
120 /* Avoid warning from flex, cuz flex sucks */
121 #ifdef FLEX_SCANNER
122 yy_current_state = 0;
123 #endif
124 %}
125
126
127 <*>\n                   { line_no++; REJECT; }
128
129 <COMMENT>^(I(S.RI).E\(([1-9][0-9]+|[2-9]))/(\)) {
130 /* Thy evil easter egg */
131 #define QQ(x) long x
132 #define KK(x) =atoi(__(&,,x,))
133 #define MM(x,a) {QQ(i);for(i=2;i<x;i++){a}}
134 #define PP(Q) (P%Q)==0
135 #define ___(x,y,z) if(x z y)
136 #define __(a,x,y,z) a(yytext[y] x z)
137 #define O__O(a,b) fprintf(stderr,"%s is %s!\n",a,b)
138 QQ(m)=1;___(__(,==,2,'P'),__(,==,5,'M'),&&
139 ){QQ(P)KK(8);MM(P,___(PP(i),,)m=0;)}__(,=,
140 7,0);___(,,m){O__O(__( &,,8,),__(&,,2,));}
141 #undef QQ
142 #undef KK
143 #undef MM
144 #undef PP
145 #undef ___
146 #undef __
147 #undef O__O
148 REJECT;
149 }
150
151 \/\/.*$                 { ; /*comment, ignore*/ }
152
153 <*>^#[ \t]*line[ \t]+[0-9]+([ \t]\"[^\n\r\f\"]*\")? {
154         char *p;
155         char *number;
156         char *filename;
157         char *str=g_strdup(yytext);
158
159         /* find first digit of line number */
160         p=str;
161         while(*p&&!isdigit(*p)) p++;
162         number=p;
163   
164         /* find end of line number */
165         while(*p&&isdigit(*p)) p++;
166         if(*p) *p++=0;
167
168         /* find beginning of filename */
169         p=strchr(p,'"');
170         if(p) p++;
171         filename=p;
172
173         /* find end of filename */
174         if(p) p=strchr(p,'"');
175         if(p) *p=0;
176
177         /* stash number (minus one because we don't count this line) */  
178         if(number) line_no=atoi(number)-1;
179
180         /* stash filename */
181         if(filename) {
182                 if(hline_filename) g_free(hline_filename);
183                 hline_filename=g_strdup(filename);
184         }
185   
186         /* clean up */
187         g_free(str);
188 }
189
190 <C_CODE>^#[ \t]*include[ \t][<"][^\n">]*[>"] {
191         if(look_for_includes==1) {
192                 char *p;
193                 char *file;
194                 char *str = g_strdup(yytext);
195                 file = strchr(str,'"');
196                 if(!file) file = strchr(str,'<');
197                 file++;
198                 p = strchr(file,'"');
199                 if(!p) p = strchr(file,'>');
200                 *p = '\0';
201                 include_files = g_list_prepend(include_files,g_strdup(file));
202                 g_free(str);
203         }
204         REJECT;
205 }
206
207 <CLASS_CODE_I>\/\*\*[ \t]*$     {
208                         /* eat out gtk doc stuff */
209                         BEGIN(GTK_DOC_BEFORE_NAME);
210                         clear_cbuf();
211                 }
212 <GTK_DOC_BEFORE_NAME>^[ \t]*\*[ \t]*$   {
213                         /* empty doc lines */
214                         ;
215                 }       
216 <GTK_DOC_BEFORE_NAME>^[ \t]*\*\ [_a-zA-Z][_a-zA-Z0-9]*:?[ \t]*$ {
217                         char *p;
218                         BEGIN(GTK_DOC);
219                         p = strchr(yytext, '*');
220                         g_free(gtk_doc_func);
221                         gtk_doc_func = g_strdup(p+2);
222                         p = strchr(gtk_doc_func, ':');
223                         if(p) *p='\0';
224                         g_strstrip(gtk_doc_func);
225                 }
226 <GTK_DOC_BEFORE_NAME>\*\/       {
227                         BEGIN(CLASS_CODE_I);
228                 }
229 <GTK_DOC_BEFORE_NAME>.  {
230                         BEGIN(COMMENT);
231                         before_comment = CLASS_CODE_I;
232                 }
233 <GTK_DOC>^[ \t]*\*[ \t]*$       {
234                         /* empty doc lines */
235                         add_to_cbuf(" *\n");
236                 }       
237 <GTK_DOC>^[ \t]*\*?\*\/ {
238                         BEGIN(CLASS_CODE_I);
239                         add_gtk_doc_func();
240                 }
241 <GTK_DOC>^[ \t]*\*[ \t] {
242                         fflush(stdout);
243                         add_to_cbuf(" * ");
244                         BEGIN(GTK_DOC_LINE);
245                 }
246 <GTK_DOC>\*\/   {
247                         BEGIN(CLASS_CODE_I);
248                 }
249 <GTK_DOC>.      {
250                         BEGIN(COMMENT);
251                         before_comment = CLASS_CODE_I;
252                 }
253 <GTK_DOC_LINE>\*\/      {
254                         BEGIN(CLASS_CODE_I);
255                         add_to_cbuf("\n");
256                         add_gtk_doc_func();
257                 }
258 <GTK_DOC_LINE>.$        {
259                         BEGIN(GTK_DOC);
260                         add_to_cbuf(yytext);
261                         add_to_cbuf("\n");
262                 }
263 <GTK_DOC_LINE>. {
264                         fflush(stdout);
265                         add_to_cbuf(yytext);
266                 }
267
268 <C_CODE>\/\/.*$         { add_to_cbuf(yytext); /*comment, ignore*/ }
269 <CLASS_CODE>\/\/.*$     { ; /*comment, ignore*/ }
270 <CLASS_CODE_I>\/\/.*$   { ; /*comment, ignore*/ }
271 <PROPERTY_CODE_I>\/\/.*$        { ; /*comment, ignore*/ }
272 \/\*            {BEGIN(COMMENT); before_comment = INITIAL; }
273 <C_CODE>\/\*    {
274         add_to_cbuf(yytext);
275         BEGIN(COMMENT);
276         before_comment = C_CODE;
277 }
278 <CLASS_CODE>\/\*        {BEGIN(COMMENT); before_comment = CLASS_CODE; }
279 <CLASS_CODE_I>\/\*      {BEGIN(COMMENT); before_comment = CLASS_CODE_I; }
280 <PROPERTY_CODE_I>\/\*   {BEGIN(COMMENT); before_comment = PROPERTY_CODE_I; }
281 <COMMENT>\*\/   {
282         if(before_comment == C_CODE) add_to_cbuf(yytext);
283         BEGIN(before_comment);
284                 }
285 <COMMENT>.      {
286         /* comment, ignore */
287         if(before_comment == C_CODE) add_to_cbuf(yytext);
288                 }
289 <COMMENT>\n     {
290         /* comment, ignore */
291         if(before_comment == C_CODE) add_to_cbuf(yytext);
292                 }
293
294 ^\%(a|all)\{            {
295                         BEGIN(C_CODE);
296                         parenth_depth = 1;
297                         class_after_c = FALSE;
298                         code_type = ACODE;
299                         clear_cbuf();
300                         ccode_line = line_no;
301                 }
302 ^\%(at|alltop)\{                {
303                         BEGIN(C_CODE);
304                         parenth_depth = 1;
305                         class_after_c = FALSE;
306                         code_type = ATCODE;
307                         clear_cbuf();
308                         ccode_line = line_no;
309                 }
310
311 ^\%(ht|headertop)\{             {
312                         BEGIN(C_CODE);
313                         parenth_depth = 1;
314                         class_after_c = FALSE;
315                         code_type = HTCODE;
316                         clear_cbuf();
317                         ccode_line = line_no;
318                 }
319 ^\%(ph|privateheader)\{         {
320                         BEGIN(C_CODE);
321                         parenth_depth = 1;
322                         class_after_c = FALSE;
323                         code_type = PHCODE;
324                         clear_cbuf();
325                         ccode_line = line_no;
326                 }
327 ^\%(h|header)\{         {
328                         BEGIN(C_CODE);
329                         parenth_depth = 1;
330                         class_after_c = FALSE;
331                         code_type = HCODE;
332                         clear_cbuf();
333                         ccode_line = line_no;
334                 }
335 ^\%\{           {
336                         BEGIN(C_CODE);
337                         parenth_depth = 1;
338                         class_after_c = FALSE;
339                         code_type = CCODE;
340                         clear_cbuf();
341                         ccode_line = line_no;
342                         if(look_for_includes==0)
343                                 look_for_includes=1;
344                 }
345 <C_CODE>^\%\}   {
346                         BEGIN(INITIAL);
347                         yylval.cbuf = cbuf;
348                         cbuf = NULL;
349                         if(look_for_includes==1)
350                                 look_for_includes=0;
351                         return code_type;
352                 }
353
354 <C_CODE>\'\{\'          { add_to_cbuf(yytext); }
355 <C_CODE>\'\\\{\'        { add_to_cbuf(yytext); }
356 <C_CODE>\'\}\'          { add_to_cbuf(yytext); }
357 <C_CODE>\'\\\}\'        { add_to_cbuf(yytext); }
358 <C_CODE>\'\"\'          { add_to_cbuf(yytext); }
359 <C_CODE>\'\\\"\'        { add_to_cbuf(yytext); }
360         
361 <C_CODE>\\.     { add_to_cbuf(yytext); }
362
363
364 <C_CODE>\"      {
365                         BEGIN(CODE_STRING);
366                         before_string = C_CODE;
367                         add_to_cbuf(yytext);
368                 }
369 <PROPERTY_CODE_I>\"     {
370                         BEGIN(CODE_STRING);
371                         before_string = PROPERTY_CODE_I;
372                         add_to_cbuf(yytext);
373                 }
374 <CODE_STRING>\\.        { add_to_cbuf(yytext); }
375 <CODE_STRING>\" {
376                         BEGIN(before_string);
377                         add_to_cbuf(yytext);
378                         if (before_string == PROPERTY_CODE_I) {
379                                 yylval.id = cbuf->str;
380                                 g_string_free (cbuf, FALSE);
381                                 cbuf = NULL;
382                                 return STRING;
383                         }
384                 }
385 <CODE_STRING>.  { add_to_cbuf(yytext); }
386 <CODE_STRING>\n { add_to_cbuf(yytext); }
387
388 <C_CODE>\{      {
389                         parenth_depth++;
390                         add_to_cbuf(yytext);
391                 }
392 <C_CODE>\}      {
393                         parenth_depth--;
394                         if(parenth_depth<0) {
395                                 REJECT;
396                         } else if(parenth_depth==0 && class_after_c) {
397                                 BEGIN(CLASS_CODE_I);
398                                 yylval.cbuf = cbuf;
399                                 cbuf = NULL;
400                                 return CCODE;
401                         }
402                         add_to_cbuf(yytext);
403                 }
404
405 <C_CODE>.       { add_to_cbuf(yytext); }
406 <C_CODE>\n      { add_to_cbuf(yytext); }
407
408 class           {
409                         static int found_classes = 0;
410                         look_for_includes = 2;
411                         BEGIN(CLASS_CODE);
412
413                         if(++found_classes > 1) {
414                                 error_print(GOB_ERROR, line_no,
415                                             "Only one class per file allowed");
416                         }
417
418                         return CLASS;
419                 }
420
421 error           { return ERROR; }
422 enum            { return ENUM; }
423 flags           { return FLAGS; }
424
425 ^[ \t]*requires[ \t]+[0-9]+\.[0-9]+\.[0-9]+[\t ]*$      {
426                         int maj = 0, min = 0, pl = 0;
427                         int rmaj = 0, rmin = 0, rpl = 0;
428                         int effective_maj = 0;
429                         int effective_rmaj = 0;
430                         char *p;
431                         
432                         sscanf (VERSION, "%d.%d.%d", &rmaj, &rmin, &rpl);
433                         effective_rmaj = rmaj;
434                         if (rmin >= 90)
435                                 effective_rmaj = rmaj + 1;
436
437                         p = strchr (yytext,'r');
438                         g_assert (p); /* we MUST have found it */
439                         sscanf (p, "requires %d.%d.%d", &maj, &min, &pl);
440                         effective_maj = maj;
441                         if (min >= 90)
442                                 effective_maj = maj + 1;
443
444                         if(rmaj < maj ||
445                            (rmaj == maj && rmin < min) ||
446                            (rmaj == maj && rmin == min && rpl < pl)) {
447                                 error_printf (GOB_ERROR, line_no,
448                                               "GOB version at least %d.%d.%d required "
449                                               "(this is %s)\n"
450                                               "To upgrade your gob, see: "
451                                               "http://www.5z.com/jirka/gob.html",
452                                               maj, min, pl, VERSION);
453                         }
454
455                         if(effective_rmaj != effective_maj) {
456                                 error_printf(GOB_ERROR, line_no,
457                                              "GOB major version %d required "
458                                              "(this is %s)\n"
459                                              "To upgrade your gob, see: "
460                                              "http://www.5z.com/jirka/gob.html",
461                                              effective_maj, VERSION);
462                         }
463
464                 }
465
466 <CLASS_CODE,CLASS_CODE_I>class|this     {
467                         if(for_cpp) {
468                                 error_printf(GOB_WARN, line_no,
469                                              "'%s' keyword should not "
470                                              "be used when generating "
471                                              "C++ code", yytext);
472                         }
473                         REJECT;
474                 }
475
476 <CLASS_CODE>from        {return FROM;}
477 <CLASS_CODE>\"  {
478                         BEGIN(CLASS_STRING);
479                         before_string = CLASS_CODE;
480                         add_to_cbuf(yytext);
481                 }
482 <CLASS_STRING>\\.       { add_to_cbuf(yytext); }
483 <CLASS_STRING>\"        {
484                         BEGIN(before_string);
485                         add_to_cbuf(yytext);
486                         yylval.id = cbuf->str;
487                         g_string_free (cbuf, FALSE);
488                         cbuf = NULL;
489                         return STRING;
490                 }
491 <CLASS_STRING>. { add_to_cbuf(yytext); }
492 <CLASS_STRING>\n        { add_to_cbuf(yytext); }
493
494 <CLASS_CODE_I,PROPERTY_CODE_I>void      {return VOID;}
495 <CLASS_CODE_I,PROPERTY_CODE_I>struct    {return STRUCT;}
496 <CLASS_CODE_I,PROPERTY_CODE_I>union     {return UNION;}
497 <CLASS_CODE_I,PROPERTY_CODE_I>enum      {return ENUM;}
498 <CLASS_CODE_I,PROPERTY_CODE_I>signed    {return SIGNED;}
499 <CLASS_CODE_I,PROPERTY_CODE_I>unsigned  {return UNSIGNED;}
500 <CLASS_CODE_I,PROPERTY_CODE_I>long      {return LONG;}
501 <CLASS_CODE_I,PROPERTY_CODE_I>short     {return SHORT;}
502 <CLASS_CODE_I,PROPERTY_CODE_I>int       {return INT;}
503 <CLASS_CODE_I,PROPERTY_CODE_I>float     {return FLOAT;}
504 <CLASS_CODE_I,PROPERTY_CODE_I>double    {return DOUBLE;}
505 <CLASS_CODE_I,PROPERTY_CODE_I>char      {return CHAR;}
506 <CLASS_CODE_I,PROPERTY_CODE_I>const     {return CONST;}
507
508 <CLASS_CODE_I>\.\.\.    {return THREEDOTS;}
509
510 <CLASS_CODE_I>public    {yylval.line = line_no; return PUBLIC;}
511 <CLASS_CODE_I>private   {yylval.line = line_no; return PRIVATE;}
512 <CLASS_CODE_I>protected {yylval.line = line_no; return PROTECTED;}
513 <CLASS_CODE_I>classwide {yylval.line = line_no; return CLASSWIDE;}
514 <CLASS_CODE_I>argument  {yylval.line = line_no; return ARGUMENT;}
515 <CLASS_CODE_I>virtual   {yylval.line = line_no; return VIRTUAL;}
516 <CLASS_CODE_I>signal    {yylval.line = line_no; return SIGNAL;}
517 <CLASS_CODE_I>override  {yylval.line = line_no; return OVERRIDE;}
518 <CLASS_CODE_I>property  {
519                                 yylval.line = line_no;
520                                 BEGIN(PROPERTY_CODE);
521                                 return PROPERTY;
522                         }
523 <PROPERTY_CODE_I>nick   { yylval.line = line_no; return NICK; }
524 <PROPERTY_CODE_I>blurb  { yylval.line = line_no; return BLURB; }
525 <PROPERTY_CODE_I>maximum        { yylval.line = line_no; return MAXIMUM; }
526 <PROPERTY_CODE_I>minimum        { yylval.line = line_no; return MINIMUM; }
527 <PROPERTY_CODE_I>default_value  { yylval.line = line_no; return DEFAULT_VALUE; }
528 <PROPERTY_CODE_I>flags  { yylval.line = line_no; return FLAGS; }
529 <PROPERTY_CODE_I>type   { yylval.line = line_no; return TYPE; }
530 <PROPERTY_CODE_I>flags_type     { yylval.line = line_no; return FLAGS_TYPE; }
531 <PROPERTY_CODE_I>enum_type      { yylval.line = line_no; return ENUM_TYPE; }
532 <PROPERTY_CODE_I>param_type     { yylval.line = line_no; return PARAM_TYPE; }
533 <PROPERTY_CODE_I>boxed_type     { yylval.line = line_no; return BOXED_TYPE; }
534 <PROPERTY_CODE_I>object_type    { yylval.line = line_no; return OBJECT_TYPE; }
535 <PROPERTY_CODE>[(]      {
536                 yylval.line = line_no;
537                 property_paren_depth = 1;
538                 BEGIN(PROPERTY_CODE_I);
539                 return '(';
540                         }
541 <PROPERTY_CODE_I>[(]    {
542                 yylval.line = line_no;
543                 property_paren_depth++;
544                 return '(';
545                         }
546 <PROPERTY_CODE_I>[)]    {
547                 yylval.line = line_no;
548                 property_paren_depth--;
549                 if (property_paren_depth == 0) {
550                         BEGIN(CLASS_CODE_I);
551                 }
552                 return ')';
553                         }
554
555 <CLASS_CODE,CLASS_CODE_I,PROPERTY_CODE,PROPERTY_CODE_I,INITIAL>0|[1-9][0-9]*|0x[0-9a-fA-F]+|0[0-7]+|[0-9]*\.[0-9]+|\.[0-9][0-9]*        {
556                         yylval.id = g_strdup(yytext);
557                         return NUMBER;
558                 }
559 <CLASS_CODE,CLASS_CODE_I,PROPERTY_CODE,PROPERTY_CODE_I,INITIAL>[A-Za-z_][A-Za-z0-9_]*(::[A-Za-z0-9_]*)+ {
560                         /* This is cpp kind of token thingie */
561                         if (for_cpp) {
562                                 yylval.id = g_strdup(yytext);
563                                 return TOKEN;
564                         } else {
565                                 REJECT;
566                         }
567                 }
568 <CLASS_CODE,CLASS_CODE_I,PROPERTY_CODE,PROPERTY_CODE_I,INITIAL>[A-Za-z_][A-Za-z0-9_]*(:[A-Za-z_][A-Za-z0-9_]*)+ {
569                         /* this one is for a classname with a namespace */
570                         yylval.id = g_strdup(yytext);
571                         return TYPETOKEN;
572                 }
573 <CLASS_CODE,CLASS_CODE_I,PROPERTY_CODE,PROPERTY_CODE_I,INITIAL>:[A-Za-z_][A-Za-z0-9_]*(:[A-Za-z_][A-Za-z0-9_]*)*        {
574                         /* this is for a classname with an empty namespace */
575                         yylval.id = g_strdup(yytext);
576                         return TYPETOKEN;
577                 }
578 <CLASS_CODE,CLASS_CODE_I,PROPERTY_CODE,PROPERTY_CODE_I,INITIAL>[A-Za-z_][A-Za-z0-9_]*   {
579                         yylval.id = g_strdup(yytext);
580                         return TOKEN;
581                 }
582 <CLASS_CODE,CLASS_CODE_I,PROPERTY_CODE,PROPERTY_CODE_I,INITIAL>\'\\.\'|\'.\'    {
583                         yylval.id = g_strdup(yytext);
584                         return SINGLE_CHAR;
585                 }
586
587 <CLASS_CODE_I>(\[[0-9]*\]|\[[A-Za-z_][A-Za-z0-9_]*\])+  {
588                         yylval.id = g_strdup(yytext);
589                         return ARRAY_DIM;
590                 }
591 <CLASS_CODE_I>:[0-9]+ {
592                         /* cheat for bitfield */
593                         yylval.id = g_strdup(yytext);
594                         return ARRAY_DIM;
595                 }
596 <CLASS_CODE>\{  {
597                         BEGIN(CLASS_CODE_I);
598                         return '{';
599                 }
600 <CLASS_CODE_I,PROPERTY_CODE>\{  {
601                         BEGIN(C_CODE);
602                         parenth_depth=1;
603                         class_after_c = TRUE;
604                         yylval.line = line_no;
605                         clear_cbuf();
606                         ccode_line = line_no;
607                         return '{';
608                 }
609 <CLASS_CODE_I>\}        {
610                                 BEGIN(INITIAL);
611                                 return '}';
612                         }
613
614 <CLASS_CODE,CLASS_CODE_I,INITIAL,PROPERTY_CODE,PROPERTY_CODE_I>[\f\t ]  ;  /*ignore*/
615
616 <*>.            {
617                         yylval.line = line_no;
618                         return yytext[0];
619                 }
620
621 <*>[\n\r]       ;  /*ignore*/
622
623 ^[ \t]*prealloc[ \t]+[0-9]+[ \t]*$ {
624                         char *p;
625                         int t;
626                         p = strchr (yytext,'p');
627                         g_assert (p); /* we MUST have found it */
628                         sscanf (p, "prealloc %d", &t);
629                         prealloc=t;
630                 }
631
632 %%