// Copyright (c) 2008 Pedro Quaresma, Coimbra, Portugal // Versão 2.0 // versão 1.0, desenvolvida por Augusto Pinho // (sob supervisão de Pedro Quaresma) %{ #include /* os índices do vector vão coincidir com os valores da codificação dos caracteres, que no caso dos caracteres acentuados é ajustada de forma a não haver conflitos, 122+1+32 = 155, isto dado não se poderem considerar índices negativos. O gasto de memória que esta solução implica não é (muito) significativo. */ #define MAXCOD 155 int paraminuscula(char c) { /* A diferença entre letras maiúsculas e minúsculas é de 32, no caso das letras não acentuadas pode-se usar a função pré-definida tolower, no caso das letras acentuadas essa função não faz nada */ if (c >= -64 && c <= -36) return(c+32); else return(c); } %} double conta_2l=0; double conta_3l=0; double conta_1l=0; double conta_2lT=0; double conta_3lT=0; double conta_1lT=0; int i=0; int j=0; int k=0; int l=0; int m=0; int n=0; long int Letr1[MAXCOD]; long int Letr2 [MAXCOD][MAXCOD]; long int Letr3 [MAXCOD][MAXCOD][MAXCOD]; char chI; char chF; /* Alfabeto de entrada */ letras [a-zA-Z]|"á"|"à"|"ã"|"â"|"ç"|"é"|"è"|"ê"|"í"|"ì"|"ó"|"ò"|"õ"|"ô"|"ú"|"ù"|"ü"|"Á"|"À"|"Ã"|"Â"|"Ç"|"É"|"È"|"Ê"|"Í"|"Ì"|"Ó"|"Ò"|"Õ"|"Ô"|"Ú"|"Ù"|"Ü" separadores "?"|"."|","|"!"|";"|":"|" "|")"|"("|"-"|\n quebras \n| %% /* Vamos assumir que as palavras curtas mais frequentes são com um número de letras inferior a 4 (cálculo feito através do programa "media.l". */ /* Não se vai diferenciar as maiúsculas das minúsculas */ ^{letras}{1,3}{separadores}{1} { // 1 letra if(yyleng == 2 ) { unput(yytext[1]); if(yytext[1]<0){ i =-1*paraminuscula(yytext[1])+123; } else { i=tolower(yytext[0]); } Letr1[i]=Letr1[i]+1; } // 2 letras if(yyleng == 3 ) { unput(yytext[2]); if(yytext[0]<0) i =-1*paraminuscula(yytext[0])+123; else i=tolower(yytext[0]); if(yytext[1]<0) j =-1*paraminuscula(yytext[1])+123; else j=tolower(yytext[1]); Letr2[i][j]=Letr2[i][j]+1; } // 3 letras if(yyleng == 4) { unput(yytext[3]); if(yytext[0]<0) i = -1*paraminuscula(yytext[0])+123; else i = tolower(yytext[0]); if(yytext[1]<0) j = -1*paraminuscula(yytext[1])+123; else j = tolower(yytext[1]); if(yytext[2]<0) k =-1*paraminuscula(yytext[2])+123; else k = tolower(yytext[2]); Letr3[i][j][k]=Letr3[i][j][k]+1; } } {separadores}{1}{letras}{1,3}{separadores}{1} { /* Existem caracteres especiais como por exemplo algumas letras acentuadas que possuiem uma "representação negativa" para evitar numeros negativos uma vez que não é possivel definir possições negativas num vector vamos somar nestes casos +123(avançando assim 123 posições, passando para a frente dos caracteres que nos interessam. */ // 1 letra if(yyleng == 3 ) { unput(yytext[2]); if(yytext[1]<0){ i =-1*paraminuscula(yytext[1])+123; } else { i = tolower(yytext[1]); } Letr1[i]=Letr1[i]+1; } // 2 letras if(yyleng == 4 ) { unput(yytext[3]); if(yytext[1]<0){ i = -1*paraminuscula(yytext[1])+123; } else { i = tolower(yytext[1]); } if(yytext[2]<0){ j = -1*paraminuscula(yytext[2])+123; } else { j = tolower(yytext[2]); } Letr2[i][j]=Letr2[i][j]+1; } // 3 letras if(yyleng == 5){ unput(yytext[4]); if(yytext[1]<0){ i = -1*paraminuscula(yytext[1])+123; } else { i = tolower(yytext[1]); } if(yytext[2]<0) { j = -1*paraminuscula(yytext[2])+123; } else { j = tolower(j=yytext[2]); } if(yytext[3]<0){ k = -1*paraminuscula(yytext[3])+123; } else { k = tolower(yytext[3]); } Letr3[i][j][k]=Letr3[i][j][k]+1; } } .|\n %% main(int argc, char *argv[]) { // interface linha de comando // media char *ficheiroEntrada,*ficheiroSaida; FILE *fsai, *fopen(); if (argc<=2) { // valores de entrada insuficientes (2+1) printf("\nUtilização: curtas nome_ficheiro_entrada nome_ficheiro_saída\n\n"); return; } // obtêm os argumentos da linha de comando ficheiroEntrada=argv[1]; ficheiroSaida=argv[2]; printf ("\nFicheiro a Processar: %s\nFicheiro com resultados: %s\n\n",ficheiroEntrada,ficheiroSaida); if ((yyin = fopen(ficheiroEntrada,"r")) == NULL) { printf("Não foi possível abrir o ficheiro %s\n",ficheiroEntrada); } else if ((fsai = fopen(ficheiroSaida,"w")) == NULL) { printf("Não foi possível abrir para escrita o ficheiro %s\n",ficheiroSaida); } else { // processar yylex(); /* Palavras de uma letra: conta palavras de uma letra; */ conta_1l=0; conta_1lT=0; for (i=0; i < MAXCOD; i++) if(Letr1[i]!=0) { conta_1l=conta_1l+1; conta_1lT=conta_1lT+Letr1[i]; } /* vai escrever as palavras de 2 letras determinando a resepectiva frequencia; */ fprintf(fsai,"1 letra: \n"); for (i=0; i < MAXCOD; i++) { if(Letr1[i]!=0) { if (i>123) k=-1*(i-123); else k=i; fprintf(fsai,"%c\t%0.6f\n",k,(Letr1[i]/conta_1lT)*100); } } /* Palavras de duas letras conta nº total de palavras com 2 letras: */ conta_2l=0; conta_2lT=0; for (i=0; i < MAXCOD; i++) for(j=0;j < MAXCOD; j++) if(Letr2[i][j]!=0) { conta_2l=conta_2l+1; conta_2lT=conta_2lT+Letr2[i][j]; } fprintf(fsai,"\n2 letras: \n"); /* vai escrever as palavras de 3 letras determinando a respectiva frequência; */ for (i=0; i < MAXCOD; i++) for(j=0;j < MAXCOD; j++) { if(Letr2[i][j]!=0) { if (i>123) k=-1*(i-123); else k=i; if (j>123) l=-1*(j-123); else l=j; fprintf(fsai,"%c%c\t%0.6f\n",k,l,(Letr2[i][j]/conta_2lT)*100); } } /* Palavras de três letras conta nº total de palavras com 3 letras: */ conta_3l=0; conta_3lT=0; for (i=0; i < MAXCOD; i++) for(j=0;j < MAXCOD; j++) for(n=0;n < MAXCOD; n++) if(Letr3[i][j][n]!=0) { conta_3l=conta_3l+1; conta_3lT=conta_3lT+Letr3[i][j][n]; } /* vai escrever as palavras de 2 letras determinando a respectiva frequência; */ fprintf(fsai,"\n3 letras: \n"); for (i=0; i < MAXCOD; i++) for(j=0;j < MAXCOD; j++) for(n=0;n < MAXCOD; n++) { if(Letr3[i][j][n]!=0) { if (i>123) k=-1*(i-123); else k=i; if (j>123) l=-1*(j-123); else l=j; if (n>123) m=-1*(n-123); else m=n; fprintf(fsai,"%c%c%c\t%0.6f\n",k,l,m,(Letr3[i][j][n]/conta_3lT)*100); } } } }