Difference between revisions of "The Flex Lexical Analyzer/Exercise 9 - Comments/code ratio in C++ and Java"

From Wiki**3

< The Flex Lexical Analyzer
(Created page with "== The Problem (in Portuguese) == Crie um analisador lexical (especificação para a ferramenta Flex) que aceite um ficheiro C++ (ou Java) e que apresente na saída ('''std::...")
 
 
(2 intermediate revisions by the same user not shown)
Line 1: Line 1:
 +
Test 1 201608081800.
 +
 
== The Problem (in Portuguese) ==
 
== The Problem (in Portuguese) ==
  
Line 9: 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 29: 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 37: 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 55: Line 59:
 
   std::cout << "Comments length: " << comments_length << std::endl;
 
   std::cout << "Comments length: " << comments_length << std::endl;
 
}
 
}
</text>
+
</source>
  
 
[[category:Compiladores|Flex Lexical Analyzer]]
 
[[category:Compiladores|Flex Lexical Analyzer]]
 
[[category:Ensino]]
 
[[category:Ensino]]

Latest revision as of 13:49, 4 March 2019

Test 1 201608081800.

The Problem (in Portuguese)

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).

The Solution

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;
}