%{ #include #define showcase #ifdef showcase enum Flags { TYPE, UPPERLOWER, SEVENBIT, LENTABLE, COMP, CONST, ENUM, INCLUDE, GLOBAL, SHAREDLIB, NULLSTRINGS, NOTYPE, }; class Options { public: #define SMETHOD(X) void X(char* s) { std::cout << #X << ": " << s << std::endl; } SMETHOD(set_delimiters) SMETHOD(set_language) void set_total_switches(int s) { std::cout << "set_total_switches: " << s << std::endl; } SMETHOD(set_stringpool_name) SMETHOD(set_constants_prefix) SMETHOD(set_wordlist_name) SMETHOD(set_lengthtable_name) SMETHOD(set_hash_name) SMETHOD(set_function_name) SMETHOD(set_class_name) SMETHOD(set_slot_name) SMETHOD(set_initializer_suffix) void set(Flags f) { switch(f) { #define FLAG(X) case X: std::cout << "set: " << #X << std::endl; break; FLAG(TYPE) FLAG(UPPERLOWER) FLAG(SEVENBIT) FLAG(LENTABLE) FLAG(COMP) FLAG(CONST) FLAG(ENUM) FLAG(INCLUDE) FLAG(GLOBAL) FLAG(SHAREDLIB) FLAG(NULLSTRINGS) FLAG(NOTYPE) } } }; Options option; #else #include "options.h" #endif %} %option c++ %option noyywrap %option yylineno %x DECL_SOL %x DECL_EOL %x DECL_VERBATIM %x DECL_DELIMITERS %x DECL_LANGUAGE %x DECL_SWITCH %x DECL_DEFINE %x DECL_DEFINE_STRINGPOOL_NAME %x DECL_DEFINE_CONSTANTS_PREFIX %x DECL_DEFINE_WORDLIST_NAME %x DECL_DEFINE_LENGTHTABLE_NAME %x DECL_DEFINE_SLOT_NAME %x DECL_DEFINE_INITIALIZER_SUFFIX %x DECL_DEFINE_HASH_NAME %x DECL_DEFINE_FUNCTION_NAME %x DECL_DEFINE_CLASS_NAME %x DECL_DEFINE_ERROR %x KEYWORDS %x ADDITIONALCODE WS [ \r\t]+ oWS {WS}? nWS [^ \r\n\t]+ alnum [a-zA-Z0-9_] id [a-zA-Z_][a-zA-Z0-9_]* EOL \r?\n %% {oWS}{EOL} { } {oWS}% { BEGIN(DECL_SOL); } {oWS}[^%\r\n]+{EOL} { std::cerr << "invalid Declaration-Line: " << yytext << std::endl; } { \%{oWS} { BEGIN(KEYWORDS); } \{ { BEGIN(DECL_VERBATIM); } struct[_\-]type { option.set (TYPE); BEGIN(DECL_EOL); } ignore[_\-]case { option.set (UPPERLOWER); BEGIN(DECL_EOL); } 7bit { option.set (SEVENBIT); BEGIN(DECL_EOL); } compare[_\-]lengths { option.set (LENTABLE); BEGIN(DECL_EOL); } compare[_\-]strncmp { option.set (COMP); BEGIN(DECL_EOL); } readonly[_\-]tables { option.set (CONST); BEGIN(DECL_EOL); } enum { option.set (ENUM); BEGIN(DECL_EOL); } includes { option.set (INCLUDE); BEGIN(DECL_EOL); } global[_\-]table { option.set (GLOBAL); BEGIN(DECL_EOL); } pic { option.set (SHAREDLIB); BEGIN(DECL_EOL); } null[_\-]strings { option.set (NULLSTRINGS); BEGIN(DECL_EOL); } omit[_\-]struct[_\-]type { option.set (NOTYPE); BEGIN(DECL_EOL); } delimiters= { BEGIN(DECL_DELIMITERS); } language= { BEGIN(DECL_LANGUAGE); } switch= { BEGIN(DECL_SWITCH); } define{WS} { BEGIN(DECL_DEFINE); } [^ \r\n\t=]+ { std::cerr << "unexpected declarations-line: %" << yytext << std::endl; BEGIN(DECL_EOL); } } (([^%]*)(\%*[^%\}]))* { /* yytext -> VERBATIM */ } %\} { BEGIN(DECL_EOL); } {nWS}* { option.set_delimiters(yytext); BEGIN(DECL_EOL); } {nWS}* { option.set_language(yytext); BEGIN(DECL_EOL); } [0-9]* { option.set_total_switches(atoi(yytext)); BEGIN(DECL_EOL); } { string[_\-]pool[_\-]name{WS} { BEGIN(DECL_DEFINE_STRINGPOOL_NAME); } constants[_\-]prefix{WS} { BEGIN(DECL_DEFINE_CONSTANTS_PREFIX); } word[_\-]array[_\-]name{WS} { BEGIN(DECL_DEFINE_WORDLIST_NAME); } length[_\-]table[_\-]namename{WS} { BEGIN(DECL_DEFINE_LENGTHTABLE_NAME); } slot[_\-]name{WS} { BEGIN(DECL_DEFINE_SLOT_NAME); } initializer-suffix{WS} { BEGIN(DECL_DEFINE_INITIALIZER_SUFFIX); } hash[_\-]function[_\-]name{WS} { BEGIN(DECL_DEFINE_HASH_NAME); } lookup[_\-]function[_\-]name{WS} { BEGIN(DECL_DEFINE_FUNCTION_NAME); } class[_\-]name{WS} { BEGIN(DECL_DEFINE_CLASS_NAME); } [^ \r\n\t]+ { std::cerr << "unknown define-directive " << yytext << std::endl; BEGIN(DECL_DEFINE_ERROR); } {EOL} { std::cerr << "unfinished define-directive" << std::endl; BEGIN(INITIAL); } } {id}? { option.set_stringpool_name(yytext); BEGIN(DECL_EOL); } {id}? { option.set_constants_prefix(yytext); BEGIN(DECL_EOL); } {id}? { option.set_wordlist_name(yytext); BEGIN(DECL_EOL); } {id}? { option.set_lengthtable_name(yytext); BEGIN(DECL_EOL); } {id}? { option.set_hash_name(yytext); BEGIN(DECL_EOL); } {id}? { option.set_function_name(yytext); BEGIN(DECL_EOL); } {id}? { option.set_class_name(yytext); BEGIN(DECL_EOL); } {alnum}* { option.set_slot_name(yytext); BEGIN(DECL_EOL); } {nWS}? { option.set_initializer_suffix(yytext); BEGIN(DECL_EOL); } {oWS}{nWS}? { /* ignore the value of a non-existend %define value */ BEGIN(DECL_EOL); } {oWS}{EOL} { BEGIN(INITIAL); } {oWS}({nWS}+{oWS})+{EOL} { std::cerr << "unexpected text after declaration line: " << yytext << std::endl; BEGIN(INITIAL);} {oWS}{EOL} { /* ignore empty lines and \n at end-of-lines */ } ^%%{EOL} { BEGIN(ADDITIONALCODE); } ^[^\r\n]*$ { std::cout << "KEYWORD: " << yytext << std::endl; } {EOL} { /* ignore empty lines and \n at end-of-lines */ } ^[^\r\n]*$ { std::cout << "ADDITIONAL CODE: " << yytext << std::endl; } <> { return 0; } %% int main(int argc, char** argv) { yyFlexLexer l(std::cin, std::cout); l.yylex(); return 0; }