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