(One intermediate revision by the same user not shown) | |||
Line 11: | Line 11: | ||
Comments in the specification explain the ideas. | Comments in the specification explain the ideas. | ||
− | <text> | + | <source lang="text"> |
%option stack 8bit noyywrap yylineno | %option stack 8bit noyywrap yylineno | ||
%{ | %{ | ||
Line 31: | Line 31: | ||
<xCHAR>\' code_length += yyleng; yy_pop_state(); | <xCHAR>\' code_length += yyleng; yy_pop_state(); | ||
<xCHAR>\\\' code_length += yyleng; // escaped quote (not a true char delimiter) | <xCHAR>\\\' code_length += yyleng; // escaped quote (not a true char delimiter) | ||
+ | <xCHAR>\\\\ code_length += yyleng; // escaped backslash | ||
<xCHAR>. code_length += yyleng; // we are not controlling char length | <xCHAR>. code_length += yyleng; // we are not controlling char length | ||
<xCHAR>\n yyerror("newline in char"); | <xCHAR>\n yyerror("newline in char"); | ||
Line 39: | Line 40: | ||
<xSTRING>\" code_length += yyleng; yy_pop_state(); | <xSTRING>\" code_length += yyleng; yy_pop_state(); | ||
<xSTRING>\\\" code_length += yyleng; // escaped double quote (not a true string delimiter) | <xSTRING>\\\" code_length += yyleng; // escaped double quote (not a true string delimiter) | ||
+ | <xSTRING>\\\\ code_length += yyleng; // escaped backslash | ||
<xSTRING>. code_length += yyleng; | <xSTRING>. code_length += yyleng; | ||
<xSTRING>\n yyerror("newline in string"); | <xSTRING>\n yyerror("newline in string"); | ||
Line 57: | Line 59: | ||
std::cout << "Comments length: " << comments_length << std::endl; | std::cout << "Comments length: " << comments_length << std::endl; | ||
} | } | ||
− | </ | + | </source> |
[[category:Compiladores|Flex Lexical Analyzer]] | [[category:Compiladores|Flex Lexical Analyzer]] | ||
[[category:Ensino]] | [[category:Ensino]] |
Test 1 201608081800.
Crie um analisador lexical (especificação para a ferramenta Flex) que aceite um ficheiro C++ (ou Java) e que apresente na saída (std::cout) o rácio entre as dimensões (número de caracteres) do código e dos comentários no texto do programa. Espaços brancos são contabilizados como código.
Note que nem todas as ocorrências das sequências de início e fim de comentário (i.e., //, /*, */), correspondem sempre a delimitadores de comentários. Considere ainda que os comentários em C++ (ou Java) não podem estar aninhados (a sequência /* pode ocorrer num comentário, mas isso não implica aninhamento). Considere que os ficheiros a processar estão bem formados (ou seja, os ficheiros não têm erros de escrita).
Comments in the specification explain the ideas.
%option stack 8bit noyywrap yylineno
%{
#include <iostream>
namespace {
// module-private variables
int code_length = 0;
int comments_length = 0;
}
void yyerror(const char *msg);
%}
%x xCHAR xSTRING xCOMMENT
%%
/* detect chars: they may contain double quotes that do not start strings */
\' code_length += yyleng; yy_push_state(xCHAR);
<xCHAR>\' code_length += yyleng; yy_pop_state();
<xCHAR>\\\' code_length += yyleng; // escaped quote (not a true char delimiter)
<xCHAR>\\\\ code_length += yyleng; // escaped backslash
<xCHAR>. code_length += yyleng; // we are not controlling char length
<xCHAR>\n yyerror("newline in char");
/* detect strings: they may contain false comment delimiters */
\" code_length += yyleng; yy_push_state(xSTRING);
<xSTRING>\" code_length += yyleng; yy_pop_state();
<xSTRING>\\\" code_length += yyleng; // escaped double quote (not a true string delimiter)
<xSTRING>\\\\ code_length += yyleng; // escaped backslash
<xSTRING>. code_length += yyleng;
<xSTRING>\n yyerror("newline in string");
"/*" comments_length += yyleng; yy_push_state(xCOMMENT);
<xCOMMENT>"*/" comments_length += yyleng; yy_pop_state();
<xCOMMENT>.|\n comments_length += yyleng; // everything else (including other "/*" sequences)
"//".*$ comments_length += yyleng;
.|\n code_length += yyleng;
%%
void yyerror(const char *msg) { std::cerr << msg << std::endl; }
int main() {
yylex();
std::cout << "Code length: " << code_length << std::endl;
std::cout << "Comments length: " << comments_length << std::endl;
}