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