****************************** ********** COM - P2 ********** ****************************** Data : 05/12/2003 a 06/12/2003 Versão : 04/07/2007 Professor: Fabrício Jailson Barth Autor : Leandro Salvador ( leandrosalvador.com.br ) * Prova 1) Descreva o conceito de bootstraping. Se necessário utilize desenhos: - bootstraping diz respeito ao recurso de se utilizar uma linguagem de programação para gerar um compilador que reconheça uma linguagem diferente, geralmente de nível mais alto - por exemplo, com a linguagem Assembly fazemos um compilador que reconhece Assembly, então a partir desse compilador e utilizando Assembly, construímos um compilador que reconhece C - da mesma forma, utilizamos C para construir um compilador que reconhece Java, e assim consecutivamente - em nosso trabalho, utilizamos Java para construir um compilador que reconhece Portugol, um exemplo típico de bootstraping 2) Defina e exemplifique: a) Verificação de tipos - verifica se uma variável de determinado tipo está recebendo um valor do mesmo tipo - regras de operação --> verifica que após uma determinada operação, o resultado obtido será do tipo correto, ex.: float + int = float - hierarquia de tipos --> um tipo de maior capacidade receber um tipo de menor capacidade, também conhecido como "coersão" b) Verificação de Declaração - verifica se as variáveis utilizadas no programa foram declaradas antes de terem sido utilizadas c) Verificação de Unicidade - verifica se cada variável foi definida uma única vez d) Verificação de Escopo dos Identificadores - verifica se cada variável está sendo utilizada em seu escopo correto, ou seja, se a variável foi declarada no mesmo escopo em que está sendo utilizada ou, no mínimo, em um escopo mais abrangente (que envolva o escopo onde está sendo utilizada) - podemos entender escopo como sendo a "área de atuação" do identificador (ou variável) 3) Descreva um algoritmo unificado para o controle da verificação de tipos, declaração, unicidade e escopo dos identificadores: ??? 4) Explique a necessidade de uma representação intermediária na geração do código objeto. Forneça dois exemplos: - a utilização de um Código Intermediário (C.I.) permite que o mesmo seja facilmente transformado para código objeto em diversas arquiteturas - isso pode facilitar muito a portabilidade de um programa, pois não exige que se tenha o código fonte todas as vezes em que se desejar ter o código objeto (executável) em outra arquitetura - portabilidade é a capacidade/facilidade que uma linguagem possui de ter seus programas executados (ou interpretados) em diversas arquiteturas - Java, por exemplo, compila seus programas em um C.I. que, por sua vez, será interpretado por um interpretador específico para cada Sistema Operacional - o interpretador pode ter sido compilado para cada arquitetura e Sistema Operacional, mas o C.I. que é gerado pelo compilador Java pode ser utilizado por qualquer interpretador Java, de forma "universal" - C++ e C, por sua vez, geram o C.I., mas o transforma em código objeto executável específico para cada Sistema Operacional e arquitetura, de modo que quando se desejar "rodar" o programa em outro S.O., será necessário compilar o código fonte neste S.O. - desta forma, existe a dependência do código fonte para portar o programa, já no caso do Java, não - bastará o C.I. (.class) ... continua (tem + 1 exemplo) 5) Discorra sobre a interação entre o programa-objeto e o sistema operacional. Principalmente, sobre a realocação de memória e chamadas de subrotinas. Por que em linguagens interpretadas o módulo responsável pela geração de código não precisa se preocupar com a intereção entre o programa-objeto e o sistema operacional? Forneça exemplos: - o Programa-Objeto (PO) é compilado (ou interpretado) para um específico Sistema Operacional (SO) de uma específica Arquitetura - quando é gerado, o PO já possui todas as regras específicas do SO para o qual foi gerado, inclusive e, principalmente, as regras de realocação de memória (e também de entrada/saída, entre outras) - as linguagens interpretadas se baseiam em um Código Intermediário (CI), e não em um PO - desta forma, toda vez que um programa feito em linguagem interpretada for "rodar", o interpretador da linguagem irá analisar o CI e, a partir dele, gerará o PO - quem conhece, nesse caso, as regras de interação com o SO é o interpretador, e não o CI - o módulo responsável pela geração do CI das linguagens interpretadas não precisa, portanto, se preocupar com a interação entre o PO e o SO, pois quem se preocupará com essa interação será o interpretador da linguagem - as chamadas de subrotinas fazem com que o programa pule de uma parte para outra da memória (jump), por isso também que existe a necessidade de se conhecer as regras de realocação de memória - de duas uma: ou o programa que irá "rodar" já conhece essas regras desde o momento em que foi compilado (limita sua execução para um único SO/arquitetura), ou quem conhece essas regras é o interpretador, que unicrá o CI às regras e gerará um PO (exige um interpretador para "rodar" o programa, tornando o processo mais lento) - Linguagem Interpretada --> PHP, ASP - Linguagem Compilada --> C, C++, Delphi - Linguagem Híbrida --> Java 6) Desenhe a estrutura interna de um compilador. Tente ser o mais detalhista possível: ________ ____________ ____________ ____________ _______________ ,-->... | código |-->| analisador |-->| analisador |-->| analisador |-->| código |/ | fonte | | léxico | | sintático | | semântico | | intermediário |\ ¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯¯¯¯¯ ¯|¯¯|¯¯|¯¯|¯ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ `-->... / / \ \ ,--------------´ / \ `---------------. | / \ | _________|___ _________/___ ___\_________ ___|_________ | verificação | | verificação | | verificação | | verificação | | declaração | | declaração | | declaração | | declaração | ¯¯¯¯¯¯¯¯¯|¯¯¯ ¯¯¯¯¯¯¯¯¯\¯¯¯ ¯¯¯/¯¯¯¯¯¯¯¯¯ ¯¯¯|¯¯¯¯¯¯¯¯¯ | \ / | '---------------. \ / ,---------------' \ \ / / _|__|__|__|_ | tabela | | códigos | ¯¯¯¯¯¯¯¯¯¯¯¯ _______________ ________ | interpretador | | código | ,-->| |-->| objeto | / ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯ \ _________ _________ `-->| código |-->| código | | máquina | | objeto | ¯¯¯¯¯¯¯¯¯ | máquina | ¯¯¯¯¯¯¯¯¯ ----------//----------