compiler: (WIP) Fixes for MinGW/GCC 5
[sdk] / compiler / libec / src / lexer.l
index 19a1380..6230fde 100644 (file)
@@ -2,15 +2,19 @@ D         [0-9]
 L         [a-zA-Z_]
 H         [a-fA-F0-9]
 E         [Ee][+-]?{D}+
-FS         (f|F|l|L)
-IS         (u|U|l|L)*
+P         [Pp][+-]?{D}+
+FS         (f|F|l|L|i|I|j|J)*
+IS         (u|U|l|L|i|I|j|J)*
 IDENT    {L}({L}|{D})*
 
+%option nounput
+
 %{
 import "ecdefs"
 #define YYLTYPE Location
+#define YY_NEVER_INTERACTIVE 1    // Avoid calling isatty on eC File object
 
-#include "grammar.eh"
+#include "grammar.h"
 
 bool echoOn = true;
 public void SetEchoOn(bool b) { echoOn = b; }
@@ -46,7 +50,7 @@ void TESTTTT()
 YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
 File fileStack[MAX_INCLUDE_DEPTH];
 char sourceFileStack[MAX_INCLUDE_DEPTH][MAX_LOCATION];
-public void SetSomeSourceFileStack(char * fileName, int index) { strcpy(sourceFileStack[index], fileName); }
+public void SetSomeSourceFileStack(const char * fileName, int index) { strcpy(sourceFileStack[index], fileName); }
 YYLTYPE locStack[MAX_INCLUDE_DEPTH];
 AccessMode declModeStack[MAX_INCLUDE_DEPTH];
 int include_stack_ptr = 0;
@@ -59,9 +63,9 @@ default:
 %%
 
 %{
-   yylloc.start = yylloc.end; 
-   type_yylloc.start = type_yylloc.end; 
-   expression_yylloc.start = expression_yylloc.end; 
+   yylloc.start = yylloc.end;
+   type_yylloc.start = type_yylloc.end;
+   expression_yylloc.start = expression_yylloc.end;
 %}
 
 "#"                  { preprocessor(); }
@@ -94,9 +98,13 @@ default:
 "return"             { return(RETURN); }
 "short"              { return(SHORT); }
 "signed"             { return(SIGNED); }
+"__signed"           { return(SIGNED); }
 "__signed__"         { return(SIGNED); }
 "sizeof"             { return(SIZEOF); }
+"__alignof__"        { return(ALIGNOF); }
+"__builtin_offsetof"        { return(BUILTIN_OFFSETOF); }
 "static"             { return(STATIC); }
+"__thread"           { return(THREAD); }
 "struct"             { return(STRUCT); }
 "switch"             { return(SWITCH); }
 "typedef"            { return(TYPEDEF); }
@@ -105,6 +113,7 @@ default:
 "void"               { return(VOID); }
 "volatile"           { return(VOLATILE); }
 "__volatile__"       { return(VOLATILE); }
+"__volatile"         { return(VOLATILE); }
 "while"              { return(WHILE); }
 
 "property"           { return(PROPERTY); }
@@ -123,19 +132,44 @@ default:
 "define"             { return(DEFINE); }
 "__int64"            { return(INT64); }
 "int64"              { return(INT64); }
+"__int128"           { return(INT128); }
 "__builtin_va_list"  { return(VALIST); }
 "__builtin_va_arg"   { return(VAARG); }
+"Bool"               { return(BOOL); }
+"_Bool"              { return(_BOOL); }
+"_Complex"           { return(_COMPLEX); }
+"_Imaginary"         { return(_IMAGINARY); }
+"restrict"           { return(EXT_DECL); }
 
  /* "__attribute__".?"(("({D}|{L})*"))" { return(EXT_ATTRIB); } */
 
  /* DID I MEAN? "__attribute__"" "*"(("" "*({D}|{L})*" "*("("({D}|{L})*(" "*","" "*({D}|{L})*)*" "*")")?" "*"))" { return(EXT_ATTRIB); } */
 
-"__attribute__"(" "*)"(("(" "*)({D}|{L})*(" "*)("("({D}|{L}|\")*((" "*)","(" "*)({D}|{L}|\")*)*(" "*)")")?(" "*)(","(" "*)({D}|{L})*(" "*)("("({D}|{L}|\")*((" "*)","(" "*)({D}|{L}|\")*)*(" "*)")")?(" "*))*"))" { return(EXT_ATTRIB); }
-"__attribute"(" "*)"(("(" "*)({D}|{L})*(" "*)("("({D}|{L}|\")*((" "*)","(" "*)({D}|{L}|\")*)*(" "*)")")?(" "*)(","(" "*)({D}|{L})*(" "*)("("({D}|{L}|\")*((" "*)","(" "*)({D}|{L}|\")*)*(" "*)")")?(" "*))*"))" { return(EXT_ATTRIB); }
-
+ /*
+ "__attribute_deprecated__"(" "*)"(("(" "*)({D}|{L})*(" "*)("("({D}|{L}|\")*((" "*)","(" "*)({D}|{L}|\")*)*(" "*)")")?(" "*)(","(" "*)({D}|{L})*(" "*)("("({D}|{L}|\")*((" "*)","(" "*)({D}|{L}|\")*)*(" "*)")")?(" "*))*"))" { return(EXT_ATTRIB); }
+ "__attribute__"           (" "*)"(("(" "*)({D}|{L})*(" "*)("("({D}|{L}|\")*((" "*)","(" "*)({D}|{L}|\")*)*(" "*)")")?(" "*)(","(" "*)({D}|{L})*(" "*)("("({D}|{L}|\")*((" "*)","(" "*)({D}|{L}|\")*)*(" "*)")")?(" "*))*"))" { return(EXT_ATTRIB); }
+ "__attribute"             (" "*)"(("(" "*)({D}|{L})*(" "*)("("({D}|{L}|\")*((" "*)","(" "*)({D}|{L}|\")*)*(" "*)")")?(" "*)(","(" "*)({D}|{L})*(" "*)("("({D}|{L}|\")*((" "*)","(" "*)({D}|{L}|\")*)*(" "*)")")?(" "*))*"))" { return(EXT_ATTRIB); }
+ */
+ /*
+ [__attribute__] [spaces]
+   [((] [spaces]
+      [digits | letters] [spaces]
+         ( [(]  [digits or letters or "]  ( [spaces] [,] [spaces] [digits or letters or "] )*  [spaces]  [)] )?
+      [spaces]
+      ( [,] [spaces]  [digits or letters]  [spaces]
+         ( [(]  [digits or letters or "]
+            ( [spaces] [,] [spaces] [digits or letters or "] )*  [spaces] [)]
+         )? [spaces]
+      )*
+   [))]
+ */
  /* "__attribute__".?"((".?({D}|{L})*.?("("({D}|{L})*(.?",".?({D}|{L})*)*.?")")?.?"))" { return(EXT_ATTRIB); } */
  /* "__attribute".?"((".?({D}|{L})*.?("("({D}|{L})*(.?",".?({D}|{L})*)*.?")")?.?"))" { return(EXT_ATTRIB); }*/
 
+"__attribute_deprecated__" { return ATTRIB_DEP; }
+"__attribute__" { return ATTRIB; }
+"__attribute" { return __ATTRIB; }
+
 "__inline__"               { return(EXT_STORAGE); }
 "_inline"                  { return(EXT_STORAGE); }
 "__inline"                 { return(EXT_STORAGE); }
@@ -149,7 +183,7 @@ default:
 "_stdcall"                 { return(EXT_DECL); }
 "stdcall"                  { return(EXT_DECL); }
 "__restrict"               { return(EXT_DECL); }
-"__const"                  { return(EXT_DECL); }
+"__const"                  { return(CONST /*EXT_DECL*/); }
 "__restrict__"             { return(EXT_DECL); }
 "public"                   { return(PUBLIC); }
 "private"                  { return(PRIVATE); }
@@ -179,10 +213,15 @@ default:
 "dbfield"                  { return(DBFIELD); }
 "dbindex"                  { return(DBINDEX); }
 "database_open"            { return(DATABASE_OPEN); }
-      
-("::"|(({IDENT}"&"?"::")*)){IDENT}?    { return(check_type()); }     // {L}({L}|{D})*      { return(check_type()); }  // ("::"|(({IDENT}"::")*)){IDENT}  { return(check_type()); }     // {L}({L}|{D})*      { return(check_type()); }
+
+("::"?(({IDENT}"&"?"::")*)){IDENT}?    { return(check_type()); }     // {L}({L}|{D})*      { return(check_type()); }  // ("::"|(({IDENT}"::")*)){IDENT}  { return(check_type()); }     // {L}({L}|{D})*      { return(check_type()); }
 
 0[xX]{H}+{IS}?          { return(CONSTANT); }
+
+0[xX]{H}+{P}{FS}?    { return(CONSTANT); }
+0[xX]{H}*"."{H}+({P})?{FS}?    { return(CONSTANT); }
+0[xX]{H}+"."{H}*({P})?{FS}?    { return(CONSTANT); }
+
 0{D}+{IS}?              { return(CONSTANT); }
 {D}+{IS}?               { return(CONSTANT); }
 L?'(\\.|[^\\'])+'       { return(CONSTANT); }
@@ -191,7 +230,8 @@ L?'(\\.|[^\\'])+'       { return(CONSTANT); }
 {D}*"."{D}+({E})?{FS}?  { return(CONSTANT); }
 {D}+"."{D}*({E})?{FS}?  { return(CONSTANT); }
 
-L?\"(\\.|[^\\"])*\"     { return(STRING_LITERAL); }
+\"(\\.|[^\\"])*\"     { return(STRING_LITERAL); }
+L\"(\\.|[^\\"])*\"     { return(WIDE_STRING_LITERAL); }
 
 "..."       { return(ELLIPSIS); }
 ">>="       { return(RIGHT_ASSIGN); }
@@ -240,10 +280,18 @@ L?\"(\\.|[^\\"])*\"     { return(STRING_LITERAL); }
 "^"         { return('^'); }
 "|"         { return('|'); }
 "?"         { return('?'); }
+"$"         { return('$'); }
 
 <<EOF>> {
+      while(include_stack_ptr && !fileStack[include_stack_ptr-1])
+      {
+         --include_stack_ptr;
+         defaultDeclMode = declMode = structDeclMode = declModeStack[include_stack_ptr];
+      }
+
       if ( --include_stack_ptr < 0 )
       {
+         include_stack_ptr = 0;
          yyterminate();
       }
       else
@@ -255,28 +303,35 @@ L?\"(\\.|[^\\"])*\"     { return(STRING_LITERAL); }
          type_yylloc = locStack[include_stack_ptr];
          expression_yylloc = locStack[include_stack_ptr];
          yy_switch_to_buffer(include_stack[include_stack_ptr] );
-         defaultDeclMode = declMode = declModeStack[include_stack_ptr];
+         defaultDeclMode = declMode = structDeclMode = declModeStack[include_stack_ptr];
       }
    }
 
 
 [ \v\f]   { yylloc.start = yylloc.end; type_yylloc.start = type_yylloc.end; expression_yylloc.start = expression_yylloc.end;}
-[\n+]    { 
-   yylloc.end.charPos = 1; yylloc.end.line += yyleng; yylloc.start = yylloc.end; 
-   type_yylloc.end.charPos = 1; type_yylloc.end.line += yyleng; type_yylloc.start = type_yylloc.end; 
-   expression_yylloc.end.charPos = 1; expression_yylloc.end.line += yyleng; expression_yylloc.start = expression_yylloc.end; 
+[\n+]    {
+   yylloc.end.charPos = 1; yylloc.end.line += yyleng; yylloc.start = yylloc.end;
+   type_yylloc.end.charPos = 1; type_yylloc.end.line += yyleng; type_yylloc.start = type_yylloc.end;
+   expression_yylloc.end.charPos = 1; expression_yylloc.end.line += yyleng; expression_yylloc.start = expression_yylloc.end;
    }
-[\t]     { 
-   yylloc.start.charPos++ /*= 3 - (yylloc.start.col % 3)*/; yylloc.end.charPos = yylloc.start.charPos; yylloc.start.pos = yylloc.end.pos; 
-   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; 
-   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; 
+[\t]     {
+   yylloc.start.charPos++ /*= 3 - (yylloc.start.col % 3)*/; yylloc.end.charPos = yylloc.start.charPos; yylloc.start.pos = yylloc.end.pos;
+   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;
+   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;
+   }
+[\r]  { yylloc.start = yylloc.end; expression_yylloc.start = expression_yylloc.end;  type_yylloc.start = type_yylloc.end; }
+.         {
+   yylloc.start = yylloc.end; expression_yylloc.start = expression_yylloc.end;  type_yylloc.start = type_yylloc.end;
+   if(inCompiler)
+      printf("lexer error: invalid char 0x%X at line %d, col %d\n", (unsigned char)yytext[0], yylloc.start.line, yylloc.start.charPos);
+   yyerror();
    }
-
-.         { yylloc.start = yylloc.end; expression_yylloc.start = expression_yylloc.end;  type_yylloc.start = type_yylloc.end; }
 
 %%
 
-yywrap()
+private:
+
+int yywrap()
 {
    return(1);
 }
@@ -317,7 +372,7 @@ int comment()
 
 int commentCPP()
 {
-   int c, last = 0;
+   int c; //, last = 0;
    for(;;)
    {
       c = input();
@@ -342,7 +397,7 @@ int commentCPP()
          yylloc.end.charPos++;
          yylloc.end.pos++;
       }
-      last = c;
+      //last = c;
    }
    yylloc.start = yylloc.end;
    return 0;
@@ -375,11 +430,13 @@ int preprocessor()
             if(lineNumber)
             {
                char fileName[MAX_LOCATION];
-               
+
                int inOut;
+
+               fileName[0] = 0;
                GetString(&pointer, fileName, MAX_LOCATION);
                inOut = GetValue(&pointer);
-                              
+
                if(inOut == 1)
                {
                   char extension[MAX_EXTENSION];
@@ -388,20 +445,25 @@ int preprocessor()
 
                   GetExtension(fileName, extension);
                   if(!strcmp(extension, "c") || !strcmp(extension, "h"))
-                     declMode = defaultDeclMode = defaultAccess;
+                     declMode = defaultDeclMode = structDeclMode = defaultAccess;
 
+                  fileStack[include_stack_ptr] = null;
                   include_stack_ptr++;
                }
                else if(inOut == 2)
                {
                   include_stack_ptr--;
-                  defaultDeclMode = declMode = declModeStack[include_stack_ptr];
+                  defaultDeclMode = declMode = structDeclMode = declModeStack[include_stack_ptr];
                }
 
                yylloc.end.charPos = 1;
                yylloc.end.line = lineNumber;
                //yylloc.end.pos -= count;
-               yylloc.end.included = (include_stack_ptr > 0) ? GetIncludeFileID(fileName) : 0;
+
+               if(include_stack_ptr > 0 || (lineNumber && fileName[0]))
+                  yylloc.end.included = GetIncludeFileID(fileName);
+               else
+                  yylloc.end.included = 0;
             }
             /*
             int lineNumber = strtol(line+1, &endPtr, 0);
@@ -435,7 +497,7 @@ int preprocessor()
          }
       }
       last = c;
-   }   
+   }
    yylloc.start = yylloc.end;
    line[count] = 0;
 
@@ -445,7 +507,7 @@ int preprocessor()
    {
       char includeFile[MAX_LOCATION] = "";
 
-      strcpy(line, line+c);
+      memmove(line, line+c, strlen(line+c)+1);
       TrimLSpaces(line, line);
       if(line[0] == '\"')
       {
@@ -472,7 +534,7 @@ int preprocessor()
 
       if ( include_stack_ptr >= MAX_INCLUDE_DEPTH )
       {
-         fprintf( stderr, "Includes nested too deeply" );
+         fprintf( stderr, "%s", $"Includes nested too deeply" );
          exit( 1 );
       }
 
@@ -495,14 +557,12 @@ int preprocessor()
 
             GetExtension(includeFile, extension);
             if(!strcmp(extension, "c") || !strcmp(extension, "h"))
-               declMode = defaultDeclMode = defaultAccess;
+               declMode = defaultDeclMode = structDeclMode = defaultAccess;
 
             fileInput = file;
             yy_switch_to_buffer( yy_create_buffer( fileInput, YY_BUF_SIZE ) );
             BEGIN(INITIAL);
          }
-         else
-            printf("");
       }
    }
    return 0;
@@ -514,17 +574,17 @@ public void resetScanner()
    yylloc.start.charPos = yylloc.end.charPos = 1;
    yylloc.start.line = yylloc.end.line = 1;
    yylloc.start.pos = yylloc.end.pos = 0;
-   yylloc.start.included = yylloc.end.included = false;
+   yylloc.start.included = yylloc.end.included = 0;
 
    expression_yylloc.start.charPos = expression_yylloc.end.charPos = 1;
    expression_yylloc.start.line = expression_yylloc.end.line = 1;
    expression_yylloc.start.pos = expression_yylloc.end.pos = 0;
-   expression_yylloc.start.included = expression_yylloc.end.included = false;
+   expression_yylloc.start.included = expression_yylloc.end.included = 0;
 
    type_yylloc.start.charPos = type_yylloc.end.charPos = 1;
    type_yylloc.start.line = type_yylloc.end.line = 1;
    type_yylloc.start.pos = type_yylloc.end.pos = 0;
-   type_yylloc.start.included = type_yylloc.end.included = false;
+   type_yylloc.start.included = type_yylloc.end.included = 0;
 
    include_stack_ptr = 0;
 }
@@ -536,3 +596,112 @@ void resetScannerPos(CodePosition pos)
    type_yylloc.start = type_yylloc.end = pos;
    expression_yylloc.start = expression_yylloc.end = pos;
 }
+
+class LexerBackup
+{
+   YYLTYPE yylloc;
+   YYLTYPE type_yylloc;
+   YYLTYPE expression_yylloc;
+
+   AccessMode declMode;
+   AccessMode defaultDeclMode;
+
+   File fileInput;
+   YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
+   File fileStack[MAX_INCLUDE_DEPTH];
+   char sourceFileStack[MAX_INCLUDE_DEPTH][MAX_LOCATION];
+   YYLTYPE locStack[MAX_INCLUDE_DEPTH];
+   AccessMode declModeStack[MAX_INCLUDE_DEPTH];
+   int include_stack_ptr;
+   YY_BUFFER_STATE buffer;
+
+   int yy_n_chars;
+   char * yytext_ptr;
+   char * yy_c_buf_p;
+   FILE * yyin;
+   char yy_hold_char;
+   int yychar;
+   int yy_init;
+   int yy_start;
+
+};
+
+LexerBackup pushLexer()
+{
+   LexerBackup backup { };
+
+   backup.yylloc = yylloc;
+   backup.type_yylloc = type_yylloc;
+   backup.expression_yylloc = expression_yylloc;
+   backup.fileInput = fileInput;
+   memcpy(backup.include_stack, include_stack, sizeof(include_stack));
+   memcpy(backup.fileStack, fileStack, sizeof(fileStack));
+   memcpy(backup.sourceFileStack, sourceFileStack, sizeof(sourceFileStack));
+   memcpy(backup.locStack, locStack, sizeof(locStack));
+   memcpy(backup.declModeStack, declModeStack, sizeof(declModeStack));
+   backup.include_stack_ptr = include_stack_ptr;
+   backup.defaultDeclMode = defaultDeclMode;
+   backup.declMode = declMode;
+   backup.buffer = yy_current_buffer;
+
+   backup.yy_n_chars = yy_n_chars;
+   backup.yytext_ptr = yytext_ptr;
+   backup.yy_c_buf_p = yy_c_buf_p;
+   backup.yyin = yyin;
+   backup.yy_hold_char = yy_hold_char;
+   backup.yychar = yychar;
+   backup.yy_init = yy_init;
+   backup.yy_start = yy_start;
+
+   yy_init = 1;
+
+   yy_current_buffer = 0;
+
+   yylloc.start.charPos = yylloc.end.charPos = 1;
+   yylloc.start.line = yylloc.end.line = 1;
+   yylloc.start.pos = yylloc.end.pos = 0;
+   yylloc.start.included = yylloc.end.included = 0;
+
+   expression_yylloc.start.charPos = expression_yylloc.end.charPos = 1;
+   expression_yylloc.start.line = expression_yylloc.end.line = 1;
+   expression_yylloc.start.pos = expression_yylloc.end.pos = 0;
+   expression_yylloc.start.included = expression_yylloc.end.included = 0;
+
+   type_yylloc.start.charPos = type_yylloc.end.charPos = 1;
+   type_yylloc.start.line = type_yylloc.end.line = 1;
+   type_yylloc.start.pos = type_yylloc.end.pos = 0;
+   type_yylloc.start.included = type_yylloc.end.included = 0;
+
+   include_stack_ptr = 0;
+
+   return backup;
+}
+
+void popLexer(LexerBackup backup)
+{
+   yylloc = backup.yylloc;
+   type_yylloc = backup.type_yylloc;
+   expression_yylloc = backup.expression_yylloc;
+   fileInput = backup.fileInput;
+   memcpy(include_stack, backup.include_stack, sizeof(include_stack));
+   memcpy(fileStack, backup.fileStack, sizeof(fileStack));
+   memcpy(sourceFileStack, backup.sourceFileStack, sizeof(sourceFileStack));
+   memcpy(locStack, backup.locStack, sizeof(locStack));
+   memcpy(declModeStack, backup.declModeStack, sizeof(declModeStack));
+   include_stack_ptr = backup.include_stack_ptr;
+   defaultDeclMode = backup.defaultDeclMode;
+   declMode = structDeclMode = backup.declMode;
+
+   // yy_switch_to_buffer(backup.buffer);
+   yy_current_buffer = backup.buffer;
+   yy_n_chars = backup.yy_n_chars;
+   yytext_ptr = backup.yytext_ptr;
+   yy_c_buf_p = backup.yy_c_buf_p;
+   yyin = backup.yyin;
+   yy_hold_char = backup.yy_hold_char;
+   yychar = backup.yychar;
+   yy_init = backup.yy_init;
+   yy_start = backup.yy_start;
+
+   delete backup;
+}