domingo, 18 de maio de 2008

Pessoal, aguarde mais um pouco!

Ainda estou na metade do meu resumo para o trabalho. Logo, ainda vou precisar de mais alguns dias para postá-lo. Provavelmente, vou conseguir quinta-feira.

Valeu, e até a próxima...

segunda-feira, 12 de maio de 2008

Estrutura de um tradutor: Síntese

Agora que nós já explicamos a etapa da Análise, na qual o compilador lê as sequências de caracteres e identifica cada unidade léxica (os tokens) e verifica se fazem sentido, vamos falar sobra a Síntese que é onde o compilador finalmente gera o código objeto, numa linguagem de baixo nível.
Assim, como a Análise, a Síntese também está subdividida em fases, são elas: a Geração de Código Intermediário, Otimização de Código e, enfim, a Geração de Código Obejto. Vamos descrevê-las individualmente.

Geração de Código Intermediário: Essa fase utiliza a representação interna produzida pelo Analisador Sintático e gera como saída um código, que pode ser o código objeto final, mas geralmente contitui-se de um código intermediário. Essa fase é bem útil, pois possibilita a otimização de código intermediário, de modo a obter-se o código objeto final mais eficiente. Além de resolver, gradualmente, as dificuldades da passagem de código fonte para o objeto (alto nível para baixo nível), já que o código fonte representa inúmeras instruções elementares numa linguagem de baixo nível.

Otimizção de Código: Essa fase objetiva a otimização do código intermediário em termos de velocidade de execução e espaço de memória.

Geração de Código Objeto: É a fase mais difícil, pos requer uma seleção cuidadosa das intruções e dos registradores da máquina alvo a fim de produzir um código objeto eficiente. Existem tradutores que possuem mais uma fase para realizar a otimização do código objeto.

Adaptado do Livro "Implementação de Linguagens de Programação: Compiladores de Ana Maria de Alencar Price e Simão Sirineo Toscani"

sábado, 10 de maio de 2008

Estrutura de um tradutor: Análise

Em geral, os tradutores de linguagens de programação são programas bastantes complexos. Independentemente da linguagem a ser traduzida ou do programa objeto a ser gerado, os tradutores, de um modo geral compõe-se de funções padronizadas, que compreendem a analise de um programa fonte e a posterior sintese para a derivação do código objeto.

O processo de tradução é estruturado em fases, no qual cada subfase se comunica com a seguinte através de uma linguagem intermediária adequada. Suas fases são: Analise e Síntese.

A fase referente a Análise é subdividida em Análise Léxica, Análise Sintática e Análise Semântica.

O objetivo principal da Análise Léxica é identificar sequências de caracteres que constituem unidades léxicas (“tokens”). O analisador léxico lê, caractere a caractere, o texto fonte, verificando se os caracteres lidos pertecem ao alfabeto da linguagem, identificando tokens, e desprezando comentários e brancos desnecessários. Além de reconhecer os simbolos léxicos, o analisador também realiza outras funções, como armazenar alguns desses símbolos em tabelas internas e indicar a ocorrencia de erros léxicos.

A sequencia de tokens produzida pelo analisador léxico é utilizada como entrada pelo módulo seguinte do compilador, o analisador sintático. É interessante observar que o mesmo programa fonte é visto pelos analisadores léxico e sintatico como sentenças diferentes. Para o analisador léxico o programa fonte é uma sequencia de palavras de uma linguagem regular. Para o analisador sintatico, essa sequencia de tokens constitui uma sentença de linguagem livre de contexto (permite expressar construções mais sofisticadas).

Os simbolos léxicos (tokens) constituem uma linguagem regular, que são as mais simples. No contexto de tradução de linguagem de programação, as linguagens são usualmente apresentadas através de gramaticas ou algoritmos (automatos) que as reconhecem.

A fase da Análise Sintática tem por função verificar se a estrutura gramatical do programa está correta (isto é, se essa estrutura foi formada usando as regras gramaticais da linguagem). A Analise Semântica irá verificar se as estruturas do programa irão fazer sentido durante a execução.

O Analisador Sintático identifica seqüências de símbolos que constituem estruturas sintáticas (cadeia de tokens) do programa fonte. Outra função dos reconhecedores sintáticos é a detecção de erros de sintaxe indentificando clara e objetivamente a posição e o tipo de erro ocorrido. Mesmo que erros tenham sido encontrados, o Analisador Sintatico deve tentar recuperá-los prosseguindo a análise do texto restante.

Muitas vezes, o Analisador Sintático opera conjuntamente com o Analisador Semântico, cuja principal atividade é determinar se as estruturas sintaticas analisadas fazem sentido, ou seja, verificar se um identificador declarado como váriavel é usado como tal; Se existe compatibilidade entre os operandos e operadores em expressões; etc.


Adaptado do livro: Implementação de Linguagens de Programação: Compiladores, de Ana Maria de Alencar Price e Simão Sirineo Toscani

quinta-feira, 8 de maio de 2008

O modelo de compilação de análise e síntese I

Depois das várias explicações já dadas, está na hora de um maior aprofundamento de como ocorre o processo de compilação. Nela existem duas partes: a análise e a síntese. Porém para o seu melhor entendimento, teremos que aprender mais alguns conceitos. São eles os algoritmos e as estruturas de dados.
Algoritmos: Para resolver um problema no computador é necessário que seja primeiramente encontrada uma maneira de descrever este problema de uma forma clara e precisa. É preciso que encontremos uma seqüência de passos que permitam que o problema possa ser resolvido de maneira automática e repetitiva. Esta seqüência de passos é chamada de algoritmo.
Sendo assim, algoritmo é um conjunto de instruções finita, não ambigua e com todos os passos definitos responsável por solucionar um problema.

Ele pode ser escrito em pseudo linguagem ou por meio de fluxogramas. Por pseudo linguagem, os algoritmos são representados em uma linguagem que esteja o mais próximo possível de uma linguagem de programação de computadores de alto nível, mas evitando definir regras de construção gramatical muito rígidas. A idéia é usar as vantagens do emprego da linguagem natural, mas restringindo o escopo, o objetivo da linguagem. Normalmente estas linguagens são versões ultra reduzidas de linguagens de alto nível do tipo Pascal ou C. Por fluxogramas várias formas geométricas são utilizadas para descrever cada uma das possíveis ações durante a execução do algoritmos.
Exemplo:

Estrutura de dados: é o nome dado a organização de dados e algoritmos de forma coerente e racional de modo a otimizar, melhorar o seu uso. De acordo com o modo como um conjunto de dados são organizados e como as operações que são efetuadas sobre estes dados pode-se solucionar de forma simples problemas extremamente complexos. Existem diversos modelos de estruturas de dados, e novos modelos são criados constantemente, pois acompanham também a evolução dos algoritmos e das linguagens de programação, porém iremos nos prender a uma estrutura clássica que será citada com frequência daqui em diante.
Essa estrutura é chamada de árvore e ela se caracteriza pela relação de hierarquia entre os elementos que a compõem. O exemplo abaixo é uma representação simples de uma árvore binária, caracterizada pelo elemento distinto (bola de cor vermelha) e sua bifurcações chamadas sub-árvore direita e sub-árvore esquerda (bola de cor azul).

segunda-feira, 5 de maio de 2008

Imagens esquemáticas de compiladores e interpretadores.

Tá, nós já demos várias definições de compiladores e interpretadores e explicamos algumas diferenças entre eles aqui no blog. Mas vamos continuar a explicar, para que todo mundo entenda melhor.

Os Compiladores são tradutores que mapeiam programas escritos em linguagem de alto nível para programas equivalentes em linguagem de máquina. A execução de um programa escrito em linguagem de alto níve
l é, basicamente, um processo de dois passos: primeiro ocorre a conversão do programa fonte para o programa objeto equivalente, esse intervale de tem é chamado de tempo de compilação; Depois, o programa objeto é executado no intervalo de tempo chamado de tempo de execução.

Já os interpretadores, são processadores que aceitam como entrada o código intermediário de um programa anteriormente traduzido e produzem o "efeito de execução" do algoritmo original, sem porém mapeá-lo para a linguagem de máquina. Ou seja, a interpretação ocorre no tempo de execução, não sendo gerado um programa objeto.


Há alguns interpretadores que não utilizam um código intermediário, trabalhando diretamente sobre o programa fonte cada vez que esse deve ser executado. Mas esse enfoque consome muito tempo. Uma estratégia mais eficiente é a aplicação de técnicas de compilação para traduzir o programa fonte para uma forma intermediária que é, então, interpretada.


Adaptado do livro "Implementação de Linguagens de Programação: Compiladores", de Ana Maria de Alencar Price e Simão Sirineo Toscani.

sexta-feira, 2 de maio de 2008

Atualização do compilador Free Pascal, com várias melhorias!!!

Recentemente o compilador Free Pascal (FPC, "Free Pascal Compiler") chegou à sua versão 2.2.0 . Ele é um compilador open source para a linguagem Pascal, iniciado em 1993, hoje um dos grandes e mais sofisticados compiladores. Multiplataforma, visa a escrita do código uma única vez para compilação para várias plataformas, como Windows, Linux e Mac (claro, desde que recursos específicos de alguma plataforma não sejam utilizados). Cada vez mais programadores se utilizam do FPC, inclusive com o apoio do Lazarus, uma interface para o compilador, com facilidades para geração de aplicações gráficas.Na versão 2.2.0 várias melhorias foram conquistadas, destacando:

*Suporte às arquiteturas PowerPC/64 e ARM;

*Suporte às plataformas Windows x64, Windows CE, Mac OS X/Intel, Game Boy Advance e Nintendo DS;

*Linkador mais rápido para o ambiente Windows (uma das maiores queixas do FPC pelos programadores Windows era a lentíssima velocidade de compilação, realmente melhorada agora);

*Suporte para preenchimento automático de vários valores para variáveis durante os testes (debug), para facilitar a identificação de valores não inicializados;

*Suporte para delegação de interface (experimental, ainda) e um gerenciador de pacotes;

*Várias outras melhorias, como melhor suporte a variáveis, suporte a arquivos com múltiplos recursos (resources), widestrings compatíveis com objetos COM/OLE no Windows, etc.

adaptado do site Guia do Hardware.

quinta-feira, 1 de maio de 2008

O que são Compiladores e Interpretadores e qual a diferença básica entre eles

Pessoal, em primeiro lugar, devemos observar que os compiladores e interpretadores são programas que têm por objetivo traduzir um outro programa (escrito em linguagem de alto nível - código fonte - para linguagem de baixo nível - linguagem de máquina, gerando, assim, o código objeto), no entanto uma diferença básica deve ser notada: eles diferem na forma de traduzir um programa, pois os interpretadores traduzem e executam cada linha de código sequencialmente enquanto que os compiladores traduzem todas as linhas de código para, enfim, poder executar um programa.

valeu, até a próxima...