X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=tools%2Fminiswig%2Flexer.ll;h=954138b07fed3e9510061edefcd091c9a3a3e62f;hb=30f0f1d78e3f0bbbaf0b8d9d80fcbb579059941e;hp=3285ec4c49c00fe705387c8f326534b9f4a03044;hpb=60908c905544776c376421b8d3e12eeb936c068f;p=supertux.git diff --git a/tools/miniswig/lexer.ll b/tools/miniswig/lexer.ll index 3285ec4c4..954138b07 100644 --- a/tools/miniswig/lexer.ll +++ b/tools/miniswig/lexer.ll @@ -1,17 +1,37 @@ %{ +#include + #include #include -#include "tree.h" +#include +#include +#include "tree.hpp" #include "parser.hpp" -#include "globals.h" +#include "globals.hpp" -#define YY_DECL int yylex YY_PROTO(( YYSTYPE* yylval )) +// there seems to be a bug in flex that adds some ECHO directives +// in some rules, we don't need debug output +#define ECHO {} + +#define YY_NEVER_INTERACTIVE 1 +#define YY_DECL int yylex(YYSTYPE* yylval) #define YY_INPUT(buf, result, max_size) \ { \ input->read(buf, max_size); \ result = input->gcount(); \ } + +std::string last_docucomment; +std::string original_file; +std::string current_file; +std::string comm; +int offset_lnum; + +int getCurrentLine() +{ + return yylineno - offset_lnum; +} %} @@ -19,15 +39,52 @@ %option yylineno /* %option never-interactive */ +%x comment %% +#[ \t]+[0-9]+[ \t]+.* { + int lnum; + char file[1024]; + if(sscanf(yytext, "# %d \"%1023[^\"]\"", &lnum, file) == 2) { + offset_lnum = yylineno - lnum + 1; + current_file = file; + if(original_file == "") + original_file = file; + } else { + std::cerr << "Warning: Parse error in processor info directive.\n"; + } +} #.* /* ignore preprocessor directives */ [[:space:]]+ /* eat spaces */ -\/\*.*\*\/ /* eat comment */ -\/\/[^\n]*\n /* eat comment */ +"/*" { BEGIN(comment); comm = ""; } +[^*\n]* { comm += yytext; } +"*"+[^*/]* { comm += yytext; } +"*/" { + BEGIN(INITIAL); + if(comm[0] == '*') { // It's a docu comment... + last_docucomment = ""; + bool linestart = true; + for(size_t i = 1; i < comm.size(); ++i) { + if(linestart && (comm[i] == '*' || isspace(comm[i]))) { + continue; + } else if(comm[i] == '\n') { + linestart = true; + } else { + linestart = false; + } + last_docucomment += comm[i]; + } + } +} +\/\/[^\n]*\n { + if(yytext[2] == '/') { // it's a docu comment... + last_docucomment = std::string(yytext+3, strlen(yytext)-4); + } +} class { return T_CLASS; } struct { return T_STRUCT; } static { return T_STATIC; } +virtual { } const { return T_CONST; } unsigned { return T_UNSIGNED; } signed { return T_SIGNED; } @@ -43,18 +100,16 @@ public { return T_PUBLIC; } protected { return T_PROTECTED; } private { return T_PRIVATE; } namespace { return T_NAMESPACE; } +__suspend { return T_SUSPEND; } +__custom { return T_CUSTOM; } [a-zA-Z_][a-zA-Z_0-9]* { Namespace* ns = search_namespace; if(ns == 0) ns = current_namespace; // is it a type? - for(std::vector::iterator i = ns->types.begin(); - i != ns->types.end(); ++i) { - AtomicType* type = *i; - if(type->name == yytext) { - yylval->atomic_type = type; - return T_ATOMIC_TYPE; - } + yylval->atomic_type = ns->_findType(yytext, search_down); + if(yylval->atomic_type) { + return T_ATOMIC_TYPE; } // or a namespace? (hack for now...) yylval->_namespace = ns->_findNamespace(yytext, search_down); @@ -66,18 +121,18 @@ namespace { return T_NAMESPACE; } return T_ID; } \:\: { return T_DDCOL; } -[0-9]+ { - yylval->ival = atoi(yytext); - return T_INT; - } -[0-9]*\.[0-9]+(e[0-9]+)? { - yylval->fval = atof(yytext); - return T_FLOAT; - } -\".*\" { - yylval->str = strdup(yytext); - return T_STRING; - } +(0x)?[0-9]+ { + sscanf(yytext, "%i", &(yylval->ival)); + return T_INT; +} +[0-9]*\.[0-9]+(e[0-9]+)? { + sscanf(yytext, "%f", &(yylval->fval)); + return T_FLOAT; +} +\".*\" { + yylval->str = strdup(yytext); + return T_STRING; +} . { return yytext[0]; } %%