Compiladores Compiladores Aula 14 Prof. Me. Ivan José dos Reis Filho Aula de hoje Introdução à Compiladores Análise léxica ● Análise sintática ● Análise semântica ● História das Linguagens História das Linguagens ● Fortran (1957) ● LISP(1959) ● COBOL(1960) ● BASIC(1964) ● C(1972) ... Linguagens de Alto Nível Linguagem de Alto nível Alto nível ● Tem sentido de “alto nível de abstração, pois essas linguagens abstraem detalhes operacionais pouco relevantes. Veremos agora dois exemplos para comparar as linguagens de nível alto e baixo Exemplo em Alto Nível Programa Hello World em C #include <stdio.h> int main() { printf(“Hello World”); return 0; } Exemplo em Baixo Nível Programa Hello World em assembly x86 DOSSEG .MODEL SMALL .DATA Msg db "Hello World.",13,10,"$" .CODE Start: mov AX, @DATA mov DS, AX lea DX, Msg mov AH, 9 int 21h mov ah, 4ch int 21h END Start Introdução a Compiladores Compilador Compilador Compilador Interpretador Compilador X Interpretador Compilador ● O programa objeto é muito mais rápido no mapeamento de entradas para saídas Interpretador ● Oferece um melhor diagnóstico de erros do que um compilador, pois executa o programa fonte instrução por instrução Tradutor Linguagem fonte → Linguagem destino Chinês para Inglês ● Java para C ● C para C++ ● HTML para PHP ● Estrutura de um Compilador Mapeado em duas partes: ● Análise (front-end) − ● Verifica se o programa fonte está sintaticamente mal formado ou semanticamente incorreto. Síntese (back-end) − Constrói o programa objeto desejado a partir da representação intermediária e das informações na tabela de símbolos. Fases do Compilador Análise Análise Léxica (1ª Fase) ● ● Lê o fluxo de caracteres que compõem o programa fonte e os agrupa em sequências, chamadas lexemas. Para cada lexema, o analisador produz como saída um token no formato: <nome-token, valor atributo> ● Os token's é passado para subsequente, a análise sintática. a fase Análise Léxica (1ª Fase) <nome-token, valor atributo> ● ● ● O nome do token é um símbolo abstrato que é usado durante a análise sintática; O valor atributo, aponta para uma entrada na tabela de símbolos referente a esse token; A informação da tabela da tabela de símbolos é necessária para análise semântica e geração do código. Análise Léxica (1ª Fase) Por exemplo: Suponha que um programa fonte contenha o comando de atribuição. position = initial + rate * 60 O caracteres nessa atribuição poderiam ser agrupados nos seguintes lexemas e mapeados para os seguintes tokens passados ao analisador sintático. próximo slide Análise Léxica (1ª Fase) position = initial + rate * 60 ➢ position é um lexema mapeado em um token <id, 1>, onde id é um símbolo abstrato que significa identificador e 1 aponta para a entrada da tabela de símbolos. Análise Léxica (1ª Fase) position = initial + rate * 60 ➢ ➢ position é um lexema mapeado em um token <id, 1>, onde id é um símbolo abstrato que significa identificador e 1 aponta para a entrada da tabela de símbolos. O símbolo de atribuição = é um lexema mapeado para o token <=> Análise Léxica (1ª Fase) position = initial + rate * 60 ➢ ➢ ➢ position é um lexema mapeado em um token <id, 1>, onde id é um símbolo abstrato que significa identificador e 1 aponta para a entrada da tabela de símbolos. O símbolo de atribuição = é um lexema mapeado para o token <=> initial é um lexema mapeado para o token <id, 2>, onde 2 aponta para a entrada na tabela de símbolos, onde se encontra initial Análise Léxica (1ª Fase) position = initial + rate * 60 ➢ + é um lexema mapeado para o token <+> Análise Léxica (1ª Fase) position = initial + rate * 60 ➢ + é um lexema mapeado para o token <+> ➢ rate é um lexema mapeado para o token <id, 3> Análise Léxica (1ª Fase) position = initial + rate * 60 ➢ + é um lexema mapeado para o token <+> ➢ rate é um lexema mapeado para o token <id, 3> ➢ * é um lexema mapeado para o token <*> Análise Léxica (1ª Fase) position = initial + rate * 60 ➢ + é um lexema mapeado para o token <+> ➢ rate é um lexema mapeado para o token <id, 3> ➢ * é um lexema mapeado para o token <*> ➢ 60 é um lexema mapeado para o token <60> Análise Léxica (1ª Fase) position = initial + rate * 60 <id, 1> <=> <id, 2> <+> <id, 3> <*> <60> Tabela de símbolos id (position) 1 id (initial) 2 id (rate) 3 ... 2ª Fase Análise Sintática (2ª Fase) Componentes dos tokens são utilizados para criar uma representação intermediária, tipo árvore. Verifica se pode ser gerada por uma gramática. ● ● ● Mostra a estrutura gramatical da sequência de tokens. Cada nó interior representa uma operação. Cada nó folha representam os argumentos da operação Análise Sintática (2ª Fase) position = initial + rate * 60 <id, 1> <=> <id, 2> <+> <id, 3> <*> <60> Análise Sintática (2ª Fase) Além disso, “É a fase que analisa os tokens para descobrir a estrutura gramatical do código fonte” ● Também chamada “Reconhecimento” ● Gramática livre de contexto é usada para definir a estrutura do programa. ● Análise Sintática (2ª Fase) Regras sintáticas(1) Qualquer identificador é uma expressão ● Qualquer número é uma expressão ● Se expressão1 e expressão2 são expressões, então também são expressões ● ➢ expressão1 + expressão2 ➢ expressão1 * expressão2 ➢ ( expressão1 ) Análise Sintática (2ª Fase) Regras sintáticas(2) Se identificador1 é um identificador2 e expressão é uma expressão, então identificador1 = expressão2 é um comando (statement) ● Se expressão1 é uma expressão e statement2 é um comando, então ● while ( expressão1 ) { statement2 } if ( expressão1 ) { statement2 } são comandos (statements) Análise Sintática (2ª Fase) 3ª Fase Análise Semântica (3ª Fase) O papel do analisador é prover métodos pelos quais as estruturas construídas pelo analisador sintático possam ser avaliadas ou executadas ● Gramática Regular ● Gramática Livre de Contexto ● Gramática Sensível ao Contexto Análise Semântica (3ª Fase) O analisador utiliza a árvore de sintaxe e as informação na tabela de símbolos para verificar a consistência semântica ● Verificação de tipo - verifica se cada operador possui operandos compatíveis Exemplo: verifica se o índice do vetor é um inteiro Análise Semântica (3ª Fase) Resumo