Ações semanticas ZooaZ

Propaganda
Ações semânticas para gramática ZooAZ – Compiladores 2004-2 (De Lucca)
AÇÃO [0]
Antes de tudo, a parte semântica deve ser inicializada. Abaixo, a lista de elementos
necessários para a execução das ações semânticas.
Inicializar variáveis auxiliares e contadores

tipo: valores possívels: int/bool/caracter/flut/nada

categoria: var.simples/vetor/procedimento/função/constante/parâmetro/nomeprograma

deslocamento: controla a posição da declaração de cada identificador. Cada variável
simples incrementará o deslocamento de 1

deslocString: controla a posição da declaração de strings. Cada string incrementará o
deslocString de 1. O deslocString fará papel de apontador na tabela de Strings

contaParâmetros: contador de parâmetros declarados

escopo: controla o escopo de declaração dos identificadores

geradoRET: controla se foi ou não gerada a instrução RET em uma função




TS: tabela de símbolos ou de identificadores.
Tabela de Strings: vetor que conterá todos os strings do programa, sequencialmente,
indexados pelo deslocString.
Área de geração de código: pode-se imaginar um vetor de triplas (Operador,
operando1, operando2), indexado sequencialmente e controlado por um IG – índice de
geração). Sempre que se gera uma instrução, o IG é incrementado.
diversas pilhas para solução de referências futuras

pilhas de desvios para Principal

pilha de solução de enquanto (pilhaEnquanto)

pilha de solução de para (pilhaPara)

pilha de solução de faça-enquanto (pilhaFaça)

pilhas de solução de se-senão (pilhaSE)

outras que se fizerem necessárias

pilhaOP: pilha de apoio à geração de código de operações aritméticas e lógicas
[1] <ZooA> ::= #0 <import> programa ID #1 "{" <corpo> "}" #2 ;
 Incluir ID na TS com atributos adequados (categoria=nome programa, escopo=0)
 Gerar AMEM 0,3
[2] <ZooA> ::= #0 <import> programa ID #1 "{" <corpo> "}" #2 ;
 Verificar se há pendências nas pilhas (-> ERRO1)
[3] <import> ::= importar ID #3 ";" <import>
OBS: Não será feita importação de arquivos neste semestre
<tipo> ::= int #7 | bool #8 | caracter #9 | flutuante
<tiponada> ::= <tipo> | nada #11 ;
[7]tipo = int
[8]tipo = bool
[9]tipo = caracter
[10]tipo = flutuante
[11]tipo = nada
#10
;
[12] <declara> ::= <tiponada> ID #12 <declrotvar>
1Sempre
que ocorrer um ERRO, deve ser cancelada a geração de código. A análise pode continuar, mas
qualquer que seja o código gerado não deverá ser considerado correto.
7
se existe ID na TS no mesmo escopo
então ERRO(“Já declarado”)
senão
 monta tupla provisória para incluir na TS (ainda não sabe se categoria é variável ou
sub-rotina ou vetor) – dados disponíveis: ID, escopo, tipo e modo
[13] <declrotvar> ::= #13 ';' (é declaração de variável)
se tipo =int ou caracter ou bool
 gera instrução AMEM (0,1)
 inclui a tupla provisória na TS completando categoria=”variável simples”, sem
inicialização, deslocamento
 deslocamento++
senão
 se tipo =flutuante
 NÃO FAZ NADA – Flutuante excluído da linguagem neste semestre
 senão o tipo será nada: ERRO("'Nada' não permitido em declaração de variável")
[14] <declrotvar> ::= #14 '=' <inicial> #15 ';'
 idem ação #13 mas com inicialização: Guardar a posição utilizada da TS em uma
variável temporária para posteriormente a #15 possa colocar o valor da inicialização
[15] <declrotvar> ::= #14 '=' <inicial> #15 ';'
 Atualizar a entrada da TS (posição salva na #14) com o valor da inicialização
 Gerar CRCT (0, valor da inicialização)
 Gerar ARMZ (0, deslocamento), utilizando o deslocamento da variável da entrada da
TS salva em #14
<inicial> ::= cteint #16 | cteflut #17 | litcar #18
[16] se tipo <> int : ERRO(Tipos incompatíveis)
senão salva valor da cteint em variável temporária para usar em #15, em #28 ou em #41
[17] FLUTUANTE retirado da linguagem neste semestre. Gerar ERRO ("Flutuante não
suportado").
[18] idem #16 para caracter
[19] <inicial>::= ID #19 ;
se ID existe na TS e é o nome de uma constante
salva valor da constante (recuperar da TS) em variável temporária para usar em
#15, #28 ou em #41
senão
ERRO: Constante não declarada ou identificador não declarado como constante
[21] <declrotvar> ::= #21 '[' cteint #22 ']' ';'
OBS: VETOR RETIRADO DA LINGUAGEM - Não fazer testes com vetores.
[22] <declrotvar> ::= #21 '[' cteint #22 ']' ';'
[23]<declrotvar> ::= #23 '(' <listaargs> #24 ')' #51 <bloco> #52
 se tipo==nada
 categoria = procedimento
 se tipo== int ou caracter ou bool
 categoria = função
 Gerar DSVS -,? , empilhando o endereço onde foi gerada a instrução (IG) para resolver
ao final da sub-rotina (use a pilha de desvios para Principal)
 incluir tupla provisória (criada em #12) na TS, completando categoria (definida acima) e
7




endereço (posição do início de geração de código da sub-rotina = IG seguinte ao DSVS
gerado)
escopo++
contaParametros = 0
guardar posição onde a tupla foi incluída na TS para retornar e colocar o nº de
parâmetros (será feito em #24)
geradoRET = falso (será verificado, no final do bloco, se foi gerado o return)
[24]<declrotvar> ::= #23 '(' <listaargs> #24 ')' #51 <bloco>
 atualizar entrada na TS correspondente à subrotina, com o nº de parâmetros
 atualizar entradas dos parâmetros com deslocamentos negativos
 exemplo: nada xyz ( int a, bool b, int c)
 deslocamento de a = -3
 deslocamento de b = -2
 deslocamento de c = -1
#52
[25] <listaargs> ::= <tipo> ID #25 <repargs>
 se tipo == nada ou flutuante: ERRO(Tipos não admitidos como parâmetros)
 senão
 se a ID já existe na TS no mesmo escopo: ERRO(Já declarado)
 senão
 inserir na TS: ID, tipo, escopo, categoria=parâmetro
 contaParâmetros++
[26] <declara> ::=
 categoria = constante
final #26 <tipo> ID #27 '=' <inicial> #28 ';'
[27] <declara> ::= final #26 <tipo> ID #27 '=' <inicial> #28 ';'
 se tipo == nada ou flutuante: ERRO(Tipo inválido)
 senão
 se a ID já existe na TS no mesmo escopo: ERRO(Já declarado)
 senão inserir na TS: ID, tipo, modo, escopo, categoria
[28] <declara> ::= final #26 <tipo> ID #27 '=' <inicial> #28 ';'
 atualizar última entrada da TS (constante) com valor da inicialização (variável
temporária definida em #16, #17, #18, #19)
[29] <declara> ::= string ID #29 '=' litstring #30 ';'
 se a ID já existe na TS no mesmo escopo: ERRO(Já declarado)
 senão incluir na TS: ID, modo, escopo, categoria=string, tipo=string, deslocString
[30] <declara> ::= string ID #29 '=' litstring #30 ';'
 incluir litstring na Tab de strings, na posição definida por deslocString
 deslocString++
[31] <corpo> ::= principal '(' ')' #31 <bloco> #53 <corpo>
 incluir na TS: ID='Principal', tipo=nada, categoria=procedimento, escopo=0, nºparam=0
e endereço de geração de código correspondente ao início da função 'Principal' (IG
atual)
 resolver desvios pendentes gerados em #23 (pilha de desvios para Principal), usando o
endereço de geração de código que corresponderá ao início da função 'Principal'.
Comando SE
[32] <cmdse> ::= se '(' <cond> ')' #32 <bloco> <cmdse2> #34
 Empilhar IG na pilhaSE (onde o DSVF abaixo será gerado)
7

Gerar DSVF -,? (com endereço de destino pendente que será resolvido em #33 ou #34)
[33] <cmdse2> ::= #33 senão <bloco>
 Gerar DSVS -,? (com endereço de destino pendente que será resolvido em #34)
 Resolver referência pendente do topo da pilhaIF, usando IG atual e desempilhar
 Empilhar IG-1 (referente ao DSVS gerado acima) na pilhaIF
[34] <cmdse> ::= se '(' <cond> ')' #32 <bloco> <cmdse2> #34
 Resolver referência pendente (cujo endereço está no topo da pilhaIF) usando IG e
desempilhar (pode ter sido empilhado em #32 ou em #33)
Comando FAÇA:
[35] <cmdfaca> ::= #35 faça <bloco> enquanto '(' <cond> ')' #36
 Empilhar IG na pilhaFaça
[36] <cmdfaca> ::= #35 faça <bloco> enquanto '(' <cond> ')' #36
 Gerar (DSVT -,end) usando o topo da pilhaEnquanto como endereço e desempilhar
Comando ENQUANTO:
[37] <cmdeqto> ::= #37 enquanto '(' <cond> #38 ')' <bloco>
 Empilhar IG na pilhaEnquanto
[38] <cmdeqto> ::= #37 enquanto '(' <cond> #38 ')' <bloco>
 Empilhar IG na pilhaEnquanto (endereço onde o DSVF abaixo será gerado)
 Gerar DSVF -,? (endereço ficará pendente para resolução futura)
#39
#39
[39] <cmdeqto> ::= #37 enquanto '(' <cond> #38 ')' <bloco> #39
 Resolver referência pendente do topo da pilhaEnquanto usando IG+1 e desempilhar
 Gerar (DSVS -,end) usando o novo topo da pilhaEnquanto como endereço
Comando FOR:
[40] <cmdpara> ::= para "(" ID #40 "=" <inicial> #41 ";" <cond>
#42 ";" #43 <expr> #44 ")" <bloco> #45 ;
As ações para o COMANDO PARA deverão ser definidas e implementadas pelo grupo.
As posições de ações definidas acima são sugestões de uma possível solução.
[46] <cmdatrib> ::= ID #46 <contatrib>
Se ID não está na TS:
 ERRO(Não declarado: Não se pode chamar PROCEDIMENTO que não tenha sido
declarado anteriormente)
senão
 Se ID está na TS como função/nome de prog/const: ERRO(deve ser variável,
parâmetro ou procedimento)
 senão Salvar, em tupla temporária, os dados da TabSimb correspondentes ao ID
[47] <contatrib> ::= '=' <cond> #47
 Gerar (ARMZ base, desloc) usando informações da tupla temporária salva em #46
[48] <contatrib> ::= '(' #48 <listaparam> #49 ')'
 Se ID não é procedimento (ver dados da tupla temporária): ERRO(Esperava-se
procedimento)
 senão Zerar contaParam
[49] <contatrib> ::= '(' #48 <listaparam> #49 ')'
 Se contaParam <> nº parâmetros da tupla temporária salva em [46] ERRO(Nº de
7

parâmetros incorreto)
senão Gerar (CALL base, end) usando informações da tupla temporária salva em #46
 base = escopo atual – escopo de declaração da sub-rotina (ver tupla)
 end = endereço do procedimento (ver tupla)
[50] <listaparam> ::= <expr> #50 <rlista>
<rlista> ::= <expr> #50 <rlista>
 Incrementar contaParam
[51] <declrotvar> ::= #23 '(' <listaargs> #24 ')' #51 <bloco>
#52
 Gerar AMEM 0,3 <<reservando espaço para o registro de ativação
[52] <declrotvar> ::= #23 '(' <listaargs> #24 ')' #51 <bloco>
#52
 Decrementar escopo
 Se categoria é função e se variável geradoRET=false: ERRO(falta return)
 Se categoria é procedimento, gerar RET -,n (n é o nº de parâmetros do procedimento)
 Resolver DSVS gerado em #23 (endereço guardado na pilha de desvios para
Principal), usando o IG atual
[53] <corpo> ::= principal '(' ')' #31 <bloco> #53 <corpo>
 Verificar se há pendências em aberto nas diversas pilhas. Se houver, gerar o erro
equivalente.
 Senão Gerar PARA -,[54] <clauresult> ::= resultado <cond> #54
Se categoria não é função:
 ERRO(Não é função)
senão
 Gerar ARMZ n,0
 n é o escopo atual -> isto fará com que o valor de retorno seja copiado para
a posição mais baixa da pilha de execução (qdo o código for executado)
 Gerar RET -,K (K é o nº de parâmetros do procedimento – ver TabSimb)
 Fazer geradoRET = true
[57] <clausula> ::= '!' <valor> #57
 Gerar NEGA -,[58] <cond2> ::= '&&' <clausula> #58 <cond2>
 Gerar CONJ -,[59] <cond2> ::= '||' <clausula> #59 <cond2>
 Gerar DISJ -,[60] <oprel> ::= '>' #60 | '<' #61 | '>=' #62 | '<=' #63 |
'==' #64 | '!=' #65
Empilhar "maior" na pilhaOP
[61]
Empilhar "menor" na pilhaOP
[62]
Empilhar "maior-igual" na pilhaOP
[63]
Empilhar "menor-igual" na pilhaOP
[64]
7
Empilhar "igual" na pilhaOP
[65]
Empilhar "dif" na pilhaOP
[66] <valor> ::= <expr> <oprel> <expr> #66
 Gerar instrução de comparação correspondente à operação do topo da pilhaOP e
desempilhar
 se topo="maior" – Gerar CMMA -, se topo="igual" – Gerar CMIG -,etc
[67] <optermo> ::= '+' #67 | '-' #68
 Empilhar "soma" na pilhaOP
[68]
 Empilhar "subt" na pilhaOP
[69] <expr2> ::= <optermo> <termo> #69 <expr2>
 Gerar instrução aritmética conforme topo da pilhaOP e desempilhar
 se topo="soma" – Gerar SOMA -, se topo="subt" – Gerar SUB -,[70] <opfator> ::= '*' #70 | '/' #71 | '%' #72
Empilhar "mult" na pilhaOP
[71]
Empilhar "div" na pilhaOP
[72]
Empilhar "rest" na pilhaOP
[73] <termo2> ::= <opfator> <fator> #73 <termo2>
 Gerar instrução arimética conforme topo da pilhaOP e desempilhar
 se topo="mult" – Gerar MULT -, se topo="div" – Gerar DIV -, se topo="rest" – Gerar MOD -,[74] <fator> ::= '-' <fator> #74
 Gerar MUNARIO -,[75] <litnum> ::= cteint #75
 Gerar CRCT -,cteint
 Fazer tipo="int"
[76] <litnum> ::= cteflutuante #76
 Flutuante retirado da linguagem neste semestre. Só faz: tipo="flutuante"
[77] <fator> ::= litcar #77
 Gerar CRCT -,código(litcar) (usar o código ASCII ou Unicode do caracter)
 Fazer tipo="caracter"
[78] <fator> ::= litstring #78
 Armazenar "litstring" na Tabela de Strings (deslocString++)
 Gerar CRCT -,deslocString (posição da TabString onde o litstring foi armazenado)
 Fazer tipo="string"
[79] <fator> ::= ID #79 <contid>
OBS: Não se pode chamar FUNÇÃO NÃO pré-declarada
 Se ID está na TS e não for variável, vetor, função ou cte: ERRO(uso indevido)
7

senão Salvar dados do ID em uma tupla temporária para usar em #80/81
[80] <contid> ::= @ #80
 Se ID é constante
 Gerar CRCT -,x (x é o valor pré-declarado – está na tupla temporária)
 Fazer tipo="int"
 senão
 se ID é var.string
 Gerar CRCT -,deslocString (está na tupla temporária)
 Fazer tipo="string"
 se ID é outro tipo de variável ou parâmetro
 Gerar CRVL base, desloc (ver tupla temporária)
 Fazer tipo=(ver tipo definido na tupla temporária)
 senão ERRO(Esperava-se variável, parâmetro ou constante)
[81] <contid> ::= #81 '(' <listaparam> #82 ')'
 Se ID (ver tupla temporária) não é função: ERRO(Esperava-se função)
 Senão
 Zerar contaParam
 Fazer tipo=(ver tipo definido na tupla temporária)
[82] <contid> ::= #81 '(' <listaparam> #82 ')'
 Se contaParam <> nºparametros declarados (ver tupla temporária):
 ERRO(nº parâmetros incorreto)
 Gerar CALL base, end
 Gerar CRVL dif, 0
 dif é o escopo atual: servirá para carregar o resultado da função que está no
fundo da pilha de execução
[83] <fator> ::= ler '(' ')' #83
 Gerar instrução LEIT -,- (deixa o valor lido no topo da pilha – se for lido um caracter,
deve-se utilizar o valor do código correspondente (Unicode ou Ascii))
[84] <cmdsaida> ::= escrever "(" <expr> #84 ")";
 Se tipo da <expr> for "string" (consultar variável "tipo")
 Gerar instrução IMPRLIT _,_ (utilizará o valor do topo da pilha de execução
para acessar a TabStrings e colocar o string na tela)
 Se tipo é "caracter"
 Gerar instrução IMPRCH _,_ (o valor do topo da pilha é um código ASCII
ou Unicode. Deverá ser convertido p/o caracter adequado e depois exibido)
 Se tipo é "booleano"
 Gerar instrução IMPRBL _,_ (o valor do topo da pilha é 0 (false) ou 1 (true).
IMPRBL imprimirá a F ou V, respectivamente)
 Se tipo é "int"
 Gerar instrução IMPR _,_
 Outros: ERRO(Não implementado nesta versão)
7
Download