compiler/libec: Added grammar rule for __builtin_offset
[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 "__builtin_va_list"  { return(VALIST); }
136 "__builtin_va_arg"   { return(VAARG); }
137 "Bool"               { return(BOOL); }
138 "_Bool"              { return(_BOOL); }
139 "_Complex"           { return(_COMPLEX); }
140 "_Imaginary"         { return(_IMAGINARY); }
141 "restrict"           { return(EXT_DECL); }
142
143  /* "__attribute__".?"(("({D}|{L})*"))" { return(EXT_ATTRIB); } */
144
145  /* DID I MEAN? "__attribute__"" "*"(("" "*({D}|{L})*" "*("("({D}|{L})*(" "*","" "*({D}|{L})*)*" "*")")?" "*"))" { return(EXT_ATTRIB); } */
146
147  /*
148  "__attribute_deprecated__"(" "*)"(("(" "*)({D}|{L})*(" "*)("("({D}|{L}|\")*((" "*)","(" "*)({D}|{L}|\")*)*(" "*)")")?(" "*)(","(" "*)({D}|{L})*(" "*)("("({D}|{L}|\")*((" "*)","(" "*)({D}|{L}|\")*)*(" "*)")")?(" "*))*"))" { return(EXT_ATTRIB); }
149  "__attribute__"           (" "*)"(("(" "*)({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  */
152  /*
153  [__attribute__] [spaces]
154    [((] [spaces]
155       [digits | letters] [spaces]
156          ( [(]  [digits or letters or "]  ( [spaces] [,] [spaces] [digits or letters or "] )*  [spaces]  [)] )?
157       [spaces]
158       ( [,] [spaces]  [digits or letters]  [spaces]
159          ( [(]  [digits or letters or "]
160             ( [spaces] [,] [spaces] [digits or letters or "] )*  [spaces] [)]
161          )? [spaces]
162       )*
163    [))]
164  */
165  /* "__attribute__".?"((".?({D}|{L})*.?("("({D}|{L})*(.?",".?({D}|{L})*)*.?")")?.?"))" { return(EXT_ATTRIB); } */
166  /* "__attribute".?"((".?({D}|{L})*.?("("({D}|{L})*(.?",".?({D}|{L})*)*.?")")?.?"))" { return(EXT_ATTRIB); }*/
167
168 "__attribute_deprecated__" { return ATTRIB_DEP; }
169 "__attribute__" { return ATTRIB; }
170 "__attribute" { return __ATTRIB; }
171
172 "__inline__"               { return(EXT_STORAGE); }
173 "_inline"                  { return(EXT_STORAGE); }
174 "__inline"                 { return(EXT_STORAGE); }
175 "inline"                   { return(EXT_STORAGE); }
176 "__declspec("({D}|{L})*")" { return(EXT_STORAGE); }
177 "dllexport"                { return(EXT_STORAGE); }
178 "dllimport"                { return(EXT_STORAGE); }
179 "__cdecl"                  { return(EXT_DECL); }
180 "__stdcall"                { return(EXT_DECL); }
181 "__stdcall__"              { return(EXT_DECL); }
182 "_stdcall"                 { return(EXT_DECL); }
183 "stdcall"                  { return(EXT_DECL); }
184 "__restrict"               { return(EXT_DECL); }
185 "__const"                  { return(CONST /*EXT_DECL*/); }
186 "__restrict__"             { return(EXT_DECL); }
187 "public"                   { return(PUBLIC); }
188 "private"                  { return(PRIVATE); }
189 "typed_object"             { return(TYPED_OBJECT); }
190 "any_object"               { return(ANY_OBJECT); }
191 "incref"                   { return(_INCREF); }
192 "__extension__"            { return(EXTENSION); }
193 "_extension_"              { return(EXTENSION); }
194 "__asm__"                  { return(ASM); }
195 "asm"                      { return(ASM); }
196 "__asm"                    { return(ASM); }
197 "__typeof"                 { return(TYPEOF); }
198 "watch"                    { return(WATCH); }
199 "stopwatching"             { return(STOPWATCHING); }
200 "firewatchers"             { return(FIREWATCHERS); }
201 "watchable"                { return(WATCHABLE); }
202 "class_designer"           { return(CLASS_DESIGNER); }
203 "class_no_expansion"       { return(CLASS_NO_EXPANSION); }
204 "class_fixed"              { return(CLASS_FIXED); }
205 "class_default_property"   { return(CLASS_DEFAULT_PROPERTY); }
206 "property_category"        { return(PROPERTY_CATEGORY); }
207 "class_data"               { return(CLASS_DATA); }
208 "class_property"           { return(CLASS_PROPERTY); }
209 "subclass"                 { return(SUBCLASS); }
210 "namespace"                { return(NAMESPACE); }
211 "dbtable"                  { return(DBTABLE); }
212 "dbfield"                  { return(DBFIELD); }
213 "dbindex"                  { return(DBINDEX); }
214 "database_open"            { return(DATABASE_OPEN); }
215
216 ("::"?(({IDENT}"&"?"::")*)){IDENT}?    { return(check_type()); }     // {L}({L}|{D})*      { return(check_type()); }  // ("::"|(({IDENT}"::")*)){IDENT}  { return(check_type()); }     // {L}({L}|{D})*      { return(check_type()); }
217
218 0[xX]{H}+{IS}?          { return(CONSTANT); }
219
220 0[xX]{H}+{P}{FS}?    { return(CONSTANT); }
221 0[xX]{H}*"."{H}+({P})?{FS}?    { return(CONSTANT); }
222 0[xX]{H}+"."{H}*({P})?{FS}?    { return(CONSTANT); }
223
224 0{D}+{IS}?              { return(CONSTANT); }
225 {D}+{IS}?               { return(CONSTANT); }
226 L?'(\\.|[^\\'])+'       { return(CONSTANT); }
227
228 {D}+{E}{FS}?            { return(CONSTANT); }
229 {D}*"."{D}+({E})?{FS}?  { return(CONSTANT); }
230 {D}+"."{D}*({E})?{FS}?  { return(CONSTANT); }
231
232 \"(\\.|[^\\"])*\"     { return(STRING_LITERAL); }
233 L\"(\\.|[^\\"])*\"     { return(WIDE_STRING_LITERAL); }
234
235 "..."       { return(ELLIPSIS); }
236 ">>="       { return(RIGHT_ASSIGN); }
237 "<<="       { return(LEFT_ASSIGN); }
238 "+="        { return(ADD_ASSIGN); }
239 "-="        { return(SUB_ASSIGN); }
240 "*="        { return(MUL_ASSIGN); }
241 "/="        { return(DIV_ASSIGN); }
242 "%="        { return(MOD_ASSIGN); }
243 "&="        { return(AND_ASSIGN); }
244 "^="        { return(XOR_ASSIGN); }
245 "|="        { return(OR_ASSIGN); }
246 ">>"        { return(RIGHT_OP); }
247 "<<"        { return(LEFT_OP); }
248 "++"        { return(INC_OP); }
249 "--"        { return(DEC_OP); }
250 "->"        { return(PTR_OP); }
251 "&&"        { return(AND_OP); }
252 "||"        { return(OR_OP); }
253 "<="        { return(LE_OP); }
254 ">="        { return(GE_OP); }
255 "=="        { return(EQ_OP); }
256 "!="        { return(NE_OP); }
257    /* "::"        { return(CLASS_OP); } */
258 ";"         { return(';'); }
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
284 <<EOF>> {
285       while(include_stack_ptr && !fileStack[include_stack_ptr-1])
286       {
287          --include_stack_ptr;
288          defaultDeclMode = declMode = structDeclMode = declModeStack[include_stack_ptr];
289       }
290
291       if ( --include_stack_ptr < 0 )
292       {
293          include_stack_ptr = 0;
294          yyterminate();
295       }
296       else
297       {
298          delete fileInput;
299          yy_delete_buffer( YY_CURRENT_BUFFER );
300          fileInput = fileStack[include_stack_ptr];
301          yylloc = locStack[include_stack_ptr];
302          type_yylloc = locStack[include_stack_ptr];
303          expression_yylloc = locStack[include_stack_ptr];
304          yy_switch_to_buffer(include_stack[include_stack_ptr] );
305          defaultDeclMode = declMode = structDeclMode = declModeStack[include_stack_ptr];
306       }
307    }
308
309
310 [ \v\f]   { yylloc.start = yylloc.end; type_yylloc.start = type_yylloc.end; expression_yylloc.start = expression_yylloc.end;}
311 [\n+]    {
312    yylloc.end.charPos = 1; yylloc.end.line += yyleng; yylloc.start = yylloc.end;
313    type_yylloc.end.charPos = 1; type_yylloc.end.line += yyleng; type_yylloc.start = type_yylloc.end;
314    expression_yylloc.end.charPos = 1; expression_yylloc.end.line += yyleng; expression_yylloc.start = expression_yylloc.end;
315    }
316 [\t]     {
317    yylloc.start.charPos++ /*= 3 - (yylloc.start.col % 3)*/; yylloc.end.charPos = yylloc.start.charPos; yylloc.start.pos = yylloc.end.pos;
318    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;
319    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;
320    }
321 [\r]  { yylloc.start = yylloc.end; expression_yylloc.start = expression_yylloc.end;  type_yylloc.start = type_yylloc.end; }
322 .         {
323    yylloc.start = yylloc.end; expression_yylloc.start = expression_yylloc.end;  type_yylloc.start = type_yylloc.end;
324    if(inCompiler)
325       printf("lexer error: invalid char 0x%X at line %d, col %d\n", (unsigned char)yytext[0], yylloc.start.line, yylloc.start.charPos);
326    yyerror();
327    }
328
329 %%
330
331 private:
332
333 int yywrap()
334 {
335    return(1);
336 }
337
338 int comment()
339 {
340    int c, last = 0;
341    for(;;)
342    {
343       c = input();
344       if(c == EOF) break;
345
346       // fputc(c, output);
347       // putchar(c);
348       if(c == '\n')
349       {
350          yylloc.end.charPos = 1;
351          yylloc.end.pos++;
352          yylloc.end.line++;
353       }
354       else if (c == '\t')
355       {
356          yylloc.end.charPos++ /* += 3 - (yylloc.end.col % 3)*/;
357          yylloc.end.pos++;
358       }
359       else
360       {
361          yylloc.end.charPos++;
362          yylloc.end.pos++;
363       }
364       if(c == '/' && last == '*')
365          break;
366       last = c;
367    }
368    yylloc.start = yylloc.end;
369    return 0;
370 }
371
372 int commentCPP()
373 {
374    int c; //, last = 0;
375    for(;;)
376    {
377       c = input();
378       if(c == EOF) break;
379
380       // fputc(c, output);
381       // putchar(c);
382       if(c == '\n')
383       {
384          yylloc.end.charPos = 1;
385          yylloc.end.pos++;
386          yylloc.end.line++;
387          break;
388       }
389       else if (c == '\t')
390       {
391          yylloc.end.charPos++ /* += 3 - (yylloc.end.col % 3)*/;
392          yylloc.end.pos++;
393       }
394       else
395       {
396          yylloc.end.charPos++;
397          yylloc.end.pos++;
398       }
399       //last = c;
400    }
401    yylloc.start = yylloc.end;
402    return 0;
403 }
404
405 int preprocessor()
406 {
407    int c, last = 0;
408    int count = 0;
409    char line[1024];
410
411    line[0] = '\0';
412
413    for(;;)
414    {
415       c = input();
416       if(c == EOF) break;
417
418       if(c == '\n')
419       {
420          yylloc.end.charPos = 1;
421          yylloc.end.pos++;
422          yylloc.end.line++;
423          if(last != '\\')
424          {
425             char * pointer = line + 1;
426             int lineNumber;
427             line[count] = 0;
428             lineNumber = GetValue(&pointer);
429             if(lineNumber)
430             {
431                char fileName[MAX_LOCATION];
432
433                int inOut;
434
435                fileName[0] = 0;
436                GetString(&pointer, fileName, MAX_LOCATION);
437                inOut = GetValue(&pointer);
438
439                if(inOut == 1)
440                {
441                   char extension[MAX_EXTENSION];
442
443                   defaultDeclMode = declModeStack[include_stack_ptr] = declMode;
444
445                   GetExtension(fileName, extension);
446                   if(!strcmp(extension, "c") || !strcmp(extension, "h"))
447                      declMode = defaultDeclMode = structDeclMode = defaultAccess;
448
449                   fileStack[include_stack_ptr] = null;
450                   include_stack_ptr++;
451                }
452                else if(inOut == 2)
453                {
454                   include_stack_ptr--;
455                   defaultDeclMode = declMode = structDeclMode = declModeStack[include_stack_ptr];
456                }
457
458                yylloc.end.charPos = 1;
459                yylloc.end.line = lineNumber;
460                //yylloc.end.pos -= count;
461
462                if(include_stack_ptr > 0 || (lineNumber && fileName[0]))
463                   yylloc.end.included = GetIncludeFileID(fileName);
464                else
465                   yylloc.end.included = 0;
466             }
467             /*
468             int lineNumber = strtol(line+1, &endPtr, 0);
469             if(lineNumber)
470             {
471                GetString(&
472                endPtr
473
474                yylloc.end.charPos = 1;
475                yylloc.end.line = lineNumber;
476                yylloc.end.pos -= count;
477             }
478             */
479             break;
480          }
481          count = 0;
482       }
483       else if (c == '\t')
484       {
485          yylloc.end.charPos++ /* += 3 - (yylloc.end.col % 3)*/;
486          yylloc.end.pos++;
487          line[count++] = c;
488       }
489       else
490       {
491          yylloc.end.pos++;
492          if(c != '\r')
493          {
494             yylloc.end.charPos++;
495             line[count++] = c;
496          }
497       }
498       last = c;
499    }
500    yylloc.start = yylloc.end;
501    line[count] = 0;
502
503    TrimLSpaces(line, line);
504    for(c = 0; line[c] && line[c] != ' '; c++);
505    if(!strncmp(line, "include", c))
506    {
507       char includeFile[MAX_LOCATION] = "";
508
509       memmove(line, line+c, strlen(line+c)+1);
510       TrimLSpaces(line, line);
511       if(line[0] == '\"')
512       {
513          for(c = 1; line[c]; c++)
514          {
515             if(line[c] == '\"')
516             {
517                strncpy(includeFile, line+1, c-1);
518                includeFile[c-1] = '\0';
519                break;
520             }
521          }
522       }
523       else if(line[0] == '<')
524       {
525          for(c = 1; line[c]; c++)
526             if(line[c] == '>')
527             {
528                strncpy(includeFile, line+1, c-1);
529                includeFile[c-1] = '\0';
530                break;
531             }
532       }
533
534       if ( include_stack_ptr >= MAX_INCLUDE_DEPTH )
535       {
536          fprintf( stderr, "%s", $"Includes nested too deeply" );
537          exit( 1 );
538       }
539
540       if(inCompiler || !FindIncludeFileID(includeFile))
541       {
542          File file = OpenIncludeFile(includeFile);
543          if(file)
544          {
545             char extension[MAX_EXTENSION];
546
547             fileStack[include_stack_ptr] = fileInput;
548             locStack[include_stack_ptr] = yylloc;
549             defaultDeclMode = declModeStack[include_stack_ptr] = declMode;
550             include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER;
551
552             yylloc.start.charPos = yylloc.end.charPos = 1;
553             yylloc.start.line = yylloc.end.line = 1;
554             yylloc.start.pos = yylloc.end.pos = 0;
555             yylloc.start.included = yylloc.end.included = GetIncludeFileID(includeFile);
556
557             GetExtension(includeFile, extension);
558             if(!strcmp(extension, "c") || !strcmp(extension, "h"))
559                declMode = defaultDeclMode = structDeclMode = defaultAccess;
560
561             fileInput = file;
562             yy_switch_to_buffer( yy_create_buffer( fileInput, YY_BUF_SIZE ) );
563             BEGIN(INITIAL);
564          }
565       }
566    }
567    return 0;
568 }
569
570 public void resetScanner()
571 {
572    YY_FLUSH_BUFFER;
573    yylloc.start.charPos = yylloc.end.charPos = 1;
574    yylloc.start.line = yylloc.end.line = 1;
575    yylloc.start.pos = yylloc.end.pos = 0;
576    yylloc.start.included = yylloc.end.included = 0;
577
578    expression_yylloc.start.charPos = expression_yylloc.end.charPos = 1;
579    expression_yylloc.start.line = expression_yylloc.end.line = 1;
580    expression_yylloc.start.pos = expression_yylloc.end.pos = 0;
581    expression_yylloc.start.included = expression_yylloc.end.included = 0;
582
583    type_yylloc.start.charPos = type_yylloc.end.charPos = 1;
584    type_yylloc.start.line = type_yylloc.end.line = 1;
585    type_yylloc.start.pos = type_yylloc.end.pos = 0;
586    type_yylloc.start.included = type_yylloc.end.included = 0;
587
588    include_stack_ptr = 0;
589 }
590
591 void resetScannerPos(CodePosition pos)
592 {
593    YY_FLUSH_BUFFER;
594    yylloc.start = yylloc.end = pos;
595    type_yylloc.start = type_yylloc.end = pos;
596    expression_yylloc.start = expression_yylloc.end = pos;
597 }
598
599 class LexerBackup
600 {
601    YYLTYPE yylloc;
602    YYLTYPE type_yylloc;
603    YYLTYPE expression_yylloc;
604
605    AccessMode declMode;
606    AccessMode defaultDeclMode;
607
608    File fileInput;
609    YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
610    File fileStack[MAX_INCLUDE_DEPTH];
611    char sourceFileStack[MAX_INCLUDE_DEPTH][MAX_LOCATION];
612    YYLTYPE locStack[MAX_INCLUDE_DEPTH];
613    AccessMode declModeStack[MAX_INCLUDE_DEPTH];
614    int include_stack_ptr;
615    YY_BUFFER_STATE buffer;
616
617    int yy_n_chars;
618    char * yytext_ptr;
619    char * yy_c_buf_p;
620    FILE * yyin;
621    char yy_hold_char;
622    int yychar;
623    int yy_init;
624    int yy_start;
625
626 };
627
628 LexerBackup pushLexer()
629 {
630    LexerBackup backup { };
631
632    backup.yylloc = yylloc;
633    backup.type_yylloc = type_yylloc;
634    backup.expression_yylloc = expression_yylloc;
635    backup.fileInput = fileInput;
636    memcpy(backup.include_stack, include_stack, sizeof(include_stack));
637    memcpy(backup.fileStack, fileStack, sizeof(fileStack));
638    memcpy(backup.sourceFileStack, sourceFileStack, sizeof(sourceFileStack));
639    memcpy(backup.locStack, locStack, sizeof(locStack));
640    memcpy(backup.declModeStack, declModeStack, sizeof(declModeStack));
641    backup.include_stack_ptr = include_stack_ptr;
642    backup.defaultDeclMode = defaultDeclMode;
643    backup.declMode = declMode;
644    backup.buffer = yy_current_buffer;
645
646    backup.yy_n_chars = yy_n_chars;
647    backup.yytext_ptr = yytext_ptr;
648    backup.yy_c_buf_p = yy_c_buf_p;
649    backup.yyin = yyin;
650    backup.yy_hold_char = yy_hold_char;
651    backup.yychar = yychar;
652    backup.yy_init = yy_init;
653    backup.yy_start = yy_start;
654
655    yy_init = 1;
656
657    yy_current_buffer = 0;
658
659    yylloc.start.charPos = yylloc.end.charPos = 1;
660    yylloc.start.line = yylloc.end.line = 1;
661    yylloc.start.pos = yylloc.end.pos = 0;
662    yylloc.start.included = yylloc.end.included = 0;
663
664    expression_yylloc.start.charPos = expression_yylloc.end.charPos = 1;
665    expression_yylloc.start.line = expression_yylloc.end.line = 1;
666    expression_yylloc.start.pos = expression_yylloc.end.pos = 0;
667    expression_yylloc.start.included = expression_yylloc.end.included = 0;
668
669    type_yylloc.start.charPos = type_yylloc.end.charPos = 1;
670    type_yylloc.start.line = type_yylloc.end.line = 1;
671    type_yylloc.start.pos = type_yylloc.end.pos = 0;
672    type_yylloc.start.included = type_yylloc.end.included = 0;
673
674    include_stack_ptr = 0;
675
676    return backup;
677 }
678
679 void popLexer(LexerBackup backup)
680 {
681    yylloc = backup.yylloc;
682    type_yylloc = backup.type_yylloc;
683    expression_yylloc = backup.expression_yylloc;
684    fileInput = backup.fileInput;
685    memcpy(include_stack, backup.include_stack, sizeof(include_stack));
686    memcpy(fileStack, backup.fileStack, sizeof(fileStack));
687    memcpy(sourceFileStack, backup.sourceFileStack, sizeof(sourceFileStack));
688    memcpy(locStack, backup.locStack, sizeof(locStack));
689    memcpy(declModeStack, backup.declModeStack, sizeof(declModeStack));
690    include_stack_ptr = backup.include_stack_ptr;
691    defaultDeclMode = backup.defaultDeclMode;
692    declMode = structDeclMode = backup.declMode;
693
694    // yy_switch_to_buffer(backup.buffer);
695    yy_current_buffer = backup.buffer;
696    yy_n_chars = backup.yy_n_chars;
697    yytext_ptr = backup.yytext_ptr;
698    yy_c_buf_p = backup.yy_c_buf_p;
699    yyin = backup.yyin;
700    yy_hold_char = backup.yy_hold_char;
701    yychar = backup.yychar;
702    yy_init = backup.yy_init;
703    yy_start = backup.yy_start;
704
705    delete backup;
706 }