1. Linguagens Capítulo 1 Linguagens e processadores 2. Processamento de Linguagens: DI-UBI 2017/2018 1/28
Linguagens Linguagens Processamento de Linguagens: DI-UBI 2017/2018 2/28
Linguagens 1. Definição Definição: Uma linguagem L sobre um alfabeto (vocabulário) V é um conjunto de frases, em que uma frase é uma sequência de símbolos de V (vocábulos ou palavras). Uma linguagem apenas admite combinações de vocábulos que são frases válidas. A definição de uma linguagem é feita em dois passos: 1. Estabelecer qual o alfabeto a usar; 2. Indicar as regras que restringem, das combinações possíveis, aquelas que de facto são frases corretas. As regras referidas no passo 2 dividem-se em: - regras sintáticas: definem as formas corretas; - regras semânticas: definem as condições para que as frases sintaticamente corretas possam ser interpretadas. Processamento de Linguagens: DI-UBI 2017/2018 3/28
Linguagens As regras sintáticas preocupam-se com a estrutura das frases. As regras semânticas trabalham ao nível dos valores intrínsecos dos símbolos e preocupam-se com o significado das frases (o seu conteúdo semântico). O significado é a informação contida numa frase e é aquilo que realmente interessa conhecer para que a comunicação entre dois agentes tenha algum efeito. Processamento de Linguagens: DI-UBI 2017/2018 4/28
Linguagens 2. Linguagens naturais versus linguagens artificiais Linguagens naturais (utilizadas para as pessoas comunicarem): - frases pertencem à linguagem por razões de facto (usam no quotidiana); - regras surgem posteriormente para - sistematizar e ensinar no futuro a linguagem, e - organizar/estruturar as frases; - existe ambiguidade. Linguagens artificiais (suportam a comunicação Homem/Máquina) - só começam a ser usadas após o vocabulário ser escolhido e as regras sintáticas e semânticas serem estabelecidas; - as regras definidas são pensadas para garantir a não-ambiguidade. Processamento de Linguagens: DI-UBI 2017/2018 5/28
Linguagens 3. Como se especifica uma linguagem As linguagens artificiais têm de ter a sua sintaxe e semântica rigorosamente definidas à custa de regras apropriadas. As regras devem ser escritas de forma sucinta e objetiva, para garantir a sua interpretação - com facilidade e - sem ambiguidade, pelos agentes presentes na comunicação (Emissor e Recetor). A gramática é aceite universalmente como notação formal para definir linguagens - ensinando como se escrevem (produzem) as frases da linguagem (gerador); - determinando como se podem analisar essas frases (reconhecedor). Processamento de Linguagens: DI-UBI 2017/2018 6/28
Processamento de Linguagens: DI-UBI 2017/2018 7/28
1. Definição Definição: Seja L(G) a linguagem gerada pela gramática G. Um processador para essa linguagem P L(G), é um programa que, tendo conhecimento da gramática G: - lê um texto (sequência de caracteres); - verifica se esse texto é uma frase válida de L(G); - executa uma ação em função do significado da frase reconhecida. Todos estes programas são caracterizados por dois grandes módulos: - análise, faz o reconhecimento do significado do texto fonte; - síntese, reage ao significado identificado, produzindo um determinado resultado. Processamento de Linguagens: DI-UBI 2017/2018 8/28
Exemplos de processadores de linguagens: - compiladores: traduzem linguagens programação alto nível para código máquina; - assemblers: traduzem linguagens programação baixo nível para código máquina; - interpretadores: executam os programas imediatamente a seguir ao seu reconhecimento (realizam ações); - tradutores em geral: transformam textos escritos numa linguagem qualquer para outra linguagem qualquer; - carregadores: reconhecem descrições de dados e carregam essa informação para Base de Dados ou para Estruturas de Dados em memória central; - pesquisadores: reconhecem questões ( query ) e pesquisam em Base de Dados para mostrarem as respostas encontradas; - processadores de documentos: usados para diversos tipos de manipulação de documentos como, por ex., formatação (LATEX). Processamento de Linguagens: DI-UBI 2017/2018 9/28
Em termos cronológicos, os primeiros processadores de linguagens foram os - assemblers, - compiladores e - interpretadores. Processamento de Linguagens: DI-UBI 2017/2018 10/28
2. Tarefas O processamento divide-se em duas partes: - análise (reconhecimento) e, - síntese (reação). Processamento de Linguagens: DI-UBI 2017/2018 11/28
A análise é sempre realizada da mesma forma (qualquer que seja o processador da linguagem) e costuma subdividir-se nas três tarefas seguintes: - análise léxica: - leitura sequencial dos caracteres do texto fonte, - separação em palavras e - reconhecimento dos símbolos terminais representados por cada palavra - análise sintática: - agrupar os símbolos terminais e - verificar se formam uma frase sintaticamente correta (composta segundo as regras sintáticas da linguagem) - análise semântica: - verificar se as regras semânticas da linguagem são satisfeitas e - calcular os valores associados aos símbolos, de modo a poder conhecer-se o significado completo da frase. Processamento de Linguagens: DI-UBI 2017/2018 12/28
A síntese não é habitual dividir-se em tarefas, para não ter de se pormenorizar em que consiste a ação de transformação e o significado. Módulos associados às fases de análise e de síntese têm de comunicar entre si - Analisador léxico passa ao analisador sintático os símbolos terminais que reconheceu no texto fonte - Analisador sintático envia ao analisador semântico uma representação interna da forma (estrutura sintática) da frase (usando uma árvore de derivação) - Analisador semântico passa ao transformador (reação) uma árvore de sintaxe decorada que representa o significado da frase Processamento de Linguagens: DI-UBI 2017/2018 13/28
3. Estratégias de processamento Para a fase de síntese/reação (transformação da frase de entrada no resultado final), existem duas grandes estratégias que podem ser usadas: - Tradução Orientada pela Sintaxe - Tradução Orientada pela Semântica Processamento de Linguagens: DI-UBI 2017/2018 14/28
Tradução Orientada pela Sintaxe: - a mais antiga e a mais usada - todo o processamento é controlado pelo analisador sintático - o analisador semântico vai pedindo o próximo símbolo do texto fonte e, à medida que vai progredindo no reconhecimento, vai fazendo, de forma intercalada, a análise semântica e a transformação - não há uma separação nítida entre todas as tarefas e nunca se chega a construir integralmente a árvore de sintaxe decorada, nem tão pouco a árvore de derivação - formalismo de especificação usado é a gramática tradutora - é mais simples de especificar e menos exigente em termos de requisitos de hardware e de software. Processamento de Linguagens: DI-UBI 2017/2018 15/28
Tradução Orientada pela Semântica: - tem vindo a ganhar adeptos, à medida que os recursos-máquina aumentam e o seu preço baixa, tendo atualmente uma grande importância - todas as tarefas referidas são executadas separadamente, não se distinguindo nenhuma em relação às outras - a árvore de derivação é construída explicitamente para todas as restantes etapas trabalharem sobre a árvore de sintaxe decorada - formalismo de especificação usado é a gramática de atributos - corresponde a um maior rigor na descrição formal do processador a desenvolver e trás vantagens do ponto de vista da programação. Processamento de Linguagens: DI-UBI 2017/2018 16/28
4. Compiladores Definição: Um compilador é um processador de linguagens construído para reconhecer programas, escritos em linguagens de programação de alto nível, e traduzi-los para código binário (máquina). Texto fonte Compilador Texto alvo Mensagens O compilador visto pelo utilizador Processamento de Linguagens: DI-UBI 2017/2018 17/28
Definição: Um transcompilador ( cross-compiler ) é um processador que aceita um texto numa linguagem de alto nível e produz um texto noutra linguagem de alto nível. Os compiladores introduzem problemas específicos na análise semântica e na tradução que, neste caso, tem o nome de geração de código. Um compilador é especifico de um determinado computador, pois produz código máquina que varia entre marcas e entre modelos. Processamento de Linguagens: DI-UBI 2017/2018 18/28
Pelo facto de - existir desnível entre - a complexa estrutura da linguagem fonte e - a enorme simplicidade da linguagem máquina (o que implica grande dificuldade na definição dos esquemas de tradução) - os esquemas de tradução serem dependentes do computador escolhido como objeto da tradução, leva à criação de uma representação intermédia que deve - manter a mesma semântica do programa fonte e - permitir algumas otimizações. A linguagem escolhida para código intermédio constitui uma representação do código final ¾ não engloba detalhes (como a gestão de registos e de memória) da máquina onde será executado o código final Processamento de Linguagens: DI-UBI 2017/2018 19/28
Com a introdução duma linguagem intermédia, a tarefa de geração de código é dividida em duas sub-tarefas: - geração de código intermédio o significado da frase de entrada é reescrito na linguagem intermédia - geração de código final responsável pela tradução do código intermédio para código máquina Processamento de Linguagens: DI-UBI 2017/2018 20/28
A implementação de um compilador requer o desenvolvimento de outros módulos próprios e muito importantes para o sucesso do programa final, como sejam: - para fazer o tratamento dos identificadores recolhe toda a informação associada a cada identificador que surge no programa fonte - para fazer o tratamento de erros depois de detetado um erro, encarrega-se de o reportar ao programador e assegurar a sua correção/recuperação - para fazer a otimização do texto fonte e do texto final (objeto) gerado conduzem à produção dum código máquina bastante eficiente em termos de tamanho, de rapidez de execução e de requisitos de memória Processamento de Linguagens: DI-UBI 2017/2018 21/28
A otimização é - uma etapa complementar à geração de código (intermédio e final), - atua frequentemente em simultâneo com esta - tem por objetivo a produção de programas mais eficientes, mas mantendo sempre a correção do código otimizado A otimização do código pode ser classificada segundo a área de código a otimizar: - Local sendo cada instrução observada individualmente - Bloco sendo observada uma sequência de instruções denominada bloco básico - Global sendo observada uma janela do programa Processamento de Linguagens: DI-UBI 2017/2018 22/28
Programa fonte Análise léxica Análise sintática Análise semântica Tabela de símbolos Geração de código intermédio Geração de código Otimização de código Programa alvo Etapas de um compilador. Processamento de Linguagens: DI-UBI 2017/2018 23/28
5. Assemblers Os assemblers são funcionalmente muito parecidos com os compiladores, na medida em que traduzem um programa fonte para código máquina. A diferença reside no facto de que o texto de entrada, nos assemblers, não é escrito numa linguagem de alto nível, mas sim numa linguagem de mnemónicas estruturalmente tão simples quanto um programa em linguagem máquina. Por isso, não só o reconhecimento das frases se torna muito fácil, como também os esquemas de tradução são simples e intuitivos, e o processo de tradução muito direto Na verdade, o assembler pouco difere do módulo de geração de código final igual ao dos compiladores. Processamento de Linguagens: DI-UBI 2017/2018 24/28
6. Interpretadores Estes processadores não geram um texto de saída, mas sim executam as instruções do programa fonte logo que o reconhecem. A execução é feita sobre a representação intermédia de código, tipicamente numa notação em árvore. O uso de interpretadores é muito conhecido pelos programadores das linguagens Basic, Lisp e Prolog (os exemplos mais vulgares desta técnica de processamento). As vantagens dos interpretadores são: - fácil de implementar, - assegura maior rapidez no ciclo edição/compilação/execução, - permitem testar/alterar programas à medida que são executados. Processamento de Linguagens: DI-UBI 2017/2018 25/28
As desvantagens são: - acesso limitado a rotinas, - inviáveis em projetos de larga escala. O interpretador - não tem de se preocupar com questões de otimização; - geralmente processa linguagens de programação menos ricas estruturalmente do que o compilador. Texto fonte Interpretador Saída Dados Arquitetura de um interpretador Processamento de Linguagens: DI-UBI 2017/2018 26/28
7. Tratamento de erros A capacidade para tratar os erros é de enorme importância para a sua aceitação, pelo utilizador final, como ferramenta de trabalho. Se forem detetados erros ao analisar uma frase, esta não deve simplesmente ser rejeitada e o processamento terminar por aí. Definição: Entende-se por tratamento de erros o processo que é desencadeado pelo reconhecedor logo após a deteção de um erro na frase que está a ser analisada. A reação compreende duas grandes tarefas: - sinalização do erro; - correção/recuperação. A deteção de um erro está inerente à análise. Processamento de Linguagens: DI-UBI 2017/2018 27/28
Na analise de uma frase, são três as razões que podem levar à deteção de um erro: - caracteres inválidos (erro léxico); - combinação de símbolos terminais inválida (erro sintático); - aparecimento dum símbolo terminal que infringe as regras que têm de ser verificadas para se poder identificar o significado da frase (erro semântico); Uma frase pode ainda conter outro tipo de erros (por ex. algoritmo incorreto), em que um processador de linguagens não é capaz de os detetar (erros lógicos). A sinalização do erro é de importância crucial para que o programador possa localizar o foco de problemas, interpretá-los e corrigi-los definitivamente. Por isso, a mensagem a ser enviada deve, no mínimo, indicar: - a posição (linha e coluna, em relação ao texto fonte) onde o erro foi encontrado; - símbolo de erro; - a causa provável que justifica esse erro (diagnóstico). Processamento de Linguagens: DI-UBI 2017/2018 28/28