Line 8: | Line 8: | ||
Exemplo: | Exemplo: | ||
− | <text> | + | <source lang="text"> |
%option stack noyywrap yylineno 8bit debug | %option stack noyywrap yylineno 8bit debug | ||
%option c++ yyclass="CompactScanner" outfile="CompactScanner.cpp" | %option c++ yyclass="CompactScanner" outfile="CompactScanner.cpp" | ||
Line 24: | Line 24: | ||
} | } | ||
%% | %% | ||
− | </ | + | </source> |
== The Solution == | == The Solution == | ||
Line 30: | Line 30: | ||
[EXPLANATION COMING SOON] | [EXPLANATION COMING SOON] | ||
− | <text> | + | <source lang="text"> |
%option 8bit noyywrap yylineno stack debug | %option 8bit noyywrap yylineno stack debug | ||
%{ | %{ | ||
Line 93: | Line 93: | ||
return yylex(); | return yylex(); | ||
} | } | ||
− | </ | + | </source> |
[[category:Compiladores|Flex Lexical Analyzer]] | [[category:Compiladores|Flex Lexical Analyzer]] | ||
[[category:Ensino]] | [[category:Ensino]] |
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:
%option stack noyywrap yylineno 8bit debug
%option c++ yyclass="CompactScanner" outfile="CompactScanner.cpp"
%{
#include <string>
#include <cdk/nodes/Node.h>
#include "Scanner.h"
#include "Parser.tab.h"
%}
%%
" " return T_SPACE;
[A-Za-z][A-Za-z0-9_]* {
yylval.s = new std::string(yytext);
return T_VARIABLE;
}
%%
[EXPLANATION COMING SOON]
%option 8bit noyywrap yylineno stack debug
%{
#include <iostream>
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();
}