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