#! /usr/bin/gawk -f # Last edited on 2004-12-30 20:37:31 by stolfi # check-lex-format - VERIFICA O FORMATO DO DICIONARIO # # Para checar arquivo de dicionario padrao completo "{PALAVRA} {CLASSE} {CANONICA}" # uso: gawk -f check-lex-format -v colunas=3 catergories.tbc dic1 dic2 dic3 dic4 ... # # Para checar arquivo de dicionario extra incompleto "{PALAVRA}" ou "{PALAVRA} {CLASSE} {CANONICA}" # uso: gawk -f check-lex-format categories.tbc lex_extra BEGIN { # FORMATO DE PADROES contracao = "ct" enclise = "en" mesoclise = "me" contraido = "((" contracao ")|(" enclise ")|(" mesoclise "))" lexico = "[^,;()]+[,][a-z0-9]+[,][^,;()]+" padrao = "[(]" lexico "[;]" lexico "([;]" lexico ")?[)]" # VARIAVEIS prev = "" # nome do arquivo anterior ja lido erros = 0 # flag indicador de erros para o atual arquivo tabela = ARGV[1] # nome da tabela de categorias # colunas # variavel de entrada que indica o numero de colunas # do dicionario a checar (3-completo/indefinida-incompleto) } # CODIGO DO PROGRAMA FILENAME == tabela { classe[$1] = 0 # carrega as classes existentes no vetor classe next } FILENAME != prev { # se esta iniciando novo arquivo de dicionario close(prev) # fecha arquivo ja lido prev = FILENAME # guarda nome deste arquivo erros = 0 # zera flag de erros para este arquivo } // { gsub(/[\r]+/,"") # retira carriage return se arquivo eh do dos gsub(/[ \t]+/," ") # converte espacos e tabs multiplos para um so espaco gsub(/^[ ]/,"") # retira espaco no inicio da linha gsub(/[ ]$/,"") # retira espaco no fim da linha printf("%s\n", $0) # imprime a linha modificada } /^[#]/ { next; } # ignora comentarios /^$/ { next; } # ignora linha em branco (NF != 3) && (NF != 1) { # formato do lexico deve ser: palavra classe canonica erro("número de campos diferente de 3") } (NF == 1) && (colunas == 3) { # dicionario incompleto nao permitido nesta forma de execucao erro("número de campos diferente de 3") } (NF == 3) { # verifica se a(s) classe(s) indicada(s) existe(m) if (!($2 in classe)) erro("classe " $2 " inexistente") else if ($2 ~ "^" contraido "$") # se e' contracao, enclise ou mesoclise if ($3 !~ "^" padrao "$") # verifica formato da expansao da contracao erro("formato incorreto da expansão da contração") else # verifica classes da expansao da contracao { classe1 = gensub(/[(].+[,](.+)[,].+[;].+([;].+)?[)]/,"\\1","g",$3) # classe do primeiro lexico classe2 = gensub(/[(].+[;].+[,](.+)[,].+([;].+)?[)]/,"\\1","g",$3) # classe do segundo lexico classe3 = gensub(/[(].+[;].+([;].+[,](.+)[,].+)?[)]/,"\\2","g",$3) # classe do terceiro lexico (se existe) if (!(classe1 in classe)) erro("classe " classe1 " inexistente") if (!(classe2 in classe)) erro("classe " classe2 " inexistente") if (classe3 != "") if (!(classe3 in classe)) erro("classe " classe3 " inexistente") } } function erro(msg) { if (erros == 0) { printf "Arquivo %s:\n", FILENAME > "/dev/stderr" erros = 1 } printf "linha %d - %s: %s\n", FNR, msg, $0 > "/dev/stderr"; }