PLP – Extensão da LI2 Procedimentos de Alta Ordem Emanuella Aleixo ( [email protected]) José Antônio ([email protected]) Juliana Mafra ([email protected]) Marcela Balbino ([email protected]) Prof.: Augusto Sampaio Apresentação • Definição • Alterações na BNF • Alterações no Parser • Simplificações no Ambiente • Classes Criadas • Classes Alteradas • Testes 2/24 Procedimentos de Alta Ordem São procedimentos que podem receber outros procedimentos como parâmetro, pois agora eles passam a possuir o status de valor. { var p = "Procedimento", var a = "Alta Ordem", var n = 10, proc concat (string i, string a, int m) { i := i ++ " de " ++ a; write(i) ; write(m) }, proc pAltaOrdem( int num, [string, string, int] prod) { call prod(p, a, n) }; call pAltaOrdem(n, concat) Ex.: } 3/24 Alterações na BNF Programa ::= Comando Comando ::= Atribuicao | ComandoDeclaracao | While | IfThenElse | IO | Comando ";" Comando | Skip | ChamadaProcedimento Skip ::= Atribuicao ::= IdAbstrato “:=” Expressao IdAbstrato ::= Id | Indexacao Expressao ::= Valor | ExpUnaria | ExpBinaria | IdAbstrato Valor ::= ValorConcreto | ValorAbstrato ValorAbstrato ::= ValorProcedimento ValorProcedimento ::= “pc” ListaDeclaracaoParametro “.” Comando ValorConcreto ::= ValorInteiro | ValorBooleano | ValorString | ValorArray 4/24 Alterações na BNF ValorArray ::= “{” ListaExpressao “}” ExpUnaria ::= "-" Expressao | "not" Expressao | "length" Expressao ExpBinaria ::= Expressao "+" Expressao | Expressao "-" Expressao | Expressao "and" Expressao | Expressao "or" Expressao | Expressao "==" Expressao | Expressao "++" Expressao Indexacao ::= Id “[“ Expressao “]” ComandoDeclaracao :: = "{" Declaracao ";" Comando "}" Declaracao ::= DeclaracaoVariavel | DeclaracaoProcedimento | DeclaracaoComposta DeclaracaoVariavel ::= "var" Id "=" Expressao | "array" Id "=" Expressao DeclaracaoComposta ::= Declaracao "," Declaracao 5/24 Alterações na BNF DeclaracaoProcedimento ::= "proc" Id "(" [ ListaDeclaracaoParametro ] ")" "{" Comando "}" ListaDeclaracaoParametro ::= DeclaracaoParametro | DeclaracaoParametro "," ListaDeclaracaoParametro DeclaracaoParametro::= Tipo Id Tipo ::= "string" | "int" | "boolean" | "TipoArray" | "TipoProcedimento“ TipoProcedimento:= Tipo | Tipo "," TipoProcedimento While ::= "while" Expressao "do" Comando IfThenElse ::= "if" Expressao "then" Comando "else" Comando 6/24 Alterações no Parser Declaracao PDeclaracao(): { Declaracao retorno; } { ( LOOKAHEAD(PDeclaracaoVariavel() <COMMA>) retorno = PDeclaracaoComposta() | LOOKAHEAD(PDeclaracaoProcedimento() <COMMA>) retorno = PDeclaracaoComposta() | retorno = PDeclaracaoVariavel() | retorno = PDeclaracaoProcedimento() ) {return retorno;} } 7/24 Alterações no Parser DeclaracaoComposta PDeclaracaoComposta(): { Declaracao d1; Declaracao d2; } { d1 = PDeclaracaoVariavel() <COMMA> d2 = PDeclaracao() {return new DeclaracaoComposta(d1, d2);} | d1 = PDeclaracaoProcedimento() <COMMA> d2 = PDeclaracao() {return new DeclaracaoComposta(d1, d2);} } 8/24 Alterações no Parser Tipo PTipo(): { Tipo tipo; Tipo tipoInterno; } { ( (<INT> {tipo = Tipo.TIPO_INTEIRO;} | <BOOLEAN> {tipo = Tipo.TIPO_BOOLEANO;} | <STRING> {tipo = Tipo.TIPO_STRING;} ) [ LOOKAHEAD (<LBRACKET>) <LBRACKET> <RBRACKET> {tipoInterno = tipo; tipo = Tipo.TIPO_ARRAY; tipo.setTipoInterno(tipoInterno);} ] | tipo = PTipoProcedimento() ) { return tipo; } 9/24 } Alterações no Parser Tipo PTipoProcedimento(): { List listTipos = new ArrayList(); Tipo tipo; } { LOOKAHEAD (<LBRACKET> <RBRACKET> ) <LBRACKET> <RBRACKET> { return new TipoProcedimento(listTipos); } | <LBRACKET> tipo = PTipo() { listTipos.add(tipo); } ( (<COMMA> tipo = PTipo()) { listTipos.add(tipo); } )* <RBRACKET> { return new TipoProcedimento(listTipos); } } 10/24 Alterações no Parser Valor PValor() : { Valor retorno; } { ( retorno = PValorInteiro() | retorno = PValorBooleano() | retorno = PValorString() | retorno = PValorArray() | retorno = PValorProcedimento() ) { return retorno; } } 11/24 Alterações no Parser Valor PValorProcedimento() : { ListaDeclaracaoParametro parametrosFormais; Comando comando; } { <PC> parametrosFormais = PListaDeclaracaoParametro() <DOT> <LBRACE> comando = PComando() <RBRACE> { return new ValorProcedimento(parametrosFormais, comando); } } 12/24 Alterações no Parser ListaDeclaracaoParametro PListaDeclaracaoParametro(): { DeclaracaoParametro parametro; List retorno = new ArrayList(); } { ( ( parametro = PDeclaracaoParametro() ) { retorno.add(parametro); } ( ( <COMMA> parametro = PDeclaracaoParametro() ) { retorno.add(parametro); } )* )? { return new ListaDeclaracaoParametro(retorno); } } 13/24 Alterações no Parser DeclaracaoParametro PDeclaracaoParametro(): { Id id; Tipo tipo; } { tipo = PTipo() id = PId() { return new DeclaracaoParametro(id, tipo); } } 14/24 Simplificações no Ambiente • Como procedimento agora é um Valor, não se faz necessário fazer um mapeamento diferenciado para associar identificadores de procedimentos às respectivas definições. • Necessidade de apenas um único mapeamento. 15/24 Simplificações no Ambiente • AmbienteCompilacaoImperativa2 (plp.imperative2.memory) public void mapParametrosProcedimento(IdAbstrato idArg, ListaDeclaracaoParametro parametrosId) public ListaDeclaracaoParametro getParametrosProcedimento(IdAbstrato idArg) • ContextoCompilacaoImperativa2 (plp.imperative2.memory) • AmbienteExecucaoImperativa2 (plp.imperative2.memory) public void mapProcedimento(Id idArg, Procedimento procedimentoId) public Procedimento getProcedimento(Id idArg) • ContextoExecucaoImperativa2 (plp.imperative2.memory) 16/24 Classes Criadas • ValorProcedimento (plp.imperative3) - extends DefProcedimento - implements ValorAbstrato - public ValorProcedimento(ListaDeclaracaoParametro parametrosFormais, Comando comando) { super(parametrosFormais, comando); } - public Valor avaliar(AmbienteExecucao amb) throws ...{ return this; } 17/24 Classes Criadas • ValorProcedimento (plp.imperative3) (cont.) - public boolean checaTipo(AmbienteCompilacao amb) throws ... { return this.getTipo(amb) != null; } - public Tipo getTipo(AmbienteCompilacao amb) throws ...{ List<Tipo> list = new ArrayList<Tipo>(); ListaDeclaracaoParametro parametrosFormais2 = getParametrosFormais(); for (DeclaracaoParametro declaracaoParametro : parametrosFormais2) { list.add(declaracaoParametro.getTipo()); } return new TipoProcedimento(list); 18/24 Classes Criadas • TipoProcedimento (plp.imperative3) - extends Tipo - private List<Tipo> listTipo; // Compara os parâmetros formais com os parâmetros reais public boolean checaTipo(List<Tipo> tiposParametrosReais) { return this.listTipo.equals(tiposParametrosReais); } 19/24 Classes Alteradas • Tipo (plp.expressions1.util) - Novo tipo -> TIPO_PROC - public boolean eProc() 20/24 Classes Alteradas • DeclaracaoProcedimento (plp.imperative2.declaration) - Construtor: public DeclaracaoProcedimento(Id nome, DefProcedimento defProcedimento) public DeclaracaoProcedimento(IdAbstrato nome, ValorProcedimento valorProcedimento) - ChecaTipo: ambiente2.mapParametrosProcedimento(parametro1, parametrosFormais); ambiente.incrementa(); ambiente.map(parametro1, parametro2.getTipo(ambiente)); resultado = parametrosFormais.checaTipo(ambiente); ambiente =parametrosFormais.declaraParametro(ambiente); resultado = resultado && comando.checaTipo(ambiente); return resultado; 21/24 Classes Alteradas • DeclaracaoProcedimento (plp.imperative2.declaration) - Elabora: • ((AmbienteExecucaoImperativa2) ambiente).mapProcedimento(parametro1,new Procedimento(parametrosFormais, parametro2)); • ((AmbienteExecucaoImperativa) ambiente).map(parametro1,parametro2); 22/24 Classes Alteradas • ChamadaProcedimento (plp.imperative2.command) - executar: Procedimento procedimento = ambiente.getProcedimento(nomeProcedimento); ValorProcedimento procedimento = (ValorProcedimento) ambiente.get(nomeProcedimento); - checaTipo: ambiente.incrementa(); Tipo tipo = ambiente.get(this.nomeProcedimento); if(!tipo.eProc()){ return false; } TipoProcedimento tipoProc = (TipoProcedimento) tipo; List<Tipo> tiposParametrosReais = parametrosReais.getTipos(ambiente); resposta = tipoProc.checaTipo(tiposParametrosReais); ambiente.restaura(); return resposta; 23/24 Dúvidas ? 24/24