Crie um analisador lexical (especificação para a ferramenta Flex) que aceite uma especificação Flex e que a copie para a saída sem as acções associadas às regras. Codifique todas as rotinas auxiliares.
Uma especificação Flex, está dividida em três zonas separadas por %% (declarações, regras, código). As zonas de declarações e código devem ser copiadas integralmente para a saída.
Considere que cada regra Flex começa com um padrão (possivelmente precedido por uma lista de condições entre < e >), seguido por espaços brancos ou tabulações e por uma acção. Cada acção (constituída por código C/C++ arbitrário) pode ser escrita ao longo de várias linhas se estiver delimitada por {}, caso contrário, termina no final da linha. Cada padrão é composto por símbolos do alfabeto da linguagem e por vários operadores. Espaços que apareçam nos padrões devem ser precedidos por \ ou aparecer entre aspas (").
Exemplo: <text> %option stack noyywrap yylineno 8bit debug %option c++ yyclass="CompactScanner" outfile="CompactScanner.cpp" %{
%} %% " " return T_SPACE; [A-Za-z][A-Za-z0-9_]* {
yylval.s = new std::string(yytext); return T_VARIABLE; }
%% </text>
[EXPLANATION COMING SOON]
<text> %option 8bit noyywrap yylineno stack debug %{
inline void yyerror(const char *msg) {
std::cerr << "Error at " << yylineno << ": " << msg << std::endl;
} %} %x X_RULES X_RANGE X_STRING X_CODE1 X_CODE2 X_STRIGN X_CHARIGN X_COMMENT %%
^"%%" ECHO; yy_push_state(X_RULES);
<X_RULES>^[ \t]+.*\n ECHO; //lines to be ignored
<X_RULES>"[" ECHO; yy_push_state(X_RANGE); <X_RANGE>"]" ECHO; yy_pop_state(); <X_RANGE>"\\[" ECHO; <X_RANGE>"\\]" ECHO; <X_RANGE>. ECHO; <X_RANGE>\n yyerror("newline in range");
<X_RULES>\\\" ECHO; //avoid erroneous transition <X_RULES>\" ECHO; yy_push_state(X_STRING); <X_STRING>\" ECHO; yy_pop_state(); <X_STRING>\\\" ECHO; <X_STRING>. ECHO; <X_STRING>\n yyerror("newline in string");
<X_RULES>[ \t]+ yy_push_state(X_CODE1); <X_CODE1>\n ECHO; yy_pop_state(); <X_CODE1>"{" yy_push_state(X_CODE2); <X_CODE2>"}" yy_pop_state();
<X_CODE1,X_CODE2>\' yy_push_state(X_CHARIGN); <X_CHARIGN>\' yy_pop_state(); <X_CHARIGN>\\\' ; <X_CHARIGN>. ; <X_CHARIGN>\n yyerror("newline in char");
<X_CODE1,X_CODE2>\" yy_push_state(X_STRIGN); <X_STRIGN>\\\" ; <X_STRIGN>\" yy_pop_state(); <X_STRIGN>. ; <X_STRIGN>\n yyerror("newline in string");
<X_RULES,X_CODE1,X_CODE2>"/*" yy_push_state(X_COMMENT); <X_COMMENT>"/*" yy_push_state(X_COMMENT); <X_COMMENT>"*/" yy_pop_state(); <X_COMMENT>.|\n ;
<X_RULES,X_CODE1,X_CODE2>"//".*$ ; <X_CODE1>. ; <X_CODE2>.|\n ;
<X_RULES>^"%%" ECHO; yy_pop_state(); /* code section */
<INITIAL,X_RULES>.|\n ECHO; /* echo the rest */
%% int main() {
return yylex();
} </text>