Post on 18-Apr-2015
DEFINIÇÃO DE TIPOS – LF3
PLP – Apresentação 2
Equipe
Felype Santiago Maria Carolina Paola Rodrigues Rodrigo Cardoso
Agenda
Descrição do projeto Gramática Decisões de projeto Implementação Parser Considerações finais
Contextualização do problema
Descrição do Projeto
Objetivo
Estender a Linguagem Funcional 3 com aspectos de Haskell
Permitir definição de tipos pelo programador Tipos enumerados Tipos recursivos Tipos complexos
Tipos Enumerados
Tipo definido por uma quantidade finita de construtores.
Em Haskell:data Bool = True | Falsedata Estacao = Inverno | Verao | Outono | Primaveradata Temp = Frio | Quente
Tipos Recursivos
Tipo definido através do uso da própria definição.
Em Haskell:data Tree a = Leaf a
| Branch (Tree a) (Tree a)
Branch :: Tree a -> Tree a -> Tree aLeaf :: a -> Tree a
Tipos Complexos
Tipo definido através do uso de outras definições.
Em Haskell:type String = [Char]
type Name = String
type Address = None | Addr String
type Person = (Name, Address)
Alteração na BNF
Gramática
Alteração na BNF
ValorAbstrato ::= ValorFuncao | ValorTipo DeclaracaoFuncional ::= DecVariavel
| DecFuncao| DecTipo| DeclaracaoFuncional ","
DeclaracaoFuncional DecTipo ::= "type" Id "=" "{"
SeqConstrutores "}"
Alteração na BNF
SeqConstrutores ::= Construtor | Construtor "|" SeqConstrutores
Contrutor ::= Id | Id "(" ListaTipos ")" ListaTipos ::= TiposAceitos
| TiposAceitos "," ListaTipos TiposAceitos ::= "String" | "Boolean"
| "Int" | Id
Características da Linguagem
Decisões de projeto
Decisões de projeto
Tipos enumerados são tratados como construtores vazios.
Os nomes dos construtores não podem ser nenhuma palavra reservada da linguagem Ex: false, true, length, var, type...
Não são permitidas redefinições de construtores Nomes dos construtores são tratados como
palavra reservada em qualquer escopo Não podem ser utilizados como nomes de
variáveis, funções ou qualquer outro construtor
Decisões de projeto
Os tipos são declarados sequencialmente Evitar abertura de escopos desnecessários
Para declarar os construtores, é necessário determinar os tipos dos parâmetros aceitos Tipos primitivos (String, Boolean e Int) Qualquer tipo declarado pelo programador,
inclusive o próprio tipo sendo declarado ValorTipo herda de ValorAbstrato
Alteração na BNF
Implementação
Funcionamento das pilhas
let type dias = {dom | seg | ter | qua | qui | sex | sab}, var x = 1 in let type listaDias = {null | obj(dias) | lista(listaDias, listaDias)} in lista(lista(lista(obj(seg), obj(ter)), obj(qua)), null)
Pilha de compilação e execução
let type dias = {dom | seg | ter | qua | qui | sex | sab}, var x = 1 in let type listaDias = {null | obj(dias) | lista(listaDias, listaDias)} in lista(lista(lista(obj(seg), obj(ter)), obj(qua)), null)
Variáveis e funções
Tipos
let type dias = {dom | seg | ter | qua | qui | sex | sab}, var x = 1 in let type listaDias = {null | obj(dias) | lista(listaDias, listaDias)} in lista(lista(lista(obj(seg), obj(ter)), obj(qua)), null)
let type dias = {dom | seg | ter | qua | qui | sex | sab}, var x = 1 in let type listaDias = {null | obj(dias) | lista(listaDias, listaDias)} in lista(lista(lista(obj(seg), obj(ter)), obj(qua)), null)
<(dom, ConstEnum), (seg, ConstEnum),
(ter, ConstEnum), (qua, ConstEnum),
(qui, ConstEnum), (sex, ConstEnum),
(sab, ConstEnum)>DefType
<dias, DefType(<(dom, ConstEnum), (seg, ConstEnum),
(ter, ConstEnum), (qua, ConstEnum), (qui,
ConstEnum), (sex, ConstEnum), (sab,
ConstEnum)>)>
let type dias = {dom | seg | ter | qua | qui | sex | sab}, var x = 1 in let type listaDias = {null | obj(dias) | lista(listaDias, listaDias)} in lista(lista(lista(obj(seg), obj(ter)), obj(qua)), null)
let type dias = {dom | seg | ter | qua | qui | sex | sab}, var x = 1 in let type listaDias = {null | obj(dias) | lista(listaDias, listaDias)} in lista(lista(lista(obj(seg), obj(ter)), obj(qua)), null)
<x, TipoInteiro/ValorInt(1)>
let type dias = {dom | seg | ter | qua | qui | sex | sab}, var x = 1 in let type listaDias = {null | obj(dias) | lista(listaDias, listaDias)} in lista(lista(lista(obj(seg), obj(ter)), obj(qua)), null)
Pilha de compilação e execução
let type dias = {dom | seg | ter | qua | qui | sex | sab}, var x = 1 in let type listaDias = {null | obj(dias) | lista(listaDias, listaDias)} in lista(lista(lista(obj(seg), obj(ter)), obj(qua)), null)
<dias, DefType(<(dom, ConstEnum), (seg, ConstEnum),
(ter, ConstEnum), (qua, ConstEnum), (qui,
ConstEnum), (sex, ConstEnum), (sab,
ConstEnum)>)>
<x, TipoInteiro/ValorInt(1)
>
<(null, ConstEnum), (obj, ConstTipoRecursivo(dias)),
(lista, ConstTipoRecursivo(listaDias, listaDias))>
DefType
<listaDias, DefType(<(null, ConstEnum),
(obj, ConstTipoRecursivo(dias)), (lista, ConstTipoRecursivo(listaDias,
listaDias))>)>
let type dias = {dom | seg | ter | qua | qui | sex | sab}, var x = 1 in let type listaDias = {null | obj(dias) | lista(listaDias, listaDias)} in lista(lista(lista(obj(seg), obj(ter)), obj(qua)), null)
let type dias = {dom | seg | ter | qua | qui | sex | sab}, var x = 1 in let type listaDias = {null | obj(dias) | lista(listaDias, listaDias)} in lista(lista(lista(obj(seg), obj(ter)), obj(qua)), null)
let type dias = {dom | seg | ter | qua | qui | sex | sab}, var x = 1 in let type listaDias = {null | obj(dias) | lista(listaDias, listaDias)} in lista(lista(lista(obj(seg), obj(ter)), obj(qua)), null)
Variáveis e funções Tipos
Pilha de compilação e execução
let type dias = {dom | seg | ter | qua | qui | sex | sab}, var x = 1 in let type listaDias = {null | obj(dias) | lista(listaDias, listaDias)} in lista(lista(lista(obj(seg), obj(ter)), obj(qua)), null)
Variáveis e funções Tipos
<dias, DefType(<(dom, ConstEnum), (seg, ConstEnum),
(ter, ConstEnum), (qua, ConstEnum), (qui,
ConstEnum), (sex, ConstEnum), (sab,
ConstEnum)>)>
<x, TipoInteiro>
<listaDias, DefType(<(null, ConstEnum),
(obj, ConstTipoRecursivo(dias)), (lista, ConstTipoRecursivo(listaDias,
listaDias))>)>
Diagrama UML - Contexto
Diagrama UML - Tipos novos
Implementação - Modificações
Classes/Interfaces AmbienteFuncional<T, K>
AmbienteExecucaoFuncional ContextoExecucaoFuncional
AmbienteCompilacaoFuncional (NOVO) ContextoCompilacaoFuncional (NOVO)
Aplicação Modificações em métodos
ExpDeclaracao - Mapeamento de estruturas avaliar, includeBindings, resolveBindings,
resolveTypeBidings...
Alteração na BNF
Parser
Parser - PDeclType()
DeclaracaoFuncional PDeclType() :{
Id tipo;SeqConstrutor seqConstrutor;
}{
( <TYPE> tipo = PId() <ASSIGN> <LBRACE> seqConstrutor = PSeqConstrutor(tipo.toString()) <RBRACE>){
return new DecType(tipo, seqConstrutor);}
}
Parser - PSeqConstrutorSeqConstrutor PSeqConstrutor(String tipo) :{
Construtor construtor;List lista = null;int index = 0;
}{( construtor = PConstrutor(tipo, index++))
{ lista = new ArrayList(); lista.add(construtor);
}( (<BIT_OR> construtor = PConstrutor(tipo, index++)) {lista.add(construtor);}) *{ return new SeqConstrutor(lista); }
Parser - PConstrutor
Construtor PConstrutor(String tipo, int index):{Construtor construtor;}{((
LOOKAHEAD(<IDENTIFIER> <LPAREN>) construtor = PConstrutorTipoRecursivo(tipo)| LOOKAHEAD(<IDENTIFIER>) construtor = PConstrutorEnum(tipo, index) )){ return construtor; }
}
Exemplo de programas, conclusões e referências
Para finalizar...
Exemplos de programas Ao vivo é melhor! =D
Conclusões
Aumentou o poder de expressão da linguagem
Implementação única para tipos enumerados e recursivos.
Trabalhos futuros: Otimizar as heranças Funções nativas (NEXT, PREVIOUS e ORD)
Referências
Programming Language Concepts and Paradigms - David A. Watt
Programming language processors in Java - David A. Watt e Deryck F. Brown
http://www.cin.ufpe.br/~if708 http://www.haskell.org/tutorial/goodies.ht
ml
Dúvidas... Sugestões...
DEFINIÇÃO DE TIPOS – LF3
PLP – Apresentação 2