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