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 plicas ').
Exemplo de entrada e de saída | ||||
---|---|---|---|---|
|
This solution assumes that comments only occur in actions in the rules section.
[EXPLANATION COMING SOON]
Solução |
---|
%option 8bit noyywrap yylineno stack
%{
#include <iostream>
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_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;
}
|