#! /usr/bin/gawk -f # Last edited on 2001-11-20 15:28:57 by stolfi # TRANSFORMACAO: # # # 1)A) DE: # funcao(Tracos):nomefuncao-> # funcao1(Tracos1), # funcao2(Tracos2), # *funcao3(Tracos3), # funcao4(Tracos4), # funcao5(Tracos5). # # PARA: # funcao(S1,S,INF,SUP,_,A,Tracos):- # funcao3(S3,S4,INF,SUP,d,A3,Tracos3), # funcao2(S2,S3,INF,S3,e,A2,Tracos2), # funcao1(S1,S2,INF,S2,e,A1,Tracos1), # funcao4(S4,S5,S4,SUP,d,A4,Tracos4), # funcao5(S5,S,S5,SUP,d,A5,Tracos5), # monta_arv(A,nomefuncao,[A1,A2,A3,A4,A5]). # # # 1)B) DE: # funcao(Tracos):.-> # funcao1(Tracos1), # funcao2(Tracos2), # *funcao3(Tracos3), # funcao4(Tracos4), # funcao5(Tracos5). # # PARA: # funcao(S1,S,INF,SUP,_,A,Tracos):- # funcao3(S3,S4,INF,SUP,d,A3,Tracos3), # funcao2(S2,S3,INF,S3,e,A2,Tracos2), # funcao1(S1,S2,INF,S2,e,A1,Tracos1), # funcao4(S4,S5,S4,SUP,d,A4,Tracos4), # funcao5(S5,S,S5,SUP,d,A5,Tracos5), # monta_arv(A,.,[A1,A2,A3,A4,A5]). # # # 1)C) DE: # funcao(Tracos)-> # funcao1(Tracos1), # funcao2(Tracos2), # *funcao3(Tracos3), # funcao4(Tracos4), # funcao5(Tracos5). # # PARA: # funcao(S1,S,INF,SUP,_,A,Tracos):- # funcao3(S3,S4,INF,SUP,d,A3,Tracos3), # funcao2(S2,S3,INF,S3,e,A2,Tracos2), # funcao1(S1,S2,INF,S2,e,A1,Tracos1), # funcao4(S4,S5,S4,SUP,d,A4,Tracos4), # funcao5(S5,S,S5,SUP,d,A5,Tracos5), # monta_arv(A,funcao,[A1,A2,A3,A4,A5]). # # # 1)D) DE: # funcao-> # funcao1(Tracos1), # funcao2(Tracos2), # *funcao3(Tracos3), # funcao4, # funcao5(Tracos5). # # PARA: # funcao(S1,S,INF,SUP,_,A):- # funcao3(S3,S4,INF,SUP,d,A3,Tracos3), # funcao2(S2,S3,INF,S3,e,A2,Tracos2), # funcao1(S1,S2,INF,S2,e,A1,Tracos1), # funcao4(S4,S5,S4,SUP,d,A4), # funcao5(S5,S,S5,SUP,d,A5,Tracos5), # monta_arv(A,funcao,[A1,A2,A3,A4,A5]). # # # 2) DE: # funcao(Tracos):nomefuncao-> # funcao1(Tracos1), # funcao2(Tracos2), # funcao3(Tracos3), # funcao4(Tracos4), # funcao5(Tracos5). # # PARA: # funcao(S1,S,INF,SUP,d,A,Tracos):- # funcao1(S1,S2,INF,SUP,d,A1,Tracos1), # funcao2(S2,S3,S2,SUP,d,A2,Tracos2), # funcao3(S3,S4,S3,SUP,d,A3,Tracos3), # funcao4(S4,S5,S4,SUP,d,A4,Tracos4), # funcao5(S5,S,S5,SUP,d,A5,Tracos5), # monta_arv(A,nomefuncao,[A1,A2,A3,A4,A5]). # # funcao(S1,S,INF,SUP,e,A,Tracos):- # funcao5(S5,S,INF,SUP,e,A5,Tracos5), # funcao4(S4,S5,INF,S5,e,A4,Tracos4), # funcao3(S3,S4,INF,S4,e,A3,Tracos3), # funcao2(S2,S3,INF,S3,e,A2,Tracos2), # funcao1(S1,S2,INF,S2,e,A1,Tracos1), # monta_arv(A,nomefuncao,[A1,A2,A3,A4,A5]). # # # 3)A) DE: # e_funcao(Tracos):nomefuncao->. # # PARA: # e_funcao(S,S,_,_,_,nomefuncao,Tracos). # # # 3)B) DE: # e_funcao(Tracos)->. # # PARA: # e_funcao(S,S,_,_,_,'',Tracos). # # # 3)C) DE: # e_funcao:nomefuncao->. # # PARA: # e_funcao(S,S,_,_,_,nomefuncao). # # # 3)D) DE: # e_funcao->. # # PARA: # e_funcao(S,S,_,_,_,''). # # # 4)A) DE: # =subst(PAL,CAN,G,N). # # PARA: # subst(S1,S,INF,SUP,_,A,PAL,CAN,G,N):- # x_subst(S1,S,PAL,CAN,G,N), # INF =< S1, # SUP >= S, # monta_arv(A,subst,[PAL]). # # x_subst(0,0,_,_,_,_). # # 4)B) DE: # =subst(PAL,CAN,G,N):substantivo. # # PARA: # subst(S1,S,INF,SUP,_,A,PAL,CAN,G,N):- # x_subst(S1,S,PAL,CAN,G,N), # INF =< S1, # SUP >= S, # monta_arv(A,substantivo,[PAL]). # # x_subst(0,0,_,_,_,_). # # # VINDO DO PRE-ANALISADOR: # x_subst(2,3,meninas,menino,fem,pl). # # # # BEGIN { nomefunc = "[a-z][a-z0-9_]*" nomevar = "[A-Z][A-Za-z0-9_]*" varsemnome = "[_]" variavel = "(" nomevar "|" varsemnome ")" string = "[a-z][a-z0-9_]*" stringaspas = "['][^']*[']" inteiro = "[0-9]+" valor = "(" string "|" stringaspas "|" inteiro ")" param = "(" variavel "|" valor ")" listaparam = "([(]" param "([,]" param ")*[)])?" listaparamlex = "[(]PAL([,]" param ")*[)]" declfunccab = "^" nomefunc listaparam "([:](" nomefunc "|[.]))?[-][>]$" declfuncvaz = "^[e][_]" nomefunc listaparam "([:]" nomefunc ")?[-][>][.]$" linhafunc = "^[*]?" nomefunc listaparam "[,]$" ultlinhafunc = "^[*]?" nomefunc listaparam "[.]$" declfunclex = "^[=]" nomefunc listaparamlex "([:]" nomefunc ")?[.]$" # linhaspred: # -1 - predicados completos / nao iniciados # 0 - cabecalho de predicado declarado, nenhuma linha de chamada # >0 - numero de linhas de chamadas do predicado, predicado ainda nao finalizado linhaspred = -1 # nenhum predicado iniciado } //{ remove_comments(); } // { gsub(/[ \t]+/," ") gsub(/^[ ]/,"") gsub(/[ ]$/,"") $0 = gensub(/([*=,():->.])[ ]/, "\\1", "g") $0 = gensub(/[ ]([*=,():->.])/, "\\1", "g") } /^$/ { next; } /^[ \t]*[#]/ { next; } ($0 ~ declfunccab) { # declaracao do cabecalho de um predicado - 2) if (linhaspred != -1) {erro(("predicado anterior nao finalizado")) next } linhaspred = 0 # cabecalho de predicado declarado asterisco = 0 # nenhum asterisco ainda encontrado decl = $0 # guarda a declaracao next } ($0 ~ declfuncvaz) { # declaracao de um predicado vazio - 3) if (linhaspred != -1) {erro(("predicado anterior nao finalizado")) next } decl = $0 nomefuncao = "''" # nome de funcao sera '' if (match(decl,"[:]" nomefunc "[-][>][.]$")) # se ha nome de funcao explicito nomefuncao = substr(decl,RSTART+1,RLENGTH-4) # guarda o nome da funcao gsub("[:]" nomefunc "[-][>][.]$", ".", decl) # a declaracao assume forma sem nome de funcao - 3)B) ou 3)D) sem -> if (!gsub("[(]", "(,", decl)) # insere virgula antes dos Tracos - 3)B) ou gsub("[.]$", "().", decl) # insere () antes do . - 3)D) gsub("[(]", "(S,S,_,_,_," nomefuncao, decl) # insere os 6 parametros necessarios printf("%s\n\n", decl) next } ($0 ~ declfunclex) { # declaracao de um terminal lexico - 4) if (linhaspred != -1) {erro(("predicado anterior nao finalizado")) next } decl = $0 nomefuncao = substr(decl, 2, index(decl,"(")-2) # guarda o nome da funcao if (match(decl,"[:]" nomefunc "[.]$")) # se ha nome de funcao explicito nomefuncao = substr(decl,RSTART+1,RLENGTH-2) # guarda o nome explicito da funcao gsub("[:]" nomefunc "[.]$", ".", decl) # a declaracao assume forma sem nome de funcao - 4)A) gsub("^[=]", "", decl) # retira o simbolo = do inicio gsub("[.]$", "", decl) # retira o . do final primlinha = decl # faz copia para primeira linha do corpo decldefault = decl # faz copia para declaracao default do lexico gsub("[(]", "(S1,S,INF,SUP,_,A", decl) # insere os 6 parametros necessarios no cabecalho gsub("[(]", "(S1,S,", primlinha) # insere S1 e S necessarios na chamada para lexico sub(nomevar, "_", decldefault) # gera a declaracao default de lexico sem as 2 posicoes gsub("[(]", "(0,0,", decldefault) # adiciona os 2 parametros de posicoes inicio e fim printf("%s:-\n", decl) # adiciona :- ao final do cabecalho e imprime printf("\tx_%s,\n", primlinha) # adiciona tab x_ no inicio e , ao final da chamada para lexico printf("\tINF =< S1,\n") printf("\tSUP >= S,\n") printf("\tmonta_arv(A,%s,[PAL]).\n\n", nomefuncao) printf("x_%s.\n\n", decldefault) next } ($0 ~ linhafunc) { if (linhaspred == -1) {erro(("predicado sem declaracao")) next } linha = $0 linhaspred += 1 # atualiza numero de linhas do predicado if (gsub("^[*]", "", linha)) # retira o simbolo * do inicio asterisco = linhaspred # guarda a linha atual que possui asterisco if (!gsub("[(]", "(,", linha)) # insere virgula antes dos Tracos gsub("[,]$", "(),", linha) # insere () antes da , final linhas[linhaspred] = linha next } ($0 ~ ultlinhafunc) { if (linhaspred == -1) {erro(("predicado sem declaracao")) next } linha = $0 linhaspred += 1 # atualiza numero de linhas do predicado if (gsub("^[*]", "", linha)) # retira o simbolo * do inicio asterisco = linhaspred # guarda a linha atual que possui asterisco if (!gsub("[(]", "(,", linha)) # insere virgula antes dos Tracos gsub("[.]$", "(),", linha) # insere () antes do . final trocando-o por , linhas[linhaspred] = linha nomefuncao = "''" # nome de funcao sera '' if (match(decl,"([:]" nomefunc "|[.])[-][>]$")) # se ha nome de funcao explicito nomefuncao = substr(decl,RSTART+1,RLENGTH-3) # guarda o nome da funcao gsub("([:]" nomefunc "|[.])[-][>]$", ":-", decl) # a declaracao assume forma sem nome de funcao - 1)C) ou 1)D) if (!gsub("[(]", "(,", decl)) # insere virgula antes dos Tracos - 1)C) ou gsub("[:][-]$", "():-", decl) # insere () antes do :- transformando 1)D) em 1)C) if (nomefuncao == "''") nomefuncao = substr(decl,2,index(decl,"(")) # guarda o nome da funcao se nao explicito listaarv = "A1" for (i=2; i<=linhaspred; i++) listaarv = listaarv ",A" i listaarv = "monta_arv(A," nomefuncao ",[" listaarv "])" if (asterisco) { gsub("[(]", "(S1,S,INF,SUP,_,A", decl) # insere os 6 parametros necessarios no cabecalho printf("%s\n",decl) x1 = asterisco "" x2 = (asterisco + 1) "" if (asterisco == linhaspred) x2 = "" gsub("[(]", "(S" x1 ",S" x2 ",INF,SUP,d,A" x1, linhas[asterisco]) printf("\t%s\n", linhas[asterisco]) for (i=asterisco-1; i>=1; i--) { x1 = i "" x2 = (i + 1) "" gsub("[(]", "(S" x1 ",S" x2 ",INF,S" x2 ",e,A" x1, linhas[i]) printf("\t%s\n", linhas[i]) } for (i=asterisco+1; i<=linhaspred; i++) { x1 = i "" x2 = (i + 1) "" if (i == linhaspred) x2 = "" gsub("[(]", "(S" x1 ",S" x2 ",S" x1 ",SUP,d,A" x1, linhas[i]) printf("\t%s\n", linhas[i]) } printf("\t%s\n\n", listaarv) } else { declatual = decl gsub("[(]", "(S1,S,INF,SUP,d,A", declatual) # insere os 6 parametros necessarios no cabecalho printf("%s\n",declatual) x1 = "1" x2 = "2" if (linhaspred == 1) x2 = "" linhaatual = linhas[1] gsub("[(]", "(S" x1 ",S" x2 ",INF,SUP,d,A" x1, linhaatual) printf("\t%s\n", linhaatual) for (i=2; i<=linhaspred; i++) { x1 = i "" x2 = (i + 1) "" if (i == linhaspred) x2 = "" linhaatual = linhas[i] gsub("[(]", "(S" x1 ",S" x2 ",S" x1 ",SUP,d,A" x1, linhaatual) printf("\t%s\n", linhaatual) } printf("\t%s\n\n", listaarv) declatual = decl gsub("[(]", "(S1,S,INF,SUP,e,A", declatual) # insere os 6 parametros necessarios no cabecalho printf("%s\n",declatual) x1 = linhaspred linhaatual = linhas[linhaspred] gsub("[(]", "(S" x1 ",S,INF,SUP,e,A" x1, linhaatual) printf("\t%s\n", linhaatual) for (i=linhaspred-1; i>=1; i--) { x1 = i "" x2 = (i + 1) "" linhaatual = linhas[i] gsub("[(]", "(S" x1 ",S" x2 ",INF,S" x2 ",e,A" x1, linhaatual) printf("\t%s\n", linhaatual) } printf("\t%s\n\n", listaarv) } linhaspred = -1 asterisco = 0 for (i in linhas) delete linhas[i] next } // {erro(("nao reconhecivel"))} function erro(msg) { printf "linha %d - %s: %s\n", NR, msg, $0 > "/dev/stderr"; } function remove_comments( lin,res) { lin = $0; res = ""; while (lin != "") { if (inside_comment) { if (match(lin, /[*][/]/)) { lin = substr(lin, RSTART+RLENGTH); inside_comment = 0 } else { lin = ""; } } else { if (match(lin, /[/][*]/)) { res = (res substr(lin, 1, RSTART-1)); lin = substr(lin, RSTART + RLENGTH); inside_comment = 1 } else { res = (res lin); lin = ""; } } } $0 = res; }