*include stdio.h in a couple files for MinGW GCC 4.4.0
[supertux.git] / tools / miniswig / lexer.ll
1 %{
2 #include <config.h>
3   
4 #include <math.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <iostream>
8 #include "tree.hpp"
9 #include "parser.hpp"
10 #include "globals.hpp"
11
12 // there seems to be a bug in flex that adds some ECHO directives
13 // in some rules, we don't need debug output
14 #define ECHO  {}
15
16 #define YY_NEVER_INTERACTIVE 1
17 #define YY_DECL int yylex(YYSTYPE* yylval)
18
19 #define YY_INPUT(buf, result, max_size)                     \
20 {                                                           \
21     input->read(buf, max_size);                             \
22     result = input->gcount();                               \
23 }
24
25 std::string last_docucomment;
26 std::string original_file;
27 std::string current_file;
28 std::string comm;
29 int offset_lnum;
30
31 int getCurrentLine()
32 {
33     return yylineno - offset_lnum;
34 }
35     
36 %}
37
38 %option noyywrap
39 %option yylineno
40 /* %option never-interactive */
41
42 %x comment
43 %%
44
45 #[ \t]+[0-9]+[ \t]+.*                         {
46     int lnum;
47     char file[1024];
48     if(sscanf(yytext, "# %d \"%1023[^\"]\"", &lnum, file) == 2) {
49         offset_lnum = yylineno - lnum + 1;
50         current_file = file;
51         if(original_file == "")
52             original_file = file;
53     } else {
54         std::cerr << "Warning: Parse error in processor info directive.\n";
55     }
56 }
57 #.*                                     /* ignore preprocessor directives */
58 [[:space:]]+                            /* eat spaces */
59 "/*"                                    { BEGIN(comment); comm = ""; }
60 <comment>[^*\n]*                        { comm += yytext; }
61 <comment>"*"+[^*/]*                     { comm += yytext; }
62 <comment>"*/"                    {
63     BEGIN(INITIAL);
64     if(comm[0] == '*') { // It's a docu comment...
65         last_docucomment = "";
66         bool linestart = true;
67         for(size_t i = 1; i < comm.size(); ++i) {
68             if(linestart && (comm[i] == '*' || isspace(comm[i]))) {
69                 continue;
70             } else if(comm[i] == '\n') {
71                 linestart = true;
72             } else {
73                 linestart = false;
74             }
75             last_docucomment += comm[i];
76         }
77     }
78 }
79 \/\/[^\n]*\n                            {
80     if(yytext[2] == '/') { // it's a docu comment...
81         last_docucomment = std::string(yytext+3, strlen(yytext)-4);
82     }
83 }
84 class                                   { return T_CLASS; }
85 struct                                  { return T_STRUCT; }
86 static                                  { return T_STATIC; }
87 virtual                                 { }
88 const                                   { return T_CONST; }
89 unsigned                                { return T_UNSIGNED; }
90 signed                                  { return T_SIGNED; }
91 void                                    { return T_VOID; }
92 bool                                    { return T_BOOL; }
93 char                                    { return T_CHAR; }
94 short                                   { return T_SHORT; }
95 int                                     { return T_INT; }
96 long                                    { return T_LONG; }
97 float                                   { return T_FLOAT; }
98 double                                  { return T_DOUBLE; }
99 public                                  { return T_PUBLIC; }
100 protected                               { return T_PROTECTED; }
101 private                                 { return T_PRIVATE; }
102 namespace                               { return T_NAMESPACE; }
103 __suspend                               { return T_SUSPEND; }
104 __custom                                { return T_CUSTOM; }
105 [a-zA-Z_][a-zA-Z_0-9]*                  {
106         Namespace* ns = search_namespace;
107         if(ns == 0)
108             ns = current_namespace;          
109         // is it a type?
110         yylval->atomic_type = ns->_findType(yytext, search_down);
111         if(yylval->atomic_type) {
112             return T_ATOMIC_TYPE;
113         }
114         // or a namespace? (hack for now...)
115         yylval->_namespace = ns->_findNamespace(yytext, search_down);
116         if(yylval->_namespace) {
117             return T_NAMESPACEREF;
118         }
119         // a new ID
120         yylval->str = strdup(yytext);
121         return T_ID;
122 }
123 \:\:                                    { return T_DDCOL; }
124 (0x)?[0-9]+ {
125         sscanf(yytext, "%i", &(yylval->ival));
126         return T_INT;
127 }
128 [0-9]*\.[0-9]+(e[0-9]+)? { 
129         sscanf(yytext, "%f", &(yylval->fval));
130         return T_FLOAT;
131 }
132 \".*\" {
133         yylval->str = strdup(yytext);
134         return T_STRING;
135 }
136 .                                       { return yytext[0]; }
137
138 %%
139