Crie um analisador lexical (especificação para a ferramenta Flex) que aceite uma lista de faixas musicais, contendo os respectivos títulos, artistas (intérpretes, compositores, etc.), durações e anotações (comentários) e que indique qual o número de faixas com mais de 3 minutos, para cada artista presente na colecção. Algumas linhas começam com espaços brancos e correspondem a comentários do dono da colecção relativamente à faixa anterior e devem ser ignoradas.
Cada uma das linhas com informação tem os seguintes campos (separados por um ou mais caracteres de tabulação):
o resto da linha corresponde a anotações (comentários)
Codifique todas as funções auxiliares. Pode utilizar estruturas de dados C++ e da STL (e.g. std::string, std::vector, std::map, etc.). Por simplicidade, considere os caracteres acentuados iguais aos não acentuados.
Download this example: Playlist.txt.
Lady Gaga Bad Romance 5:08 http://www.youtube.com/watch?v=qrO4YZeyl0I
Lady Gaga Telephone 9:31 Kill Bill
Current 93 All The Pretty Little Horses 02:38
Nick Cave sings
Antonín Dvořák "Symphony No. 9 in E Minor, Op. 95" 41:00
Wikipedia: http://en.wikipedia.org/wiki/Symphony_No._9_(Dvořák)
Petrucci Music Library: http://imslp.org/wiki/Symphony_No.9,_Op.95_(Dvořák,_Antonín)
Current 93 When the May Rain Comes 3:25
Current 93 Falling 4:22 feat. Björk
The Killers Spaceman 4:46
it's all in your mind
The Killers Human 4:10
The Killers All The Pretty Faces 4:47
The Killers "Mr. Brightside" 3:46 Yet another...
David Bowie Space Oddity 3:48 The original Major Tom
Peter Schilling Major Tom 2:50 David Bowie's space oddity some years later
Shiny Toy Guns Major Tom 4:11 Is time kind to Major Tom?
This is a 2009 cover of the 1983 song
(which was inspired by the original from 1969)
Lady Gaga 2
Current 93 2
Antonín Dvořák 1
The Killers 4
David Bowie 1
Shiny Toy Guns 1
The main idea is to locate the artist names, then the number of minutes. The task is made ambiguous because several characters have multiple functions at different stages in the processing of a given line:
The solution below contains code to track all the above situations.
Download this code: Playlist.l.
%option 8bit noyywrap yylineno
%{
#include <iostream>
#include <string>
#include <map>
static std::map<std::string, int> counts;
static std::string artist;
inline void yyerror(const char *msg) { std::cout << msg << std::endl; }
%}
NAME [[:alnum:]][- _:[:alnum:]]*
MINUTES [[:digit:]]+
COMMENT ^[ \t]+.*$
%x X_ARTIST X_TITLE X_STRING X_MINUTES
%%
{COMMENT} ; /* ignore */
^{NAME} artist = yytext; BEGIN(X_TITLE);
^\" artist = ""; BEGIN(X_ARTIST);
<X_ARTIST>\" BEGIN(X_TITLE);
<X_ARTIST>\\\" artist += '"';
<X_ARTIST>. artist += *yytext;
<X_ARTIST>\n yyerror("should not happen!");
<X_TITLE>{NAME} BEGIN(X_MINUTES); /* not needed: ignore */
<X_TITLE>\" BEGIN(X_STRING);
<X_STRING>\" BEGIN(X_MINUTES);
<X_STRING>.|\\\" ; /* not needed: ignore */
<X_STRING>\n yyerror("should not happen!");
<X_MINUTES>{MINUTES} {
int minutes = strtol(yytext, NULL, 10);
if (minutes > 2) counts[artist]++;
}
<X_MINUTES>":".*$ BEGIN(INITIAL);
<X_TITLE,X_MINUTES>\t+ ;
<INITIAL,X_TITLE,X_MINUTES>. yyerror("should not happen!");
\n ; /* ignore */
%%
int main() {
yylex();
for (std::map<std::string, int>::iterator it = counts.begin();
it != counts.end(); it++) {
std::cout << it->first << " " << it->second << std::endl;
}
}