wip II
[sdk] / compiler / libec / src / lexer.l
1 D         [0-9]
2 L         [a-zA-Z_]
3 H         [a-fA-F0-9]
4 E         [Ee][+-]?{D}+
5 FS         (f|F|l|L)
6 IS         (u|U|l|L)*
7 IDENT    {L}({L}|{D})*
8
9 %{
10 import "ecdefs"
11 #define YYLTYPE Location
12 #define YY_NEVER_INTERACTIVE 1    // Avoid calling isatty on eC File object
13
14 #include "grammar.h"
15
16 bool echoOn = true;
17 public void SetEchoOn(bool b) { echoOn = b; }
18
19 extern YYLTYPE type_yylloc;
20 extern YYLTYPE expression_yylloc;
21
22 extern File fileInput;
23 int preprocessor();
24 int comment();
25
26 void TESTTTT()
27 {
28    yylloc.end.charPos += yyleng;
29    yylloc.end.pos += yyleng;
30    type_yylloc.end.charPos += yyleng;
31    type_yylloc.end.pos += yyleng;
32    expression_yylloc.end.charPos += yyleng;
33    expression_yylloc.end.pos += yyleng;
34 }
35
36 #define YY_USER_ACTION  \
37    TESTTTT();
38
39    /*
40    yylloc.end.charPos += yyleng;
41    yylloc.end.pos += yyleng;
42    */
43
44 #define YY_INPUT(buf,result,max_size) \
45    result = fileInput.Read(buf, 1, max_size) \
46
47 YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
48 File fileStack[MAX_INCLUDE_DEPTH];
49 char sourceFileStack[MAX_INCLUDE_DEPTH][MAX_LOCATION];
50 public void SetSomeSourceFileStack(char * fileName, int index) { strcpy(sourceFileStack[index], fileName); }
51 YYLTYPE locStack[MAX_INCLUDE_DEPTH];
52 AccessMode declModeStack[MAX_INCLUDE_DEPTH];
53 int include_stack_ptr = 0;
54
55 #define uint _uint
56 default:
57
58 %}
59
60 %%
61
62 %{
63    yylloc.start = yylloc.end; 
64    type_yylloc.start = type_yylloc.end; 
65    expression_yylloc.start = expression_yylloc.end; 
66 %}
67
68 "#"                  { preprocessor(); }
69 "/*"                 { comment(); }
70 "//"                 { commentCPP(); }
71
72 "auto"               { return(AUTO); }
73 "break"              { return(BREAK); }
74 "case"               { return(CASE); }
75 "char"               { return(CHAR); }
76 "const"              { return(CONST); }
77 "continue"           { return(CONTINUE); }
78 "default"            { return(DEFAULT); }
79 "do"                 { return(DO); }
80 "double"             { return(DOUBLE); }
81 "else"               { return(ELSE); }
82 "enum"               { return(ENUM); }
83 "extern"             { return(EXTERN); }
84 "float"              { return(FLOAT); }
85 "for"                { return(FOR); }
86 "goto"               { return(GOTO); }
87 "if"                 { return(IF); }
88 "int"                { return(INT); }
89 "uint"               { return(UINT); }
90  /* "uint16"            { return(UINT16); } */
91  /* "uint32"            { return(UINT32); } */
92  /* "bool"              { return(BOOL_TOKEN); } */
93 "long"               { return(LONG); }
94 "register"           { return(REGISTER); }
95 "return"             { return(RETURN); }
96 "short"              { return(SHORT); }
97 "signed"             { return(SIGNED); }
98 "__signed"           { return(SIGNED); }
99 "__signed__"         { return(SIGNED); }
100 "sizeof"             { return(SIZEOF); }
101 "__alignof__"        { return(ALIGNOF); }
102 "static"             { return(STATIC); }
103 "struct"             { return(STRUCT); }
104 "switch"             { return(SWITCH); }
105 "typedef"            { return(TYPEDEF); }
106 "union"              { return(UNION); }
107 "unsigned"           { return(UNSIGNED); }
108 "void"               { return(VOID); }
109 "volatile"           { return(VOLATILE); }
110 "__volatile__"       { return(VOLATILE); }
111 "__volatile"         { return(VOLATILE); }
112 "while"              { return(WHILE); }
113
114 "property"           { return(PROPERTY); }
115 "set"                { return(SETPROP); }    // TODO: Don't make this a keyword...
116 "get"                { return(GETPROP); }    // TODO: Don't make this a keyword...
117 "isset"              { return(ISPROPSET); }    // TODO: Don't make this a keyword...
118 "class"              { return(CLASS); }
119 "thisclass"          { return(THISCLASS); }
120 "virtual"            { return(VIRTUAL); }
121 "delete"             { return(DELETE); }
122 "new"                { return(NEWOP); }
123 "new0"               { return(NEW0OP); }
124 "renew"              { return(RENEW); }
125 "renew0"             { return(RENEW0); }
126 "import"             { return(IMPORT); }
127 "define"             { return(DEFINE); }
128 "__int64"            { return(INT64); }
129 "int64"              { return(INT64); }
130 "__builtin_va_list"  { return(VALIST); }
131 "__builtin_va_arg"   { return(VAARG); }
132
133  /* "__attribute__".?"(("({D}|{L})*"))" { return(EXT_ATTRIB); } */
134
135  /* DID I MEAN? "__attribute__"" "*"(("" "*({D}|{L})*" "*("("({D}|{L})*(" "*","" "*({D}|{L})*)*" "*")")?" "*"))" { return(EXT_ATTRIB); } */
136
137  /*
138  "__attribute_deprecated__"(" "*)"(("(" "*)({D}|{L})*(" "*)("("({D}|{L}|\")*((" "*)","(" "*)({D}|{L}|\")*)*(" "*)")")?(" "*)(","(" "*)({D}|{L})*(" "*)("("({D}|{L}|\")*((" "*)","(" "*)({D}|{L}|\")*)*(" "*)")")?(" "*))*"))" { return(EXT_ATTRIB); }
139  "__attribute__"           (" "*)"(("(" "*)({D}|{L})*(" "*)("("({D}|{L}|\")*((" "*)","(" "*)({D}|{L}|\")*)*(" "*)")")?(" "*)(","(" "*)({D}|{L})*(" "*)("("({D}|{L}|\")*((" "*)","(" "*)({D}|{L}|\")*)*(" "*)")")?(" "*))*"))" { return(EXT_ATTRIB); }
140  "__attribute"             (" "*)"(("(" "*)({D}|{L})*(" "*)("("({D}|{L}|\")*((" "*)","(" "*)({D}|{L}|\")*)*(" "*)")")?(" "*)(","(" "*)({D}|{L})*(" "*)("("({D}|{L}|\")*((" "*)","(" "*)({D}|{L}|\")*)*(" "*)")")?(" "*))*"))" { return(EXT_ATTRIB); }
141  */
142  /*
143  [__attribute__] [spaces]
144    [((] [spaces] 
145       [digits | letters] [spaces]
146          ( [(]  [digits or letters or "]  ( [spaces] [,] [spaces] [digits or letters or "] )*  [spaces]  [)] )?
147       [spaces]
148       ( [,] [spaces]  [digits or letters]  [spaces]
149          ( [(]  [digits or letters or "]
150             ( [spaces] [,] [spaces] [digits or letters or "] )*  [spaces] [)]
151          )? [spaces] 
152       )*
153    [))]
154  */
155  /* "__attribute__".?"((".?({D}|{L})*.?("("({D}|{L})*(.?",".?({D}|{L})*)*.?")")?.?"))" { return(EXT_ATTRIB); } */
156  /* "__attribute".?"((".?({D}|{L})*.?("("({D}|{L})*(.?",".?({D}|{L})*)*.?")")?.?"))" { return(EXT_ATTRIB); }*/
157
158 "__attribute_deprecated__" { return ATTRIB_DEP; }
159 "__attribute__" { return ATTRIB; }
160 "__attribute" { return __ATTRIB; }
161
162 "__inline__"               { return(EXT_STORAGE); }
163 "_inline"                  { return(EXT_STORAGE); }
164 "__inline"                 { return(EXT_STORAGE); }
165 "inline"                   { return(EXT_STORAGE); }
166 "__declspec("({D}|{L})*")" { return(EXT_STORAGE); }
167 "dllexport"                { return(EXT_STORAGE); }
168 "dllimport"                { return(EXT_STORAGE); }
169 "__cdecl"                  { return(EXT_DECL); }
170 "__stdcall"                { return(EXT_DECL); }
171 "__stdcall__"              { return(EXT_DECL); }
172 "_stdcall"                 { return(EXT_DECL); }
173 "stdcall"                  { return(EXT_DECL); }
174 "__restrict"               { return(EXT_DECL); }
175 "__const"                  { return(EXT_DECL); }
176 "__restrict__"             { return(EXT_DECL); }
177 "public"                   { return(PUBLIC); }
178 "private"                  { return(PRIVATE); }
179 "typed_object"             { return(TYPED_OBJECT); }
180 "any_object"               { return(ANY_OBJECT); }
181 "incref"                   { return(_INCREF); }
182 "__extension__"            { return(EXTENSION); }
183 "_extension_"              { return(EXTENSION); }
184 "__asm__"                  { return(ASM); }
185 "asm"                      { return(ASM); }
186 "__asm"                    { return(ASM); }
187 "__typeof"                 { return(TYPEOF); }
188 "watch"                    { return(WATCH); }
189 "stopwatching"             { return(STOPWATCHING); }
190 "firewatchers"             { return(FIREWATCHERS); }
191 "watchable"                { return(WATCHABLE); }
192 "class_designer"           { return(CLASS_DESIGNER); }
193 "class_no_expansion"       { return(CLASS_NO_EXPANSION); }
194 "class_fixed"              { return(CLASS_FIXED); }
195 "class_default_property"   { return(CLASS_DEFAULT_PROPERTY); }
196 "property_category"        { return(PROPERTY_CATEGORY); }
197 "class_data"               { return(CLASS_DATA); }
198 "class_property"           { return(CLASS_PROPERTY); }
199 "subclass"                 { return(SUBCLASS); }
200 "namespace"                { return(NAMESPACE); }
201 "dbtable"                  { return(DBTABLE); }
202 "dbfield"                  { return(DBFIELD); }
203 "dbindex"                  { return(DBINDEX); }
204 "database_open"            { return(DATABASE_OPEN); }
205       
206 ("::"|(({IDENT}"&"?"::")*)){IDENT}?    { return(check_type()); }     // {L}({L}|{D})*      { return(check_type()); }  // ("::"|(({IDENT}"::")*)){IDENT}  { return(check_type()); }     // {L}({L}|{D})*      { return(check_type()); }
207
208 0[xX]{H}+{IS}?          { return(CONSTANT); }
209 0{D}+{IS}?              { return(CONSTANT); }
210 {D}+{IS}?               { return(CONSTANT); }
211 L?'(\\.|[^\\'])+'       { return(CONSTANT); }
212
213 {D}+{E}{FS}?            { return(CONSTANT); }
214 {D}*"."{D}+({E})?{FS}?  { return(CONSTANT); }
215 {D}+"."{D}*({E})?{FS}?  { return(CONSTANT); }
216
217 L?\"(\\.|[^\\"])*\"     { return(STRING_LITERAL); }
218
219 "..."       { return(ELLIPSIS); }
220 ">>="       { return(RIGHT_ASSIGN); }
221 "<<="       { return(LEFT_ASSIGN); }
222 "+="        { return(ADD_ASSIGN); }
223 "-="        { return(SUB_ASSIGN); }
224 "*="        { return(MUL_ASSIGN); }
225 "/="        { return(DIV_ASSIGN); }
226 "%="        { return(MOD_ASSIGN); }
227 "&="        { return(AND_ASSIGN); }
228 "^="        { return(XOR_ASSIGN); }
229 "|="        { return(OR_ASSIGN); }
230 ">>"        { return(RIGHT_OP); }
231 "<<"        { return(LEFT_OP); }
232 "++"        { return(INC_OP); }
233 "--"        { return(DEC_OP); }
234 "->"        { return(PTR_OP); }
235 "&&"        { return(AND_OP); }
236 "||"        { return(OR_OP); }
237 "<="        { return(LE_OP); }
238 ">="        { return(GE_OP); }
239 "=="        { return(EQ_OP); }
240 "!="        { return(NE_OP); }
241    /* "::"        { return(CLASS_OP); } */
242 ";"         { return(';'); }
243 ("{"|"<%")  { return('{'); }
244 ("}"|"%>")  { return('}'); }
245 ","         { return(','); }
246 ":"         { return(':'); }
247 "="         { return('='); }
248 "("         { return('('); }
249 ")"         { return(')'); }
250 ("["|"<:")  { return('['); }
251 ("]"|":>")  { return(']'); }
252 "."         { return('.'); }
253 "&"         { return('&'); }
254 "!"         { return('!'); }
255 "~"         { return('~'); }
256 "-"         { return('-'); }
257 "+"         { return('+'); }
258 "*"         { return('*'); }
259 "/"         { return('/'); }
260 "%"         { return('%'); }
261 "<"         { return('<'); }
262 ">"         { return('>'); }
263 "^"         { return('^'); }
264 "|"         { return('|'); }
265 "?"         { return('?'); }
266 "$"         { return('$'); }
267
268 <<EOF>> {
269       while(include_stack_ptr && !fileStack[include_stack_ptr-1])
270       {
271          --include_stack_ptr;
272          defaultDeclMode = declMode = declModeStack[include_stack_ptr];
273       }
274
275       if ( --include_stack_ptr < 0 )
276       {
277          include_stack_ptr = 0;
278          yyterminate();
279       }
280       else
281       {
282          delete fileInput;
283          yy_delete_buffer( YY_CURRENT_BUFFER );
284          fileInput = fileStack[include_stack_ptr];
285          yylloc = locStack[include_stack_ptr];
286          type_yylloc = locStack[include_stack_ptr];
287          expression_yylloc = locStack[include_stack_ptr];
288          yy_switch_to_buffer(include_stack[include_stack_ptr] );
289          defaultDeclMode = declMode = declModeStack[include_stack_ptr];
290       }
291    }
292
293
294 [ \v\f]   { yylloc.start = yylloc.end; type_yylloc.start = type_yylloc.end; expression_yylloc.start = expression_yylloc.end;}
295 [\n+]    { 
296    yylloc.end.charPos = 1; yylloc.end.line += yyleng; yylloc.start = yylloc.end; 
297    type_yylloc.end.charPos = 1; type_yylloc.end.line += yyleng; type_yylloc.start = type_yylloc.end; 
298    expression_yylloc.end.charPos = 1; expression_yylloc.end.line += yyleng; expression_yylloc.start = expression_yylloc.end; 
299    }
300 [\t]     { 
301    yylloc.start.charPos++ /*= 3 - (yylloc.start.col % 3)*/; yylloc.end.charPos = yylloc.start.charPos; yylloc.start.pos = yylloc.end.pos; 
302    expression_yylloc.start.charPos++ /*= 3 - (expression_yylloc.start.col % 3)*/; expression_yylloc.end.charPos = expression_yylloc.start.charPos; expression_yylloc.start.pos = expression_yylloc.end.pos; 
303    type_yylloc.start.charPos++ /*= 3 - (type_yylloc.start.col % 3)*/; type_yylloc.end.charPos = type_yylloc.start.charPos; type_yylloc.start.pos = type_yylloc.end.pos; 
304    }
305
306 .         { yylloc.start = yylloc.end; expression_yylloc.start = expression_yylloc.end;  type_yylloc.start = type_yylloc.end; }
307
308 %%
309
310 private:
311
312 yywrap()
313 {
314    return(1);
315 }
316
317 int comment()
318 {
319    int c, last = 0;
320    for(;;)
321    {
322       c = input();
323       if(c == EOF) break;
324
325       // fputc(c, output);
326       // putchar(c);
327       if(c == '\n')
328       {
329          yylloc.end.charPos = 1;
330          yylloc.end.pos++;
331          yylloc.end.line++;
332       }
333       else if (c == '\t')
334       {
335          yylloc.end.charPos++ /* += 3 - (yylloc.end.col % 3)*/;
336          yylloc.end.pos++;
337       }
338       else
339       {
340          yylloc.end.charPos++;
341          yylloc.end.pos++;
342       }
343       if(c == '/' && last == '*')
344          break;
345       last = c;
346    }
347    yylloc.start = yylloc.end;
348    return 0;
349 }
350
351 int commentCPP()
352 {
353    int c, last = 0;
354    for(;;)
355    {
356       c = input();
357       if(c == EOF) break;
358
359       // fputc(c, output);
360       // putchar(c);
361       if(c == '\n')
362       {
363          yylloc.end.charPos = 1;
364          yylloc.end.pos++;
365          yylloc.end.line++;
366          break;
367       }
368       else if (c == '\t')
369       {
370          yylloc.end.charPos++ /* += 3 - (yylloc.end.col % 3)*/;
371          yylloc.end.pos++;
372       }
373       else
374       {
375          yylloc.end.charPos++;
376          yylloc.end.pos++;
377       }
378       last = c;
379    }
380    yylloc.start = yylloc.end;
381    return 0;
382 }
383
384 int preprocessor()
385 {
386    int c, last = 0;
387    int count = 0;
388    char line[1024];
389
390    line[0] = '\0';
391
392    for(;;)
393    {
394       c = input();
395       if(c == EOF) break;
396
397       if(c == '\n')
398       {
399          yylloc.end.charPos = 1;
400          yylloc.end.pos++;
401          yylloc.end.line++;
402          if(last != '\\')
403          {
404             char * pointer = line + 1;
405             int lineNumber;
406             line[count] = 0;
407             lineNumber = GetValue(&pointer);
408             if(lineNumber)
409             {
410                char fileName[MAX_LOCATION];
411                
412                int inOut;
413
414                fileName[0] = 0;
415                GetString(&pointer, fileName, MAX_LOCATION);
416                inOut = GetValue(&pointer);
417                               
418                if(inOut == 1)
419                {
420                   char extension[MAX_EXTENSION];
421
422                   defaultDeclMode = declModeStack[include_stack_ptr] = declMode;
423
424                   GetExtension(fileName, extension);
425                   if(!strcmp(extension, "c") || !strcmp(extension, "h"))
426                      declMode = defaultDeclMode = defaultAccess;
427
428                   fileStack[include_stack_ptr] = null;
429                   include_stack_ptr++;
430                }
431                else if(inOut == 2)
432                {
433                   include_stack_ptr--;
434                   defaultDeclMode = declMode = declModeStack[include_stack_ptr];
435                }
436
437                yylloc.end.charPos = 1;
438                yylloc.end.line = lineNumber;
439                //yylloc.end.pos -= count;
440
441                if(include_stack_ptr > 0 || (lineNumber && fileName[0]))
442                   yylloc.end.included = GetIncludeFileID(fileName);
443                else
444                   yylloc.end.included = 0;
445             }
446             /*
447             int lineNumber = strtol(line+1, &endPtr, 0);
448             if(lineNumber)
449             {
450                GetString(&
451                endPtr
452
453                yylloc.end.charPos = 1;
454                yylloc.end.line = lineNumber;
455                yylloc.end.pos -= count;
456             }
457             */
458             break;
459          }
460          count = 0;
461       }
462       else if (c == '\t')
463       {
464          yylloc.end.charPos++ /* += 3 - (yylloc.end.col % 3)*/;
465          yylloc.end.pos++;
466          line[count++] = c;
467       }
468       else
469       {
470          yylloc.end.pos++;
471          if(c != '\r')
472          {
473             yylloc.end.charPos++;
474             line[count++] = c;
475          }
476       }
477       last = c;
478    }   
479    yylloc.start = yylloc.end;
480    line[count] = 0;
481
482    TrimLSpaces(line, line);
483    for(c = 0; line[c] && line[c] != ' '; c++);
484    if(!strncmp(line, "include", c))
485    {
486       char includeFile[MAX_LOCATION] = "";
487
488       memmove(line, line+c, strlen(line+c)+1);
489       TrimLSpaces(line, line);
490       if(line[0] == '\"')
491       {
492          for(c = 1; line[c]; c++)
493          {
494             if(line[c] == '\"')
495             {
496                strncpy(includeFile, line+1, c-1);
497                includeFile[c-1] = '\0';
498                break;
499             }
500          }
501       }
502       else if(line[0] == '<')
503       {
504          for(c = 1; line[c]; c++)
505             if(line[c] == '>')
506             {
507                strncpy(includeFile, line+1, c-1);
508                includeFile[c-1] = '\0';
509                break;
510             }
511       }
512
513       if ( include_stack_ptr >= MAX_INCLUDE_DEPTH )
514       {
515          fprintf( stderr, $"Includes nested too deeply" );
516          exit( 1 );
517       }
518
519       if(inCompiler || !FindIncludeFileID(includeFile))
520       {
521          File file = OpenIncludeFile(includeFile);
522          if(file)
523          {
524             char extension[MAX_EXTENSION];
525
526             fileStack[include_stack_ptr] = fileInput;
527             locStack[include_stack_ptr] = yylloc;
528             defaultDeclMode = declModeStack[include_stack_ptr] = declMode;
529             include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER;
530
531             yylloc.start.charPos = yylloc.end.charPos = 1;
532             yylloc.start.line = yylloc.end.line = 1;
533             yylloc.start.pos = yylloc.end.pos = 0;
534             yylloc.start.included = yylloc.end.included = GetIncludeFileID(includeFile);
535
536             GetExtension(includeFile, extension);
537             if(!strcmp(extension, "c") || !strcmp(extension, "h"))
538                declMode = defaultDeclMode = defaultAccess;
539
540             fileInput = file;
541             yy_switch_to_buffer( yy_create_buffer( fileInput, YY_BUF_SIZE ) );
542             BEGIN(INITIAL);
543          }
544          else
545             printf("");
546       }
547    }
548    return 0;
549 }
550
551 public void resetScanner()
552 {
553    YY_FLUSH_BUFFER;
554    yylloc.start.charPos = yylloc.end.charPos = 1;
555    yylloc.start.line = yylloc.end.line = 1;
556    yylloc.start.pos = yylloc.end.pos = 0;
557    yylloc.start.included = yylloc.end.included = 0;
558
559    expression_yylloc.start.charPos = expression_yylloc.end.charPos = 1;
560    expression_yylloc.start.line = expression_yylloc.end.line = 1;
561    expression_yylloc.start.pos = expression_yylloc.end.pos = 0;
562    expression_yylloc.start.included = expression_yylloc.end.included = 0;
563
564    type_yylloc.start.charPos = type_yylloc.end.charPos = 1;
565    type_yylloc.start.line = type_yylloc.end.line = 1;
566    type_yylloc.start.pos = type_yylloc.end.pos = 0;
567    type_yylloc.start.included = type_yylloc.end.included = 0;
568
569    include_stack_ptr = 0;
570 }
571
572 void resetScannerPos(CodePosition pos)
573 {
574    YY_FLUSH_BUFFER;
575    yylloc.start = yylloc.end = pos;
576    type_yylloc.start = type_yylloc.end = pos;
577    expression_yylloc.start = expression_yylloc.end = pos;
578 }
579
580 class LexerBackup
581 {
582    YYLTYPE yylloc;
583    YYLTYPE type_yylloc;
584    YYLTYPE expression_yylloc;
585
586    AccessMode declMode;
587    AccessMode defaultDeclMode;
588
589    File fileInput;
590    YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
591    File fileStack[MAX_INCLUDE_DEPTH];
592    char sourceFileStack[MAX_INCLUDE_DEPTH][MAX_LOCATION];
593    YYLTYPE locStack[MAX_INCLUDE_DEPTH];
594    AccessMode declModeStack[MAX_INCLUDE_DEPTH];
595    int include_stack_ptr;
596    YY_BUFFER_STATE buffer;
597
598    int yy_n_chars;
599    char * yytext_ptr;
600    char * yy_c_buf_p;
601    FILE * yyin;
602    char yy_hold_char;
603    int yychar;
604    int yy_init;
605    int yy_start;
606
607 };
608
609 LexerBackup pushLexer()
610 {
611    LexerBackup backup { };
612
613    backup.yylloc = yylloc;
614    backup.type_yylloc = type_yylloc;
615    backup.expression_yylloc = expression_yylloc;
616    backup.fileInput = fileInput;
617    memcpy(backup.include_stack, include_stack, sizeof(include_stack));
618    memcpy(backup.fileStack, fileStack, sizeof(fileStack));
619    memcpy(backup.sourceFileStack, sourceFileStack, sizeof(sourceFileStack));
620    memcpy(backup.locStack, locStack, sizeof(locStack));
621    memcpy(backup.declModeStack, declModeStack, sizeof(declModeStack));
622    backup.include_stack_ptr = include_stack_ptr;
623    backup.defaultDeclMode = defaultDeclMode;
624    backup.declMode = declMode;
625    backup.buffer = yy_current_buffer;
626
627    backup.yy_n_chars = yy_n_chars;
628    backup.yytext_ptr = yytext_ptr;
629    backup.yy_c_buf_p = yy_c_buf_p;
630    backup.yyin = yyin;
631    backup.yy_hold_char = yy_hold_char;
632    backup.yychar = yychar;
633    backup.yy_init = yy_init;
634    backup.yy_start = yy_start;
635
636    yy_init = 1;
637
638    yy_current_buffer = 0;
639
640    yylloc.start.charPos = yylloc.end.charPos = 1;
641    yylloc.start.line = yylloc.end.line = 1;
642    yylloc.start.pos = yylloc.end.pos = 0;
643    yylloc.start.included = yylloc.end.included = 0;
644
645    expression_yylloc.start.charPos = expression_yylloc.end.charPos = 1;
646    expression_yylloc.start.line = expression_yylloc.end.line = 1;
647    expression_yylloc.start.pos = expression_yylloc.end.pos = 0;
648    expression_yylloc.start.included = expression_yylloc.end.included = 0;
649
650    type_yylloc.start.charPos = type_yylloc.end.charPos = 1;
651    type_yylloc.start.line = type_yylloc.end.line = 1;
652    type_yylloc.start.pos = type_yylloc.end.pos = 0;
653    type_yylloc.start.included = type_yylloc.end.included = 0;
654
655    include_stack_ptr = 0;
656
657    return backup;
658 }
659
660 void popLexer(LexerBackup backup)
661 {
662    yylloc = backup.yylloc;
663    type_yylloc = backup.type_yylloc;
664    expression_yylloc = backup.expression_yylloc;
665    fileInput = backup.fileInput;
666    memcpy(include_stack, backup.include_stack, sizeof(include_stack));
667    memcpy(fileStack, backup.fileStack, sizeof(fileStack));
668    memcpy(sourceFileStack, backup.sourceFileStack, sizeof(sourceFileStack));
669    memcpy(locStack, backup.locStack, sizeof(locStack));
670    memcpy(declModeStack, backup.declModeStack, sizeof(declModeStack));
671    include_stack_ptr = backup.include_stack_ptr;
672    defaultDeclMode = backup.defaultDeclMode;
673    declMode = backup.declMode;
674
675    // yy_switch_to_buffer(backup.buffer);
676    yy_current_buffer = backup.buffer;
677    yy_n_chars = backup.yy_n_chars;
678    yytext_ptr = backup.yytext_ptr;
679    yy_c_buf_p = backup.yy_c_buf_p;
680    yyin = backup.yyin;
681    yy_hold_char = backup.yy_hold_char;
682    yychar = backup.yychar;
683    yy_init = backup.yy_init;
684    yy_start = backup.yy_start;
685
686    delete backup;
687 }