Document

Propaganda
Ações semânticas para gramática ZooG1 – Compiladores 2006-1 (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: variavel/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 (valor inicial = 3)

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





TI: tabela de identificadores (ou tabela de símbolos)
Tabela de Strings: vetor que conterá todos os strings do programa, sequencialmente,
indexados pelo deslocString.
EG – endereço de geração. EG deve conter o endereço onde será gerada a próxima
instrução. Valor inicial de EG-> 0 (se considerar que a área de geração é um vetor
cujo primeiro elemento tem índice 0). Sempre que se gera uma instrução, o EG é
incrementado
Área de geração de código: pode-se imaginar um vetor de triplas (Operador,
operando1, operando2), indexado sequencialmente e controlado por EG
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] <ZooG> ::= #0 <import> programa ID #1 "{" <corpo> "}" #2 ;
 Incluir ID na TI com atributos adequados (categoria=nome programa, escopo=0)
[2] <ZooG> ::= #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
1
#10
;
Sempre 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
[11] tipo = nada
[12] <declara> ::= <tiponada> ID #12 <declrotvar>
se existe ID na TI no mesmo escopo
então ERRO(“Já declarado”)
senão
 reúne mais informações para incluir na TI (ainda não sabe se categoria é variável ou
função ou vetor) – dados disponíveis: ID, escopo e tipo
[13] <declrotvar> ::= ';' #13 (é declaração de variável)
se tipo =int
 gera instrução AMEM 1
 incluir na TI os dados reunidos em #11, completando categoria=”variável simples” e
end.relativo=deslocamento
 deslocamento++
senão
 se tipo =flutuante ou caracter ou bool
 NÃO FAZ NADA – excluídos 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
[15] <declrotvar> ::= #14 '=' <inicial> #15 ';'
 Gerar PUSHK (valor da inicialização) (o valor da inicialização virá da ação #16)
 Gerar POP 0, deslocamento, utilizando o end.relativo da última variável incluída na TI
(que é igual ao valor atual da variável deslocamento, menos 1)
<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 #17 para caracter
[19] <inicial>::= ID #19 ;
RETIRADA A POSSIBILIDADE DE INICIALIZAÇÂO COM CONSTANTE NESTE
SEMESTRE.
Gerar ERRO(“Constante não suportada neste ponto”)
[21] <declrotvar> ::= '[' #21 cteint #22 ']' ';'
[22] <declrotvar> ::= '[' #21 cteint #22 ']' ';'
OBS: SINTAXE E SEMÂNTICA DE VETOR DEFINIDAS POR VOCÊS. ISTO AQUI É SÓ
UM EXEMPLO...
[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 esta instrução para resolver ao
final da sub-rotina (empilhe na pilha de desvios para Principal)
 incluir na TI os dados reunidos em #12, completando categoria (definida acima) e
7




endereço (posição do início de geração de código da sub-rotina = endereço seguinte
ao DSVS recém-gerado)
escopo++
contaParametros = 0
guardar posição onde a tupla foi incluída na TI para, no futuro, 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> #52
 atualizar entrada na TI correspondente à subrotina (cuja posição foi salva), 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
[25] <listaargs> ::= <tipo> ID #25 <repargs>
 se tipo == nada, bool, caracter ou flutuante: ERRO(Estes tipos não são admitidos como
parâmetros – NESTE SEMESTRE)
 senão
 se a ID já existe na TI no mesmo escopo: ERRO(Já declarado)
 senão
 inserir na TI: ID, categoria=parâmetro, tipo, escopo
 contaParâmetros++
[26] <declara> ::= final #26 <tipo> ID #27 '=' <inicial> #28 ';'
[27] <declara> ::= final #26 <tipo> ID #27 '=' <inicial> #28 ';'
[28] <declara> ::= final #26 <tipo> ID #27 '=' <inicial> #28 ';'
NÃO UTILIZADO NESTE SEMESTRE (não haverá geração de código para constantes)
[29] <declara> ::= string ID #29 '=' litstring #30 ';'
 se a ID já existe na TI no mesmo escopo: ERRO(Já declarado)
 senão incluir na TI: ID, categoria=variável, tipo=string, escopo, 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>
 resolver desvios pendentes gerados em #23 (pilha de desvios para Principal), usando
para isso o endereço que corresponderá à primeira instrução de 'Principal'.
Comando SE
[32] <cmdse> ::= se '(' <cond> ')' #32 <bloco> <cmdse2> #34
 Empilhar EG na pilhaSE (EG é onde o DSVF abaixo será gerado)
 Gerar DSVF ? (o endereço de destino pendente será resolvido em #33 ou #34)
[33] <cmdse2> ::= senão #33 <bloco>
 Gerar DSVS ? (o endereço de destino pendente será resolvido em #34)
 Resolver referência pendente (pendência está situada na posição indicada pelo
endereço que estiver no topo da pilhaIF) usando EG atual. Desempilhar o endereço da
pilhaIF
 Empilhar EG-1 (referente ao DSVS gerado acima) na pilhaIF
7
[34] <cmdse> ::= se '(' <cond> ')' #32 <bloco> <cmdse2> #34
 Resolver referência pendente (cujo endereço está no topo da pilhaIF) usando EG e
desempilhar (pode ter sido empilhado em #32 ou em #33)
Comando FAÇA:
[35] <cmdfaca> ::= faça #35 <bloco> enquanto '(' <cond> ')' #36
 Empilhar EG na pilhaFaça
[36] <cmdfaca> ::= faça #35 <bloco> enquanto '(' <cond> ')' #36
 Gerar (DSVT endereço) usando o valor que estiver no topo da pilhaEnquanto como
endereço e desempilhar
Comando ENQUANTO:
[37] <cmdeqto> ::= enquanto #37 '(' <cond> #38 ')' <bloco> #39
 Empilhar EG na pilhaEnquanto
[38] <cmdeqto> ::= enquanto #37 '(' <cond> #38 ')' <bloco> #39
 Empilhar EG na pilhaEnquanto (endereço onde o DSVF abaixo será gerado)
 Gerar DSVF ? (endereço ficará pendente para resolução futura – na ação #39)
[39] <cmdeqto> ::= enquanto #37 '(' <cond> #38 ')' <bloco> #39
 Resolver referência pendente do topo da pilhaEnquanto usando EG+1 e desempilhar
 Gerar (DSVS endereço), 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 não serão utilizadas neste semestre. As posições de
ações definidas acima são apenas sugestões.
[46] <cmdatrib> ::= ID #46 <contatrib>
Se ID não está na TI:
 ERRO(Não declarado: Não se pode chamar PROCEDIMENTO que não tenha sido
declarado anteriormente)
senão
 Se ID está na TI como função/nome de prog/const: ERRO(deve ser variável, parâmetro
ou procedimento)
 senão Recuperar os dados da TI correspondentes ao ID e salvar em tupla temporária
[47] <contatrib> ::= '=' <cond> #47
 Gerar (POP dif.nível, 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
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>
7
<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)
 Gerar (RET K) (K é o nº de parâmetros do procedimento)
[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(Cláusula 'resultado' só pode ser utilizada dentro de funções)
senão
 Gerar POP 0,0 -> 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)
 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]
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 de pilhaOP="maior" – Gerar CMMA -, se topo de pilhaOP=”menor” - Gerar CMME -, se topo de pilhaOP="igual" – Gerar CMIG -,etc, etc.
[67] <optermo> ::= '+' #67 | '-' #68
7

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 PUSHK cteint
 Fazer tipo="int"
[76] <litnum> ::= cteflutuante #76
 Flutuante retirado da linguagem neste semestre. Só faz: tipo="flutuante"
[77] <fator> ::= litcar #77
DESNECESSÁRIO IMPLEMENTAR NESTE SEMESTRE
 Gerar PUSHK 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 PUSHK 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 TI e não for variável, parametro, função ou cte: ERRO(uso indevido)
 senão Recuperar da TI os dados do ID e salvar em uma tupla temporária para usar em
#80/81
[80] <contid> ::= @ #80
 Se ID é constante (esta opção não terá utilidade neste semestre)
 Gerar PUSHK x (x é o valor pré-declarado – está na tupla temporária)
 Fazer tipo="int"
 senão
 se ID é var.string
 Gerar PUSHK deslocString (está na tupla temporária)
7


 Fazer tipo="string"
se ID é outro tipo de variável ou parâmetro
 Gerar PUSH 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 salva em #79) não é função: ERRO(Esperava-se função)
 Senão
 Zerar contaParam
 Fazer tipo=(ver tipo definido na tupla temporária salva em #79)
[82] <contid> ::= #81 '(' <listaparam> #82 ')'
 Se contaParam <> nºparametros declarados (ver tupla temporária):
 ERRO(nº parâmetros incorreto)
 Gerar CALL base, end
 Gerar PUSH 0, 0 <- 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 Falso ou Verdade, respectivamente)
 Se tipo é "int"
 Gerar instrução IMPR _,_
 Outros: ERRO(Não implementado nesta versão)
7
Download