(New page: == The Problem (in Portuguese) == Crie um analisador lexical (especificação para a ferramenta Flex) que aceite uma especificação YACC e que a copie para a saída sem as acções semâ...) |
(→The Solution) |
||
Line 20: | Line 20: | ||
== The Solution == | == The Solution == | ||
+ | |||
+ | [EXPLANATION COMING SOON] | ||
<text> | <text> |
Crie um analisador lexical (especificação para a ferramenta Flex) que aceite uma especificação YACC e que a copie para a saída sem as acções semânticas associadas às regras. Codifique todas as rotinas auxiliares.
A especificação YACC, tal como a do 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.
Cada regra YACC começa com um símbolo não terminal, seguido por : e por uma sequência de símbolos terminais e não terminais, acções semânticas e, eventualmente, alternativas (indicadas por|). Cada regra é terminada por ;. As acções semânticas são delimitadas por {} e podem conter código C/C++ arbitrário. Os identificadores dos símbolos começam com uma letra que pode ser seguida por caracteres alfanuméricos ou _. Caracteres individuais podem aparecer como terminais (delimitados por ').
Exemplo: <text> %union { int i; } %token ID %type<i> expr %% expr : expr '+' expr { $$ = $1 + $3; }
| ID { $$ = $1; } ;
%% </text>
[EXPLANATION COMING SOON]
<text> %option 8bit noyywrap yylineno stack %{
int count = 0; inline void yyerror(const char *msg) {
std::cerr << "Error at " << yylineno << ": " << msg << std::endl;
} %} %x X_STRIGN X_COMMENT X_CHAR X_CHARIGN X_CODE X_RULES %%
^"%%" yy_push_state(X_RULES);
<X_RULES>\' yy_push_state(X_CHAR); ECHO; <X_CHAR>\' yy_pop_state(); ECHO; <X_CHAR>\\\' ECHO; <X_CHAR>. ECHO; <X_CHAR>\n yyerror("newline in char");
<X_RULES>"{" yy_push_state(X_CODE); <X_CODE>"}" yy_pop_state();
<X_CODE>\' yy_push_state(X_CHARIGN); <X_CHARIGN>\' yy_pop_state(); ; <X_CHARIGN>\\\' ; <X_CHARIGN>. ; <X_CHARIGN>\n yyerror("newline in char");
<X_CODE>\" yy_push_state(X_STRIGN); <X_STRIGN>\\\" ; <X_STRIGN>\" yy_pop_state(); <X_STRIGN>. ; <X_STRIGN>\n yyerror("newline in string");
<X_CODE>"/*" yy_push_state(X_COMMENT); <X_COMMENT>"/*" yy_push_state(X_COMMENT); <X_COMMENT>"*/" yy_pop_state(); <X_COMMENT>.|\n ;
<X_CODE>"//".*$ ; <X_CODE>.|\n ;
<X_RULES>^"%%" yy_pop_state(); /* code section */
<INITIAL,X_RULES>.|\n ECHO; /* echo the rest */
%% int main() {
yylex(); std::cout << count << std::endl; return 0;
} </text>