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