Compiladores: P ASCAL jr

Tamanho: px
Começar a partir da página:

Download "Compiladores: P ASCAL jr"

Transcrição

1 Compiladores: P ASCAL jr Rogério Eduardo da Silva, M.Sc. 2005/2

2 Sumário 1 Introdução Evolução das Linguagens de Programação Introdução à Compilação Fases da Compilação Ferramentas para Geração de Compiladores Um Compilador Simples de uma Passagem Definição da Sintaxe Análise Gramatical Exercícios Propostos Características da linguagem P ASCAL jr Exercícios Propostos Análise Léxica O Papel do Analisador Léxico Buferização de Entrada Gramáticas e Linguagens Regulares Exercícios Propostos Especificação e Reconhecimento de Tokens Trabalho Prático # Análise Sintática O Papel do Analisador Sintático Análise Sintática Ascendente - BOTTOM UP Algoritmo Empilhar-e-Reduzir Análise Sintática Descendente - TOP DOWN Análise Sintática Preditiva Exercícios Propostos Reconhecedor de Gramáticas Preditivas Descendentes Algoritmo para Construção da Tabela de Análise Projeto de uma Gramática para um Analisador Sintático Preditivo Ascendente Projeto de uma Gramática para um Analisador Sintático Preditivo Descendente Exercícios Propostos Trabalho Prático # i

3 5 Análise Semântica Tradução Dirigida pela Sintaxe Definições L-Atribuídas Verificações de Contexto Tabela de Símbolos Atributos dos Nomes dos Identificadores Hashing Projeto das Regras Semânticas Trabalho Prático # Geração de Código Intermediário Linguagens Intermediárias Representações Gráficas Notação Pós (e Pré) Fixadas Código de Três-Endereços BackPatching (Retrocorreção) Otimização de Código Otimização Peephole Otimização de Blocos Sequenciais através de grafos Algoritmo para Construir o GAD de um bloco Algoritmo para Ordenação de um GAD Geração de Código Objeto Máquina Objeto Regras para Geração de Código Objeto Trabalho Prático # ii

4 Lista de Figuras 1.1 Processo de Compilação Fases da Compilação Árvore resultante da análise de um comando de atribuição em PASCAL Representação da árvore gramatical da produção A XYZ Ambigüidade Gramatical O papel do analisador léxico Buffer de entrada para um analisador léxico Autômato finito de reconhecimento de números inteiros e reais AFD de reconhecimento de identificadores simples AFD de reconhecimento de strings Exemplo de Árvore Sintática Derivação à Esquerda e à Direita Análise descendente com backtracking Exemplos de Recursão à Esquerda e à Direita Funcionamento de um Analisador Sintático Descendente Exemplo de Árvore Decorada para a Expressão 3* Grafo de Dependências Tipos Simples e Construtor de Tipos Hashing com Encadeamento Exemplo de Representação Gráfica de Operadores para a=b*c+b* Backpatching para expressões lógicas Grafo Acíclico Dirigido - GAD iii

5 Capítulo 1 Introdução Entende-se por linguagem como uma forma eficiente de comunicação entre pessoas. Na verdade a linguagem é um conjunto de palavras usadas, segundo certas regras, para a formação de frases compreensíveis por ambos os interlocutores (falantes). Quando um dos interlocutores é o computador, se faz necessário o uso de uma linguagem especial denominada linguagem de programação que permite a comunicação entre homem e máquina através da definição de comandos. Uma L. P. é ser dita de baixo nível, se esta somente aceitar comandos na própria linguagem da máquina (0 s e 1 s) que é de difícil aplicação. Já as linguagens ditas de alto nível, são representadas por ações próximas ao problema a ser resolvido que são, posteriormente, traduzidas para a linguagem de máquina, através de um agente especial denominado compilador ou interpretador. Concluindo: compilador é um programa capaz de traduzir um certo programa fonte (escrito em uma linguagem fonte) para outro programa objeto (escrito em uma linguagem objeto) geralmente a própria linguagem de máquina. 1.1 Evolução das Linguagens de Programação Cronologicamente, as L. P. s são classificadas em cinco gerações: (1 a ) linguagens de máquina; (2 a ) linguagens simbólicas (Assembly); (3 a ) linguagens orientadas ao usuário; (4 a ) linguagens orientadas à aplicação e (5 a ) linguagens de conhecimento. As duas primeiras são consideradas linguagens de baixo nível, enquanto que as demais de alto nível. Os primeiros computadores só podiam ser programados através da sua própria linguagem de máquina (código binário), onde cada operação possuía sua representação binária que era passada à máquina através de circuitos elétricos. Esse processo, além de extremamente difícil e cansativo, era altamente sujeito a erros devido a sua grande complexidade de execução. A seguir, como uma primeira tentativa de simplificação, surgem as linguagens simbólicas ou de montagem (Assembly). Agora, extensas seqüências binárias são substituídas por mnemônicos que são palavras especiais que representam certas ações básicas. Exemplo MOV, JMP, etc. Os mnemônicos precisavam ser traduzidos para a linguagem de máquina antes da sua execução. 1

6 A 3 a geração surgiu na década de 60, com as linguagens procedimentais como FOR- TRAN, PASCAL e ALGOL e declarativas como LISP e PROLOG. Nas linguagens procedimentais, um programa especifica uma seqüência de passos a serem seguidos para a solução do problema. Já as linguagens declarativas são subdivididas em funcionais e lógicas. A programação funcional se baseia na teoria das funções recursivas, enquanto que, as linguagens lógicas se baseiam em proposições da lógica de predicados (fatos e regras). Devido ao fato de programas escritos em linguagens de 3 a geração serem muito extensos e de difícil manutenção, surgiram as linguagens de aplicação (4 a geração), onde o desenvolvedor deixa de se preocupar com atividades secundárias e trata apenas da codificação do problema (foco do programador deixa de ser a codificação para ser a análise do problema). Aspectos como: interface de entrada e saída, relatórios, etc. são resolvidos pela própria linguagem através de um banco de dados e dicionários associados às aplicações desenvolvidas. A 5 a geração das linguagens de programação atua em problemas altamente complexos onde a representação de conhecimento se faz necessária para sua solução, como os problemas enfrentados pela inteligência artificial. A linguagem PROLOG é aceita como pertencente a esta geração. 1.2 Introdução à Compilação Conforme já dito, um compilador nada mais é do que um programa tradutor responsável por converter uma certa linguagem fonte em outra linguagem objeto (ver Figura 1.1). Usualmente a linguagem objeto é a própria linguagem de máquina, mas não necessariamente. Programa Fonte COMPILADOR Programa Objeto Mensagem de Erro Figura 1.1: Processo de Compilação Existem dois tipos básicos de tradutores: os compiladores e os interpretadores. Os primeiros fazem uma análise completa sobre o programa fonte, caso não encontre erros faz a tradução de todo o código fonte para a linguagem objeto que será posteriormente executado em uma máquina capaz de fazê-lo. Já os interpretadores não têm essa preocupação holística (análise completa) sobre o programa fonte. Um interpretador traduz um comando fonte por vez e o executa em uma máquina virtual (programa que simula o funcionamento de um computador) sem a necessidade da criação do programa objeto. Interpretadores são mais simples de serem implementados, porém, compiladores geram execuções mais rápidas de programas, pois não há a perda de tempo de traduções virtuais a cada nova instrução executada. 2

7 1.2.1 Fases da Compilação O processo de compilação pode ser dividido em dois grupos de etapas: as etapas de análise e as etapas de síntese. Na análise, o programa fonte é percorrido em busca de erros de programação (inconsistências com a linguagem fonte), já na etapa de síntese (após a verificação da corretude do programa de origem), efetua-se a tradução, propriamente dita, do código fonte para a linguagem objeto em questão. A figura 1.2 abaixo ilustra todo o processo: Programa Fonte Análise Léxica Análise Sintática ANÁLISE Tabela de Símbolos Análise Semântica Geração de Código Intermediário Manipulador de Erros Otimização de Código SÍNTESE Geração de Código Objeto Programa Objeto Figura 1.2: Fases da Compilação A análise léxica ou scanning é a primeira etapa do processo de compilação. Ela é responsável por analisar linearmente os caracteres do programa fonte e agrupá-los em unidades léxicas denominadas tokens. O token é o elemento mais básico da programação; ele é representado por um conjunto de caracteres que apresentam um significado claro para o programa. Exemplo: Para o seguinte código em PASCAL: Media := Nota1 + Nota2 * 2 Os caracteres poderiam ser agrupados da seguinte forma: 1. O identificador Media 2. O símbolo de atribuição := 3. O identificador Nota1 4. O sinal de adição + 5. O identificador Nota2 6. O sinal de multiplicação * 3

8 7. O número 2 Os espaços em branco presentes na sentença são ignorados durante a análise. O resultado da análise léxica é uma lista contendo todos os tokens encontrados no programa fonte. Essa lista léxica é então o elemento de entrada para a análise sintática ou análise gramatical (parsing), onde é verificado se os tokens podem ser agrupados em sentenças válidas (comandos, expressões, etc.) da linguagem fonte. Normalmente, esses agrupamentos são realizados através da construção de uma árvore sintática conforme é apresentado na figura 1.3: Comando de Atribuição Identificador Símbolo de Atribuição Expressão Media := Expressão Operador Aritmético Expressão Nota1 + Expressão Operador Aritmético Expressão Nota2 * 2 Figura 1.3: Árvore resultante da análise de um comando de atribuição em PASCAL A estrutura hierárquica de um programa é usualmente expressa por regras recursivas. Por exemplo, poderíamos ter as seguintes regras como parte definição de expressões: 1. Qualquer identificador é uma expressão 2. Qualquer número é uma expressão 3. Se expressão 1 e expressão 2 são expressões válidas, então expressão 1 op. aritmético expressão 2 também é A estrutura utilizada para a representação dessas regras é a gramática livre de contexto (GLC), normalmente apresentada na Forma Normal de Backus (BNF). Exemplo: comando ::= while atribuição... while ::= while expr bool do comando atribuição ::= identificador := expr aritm expr bool ::= expr aritm op.lógico expr aritm expr aritm ::= expr aritm op.aritm termo termo termo ::= número identificador Após a análise sintática, tem-se a certeza de que o programa está escrito corretamente (respeita as regras gramaticais da linguagem fonte), porém, será que o programa escrito faz algum sentido? Ou seja, executa de forma apropriada? 4

9 A análise semântica tem por objetivo validar os comandos e expressões através de análises como compatibilidade de tipos e escopo de identificadores. Esta etapa analisa, por exemplo, se um identificador declarado como variável é usado como tal, ou se uma expressão atribuída a uma variável retorna um tipo compatível com o qual foi declarada a variável (em algumas linguagens, uma variável inteira não pode receber uma expressão real). Até aqui foi realizada a etapa de análise do programa fonte, ou seja, a procura por erros de programação. Caso nenhum erro seja encontrado, o processo de compilação passa então para a etapa de síntese, ou seja, a construção do programa objeto. A geração do código intermediário é a primeira fase da construção do programa objeto. O que ela faz é a representação do programa fonte em uma linguagem intermediária simplificada (máquina abstrata), o que permite a realização da próxima etapa mais facilmente. A próxima etapa é a otimização de código, que tem por objetivo tentar modificar o código intermediário no intuito de melhorar a velocidade de execução, bem como a utilização do espaço de memória, fazendo com isso, um uso mais racional dos recursos da máquina. A última etapa do processo de compilação é a geração de código objeto propriamente dita. Esta fase tem como objetivos: produção de código objeto, reserva de memória para constantes e variáveis, seleção de registradores, etc. É a fase mais difícil, pois requer uma seleção cuidadosa das instruções e dos registradores da máquina alvo a fim de produzir código objeto eficiente. Exemplo de geração de código para o código fonte: While I < 100 do I := J + I Código Intermediário Otimização Código Objeto L0: if I<100 goto L1 L0: if I 100 goto L2 L0: MOV AX, I goto L2 I := J+I CMP AX, 100 goto L0 JGE L2 MOV AX, J MOV BX, I ADD BX MOV I, AX JMP L0 L1: Temp := J+I L2:... L2:... I := Temp goto L0 L2:... Além dessas fases, há também os módulos de gerenciamento de tabelas e manipulação de erros. O gerenciamento de tabelas consiste de um conjunto de tabelas e rotinas associadas que são utilizadas por quase todas as fases do tradutor. A principal estrutura deste módulo é a Tabela de Símbolos, que é responsável por armazenar informações acerca dos identificadores do programa sob análise, como por exemplo: declaração das variáveis, procedimentos e sub-rotinas, lista de parâmetros, etc.. 5

10 Os dados a serem armazenados dependem do projeto do tradutor, mas os mais comuns são: identificador, classe (variável, parâmetro, procedimento, etc.), tipo, endereço, tamanho. A tabela de símbolos deve ser estruturada de uma forma que permita rápida inserção e extração de informações, porém deve ser tão compacta quanto possível. O módulo de manipulação de erros tem por objetivo tratar os erros que são detectados em todas as fases de análise do programa fonte e deve dispor de mecanismos (recuperação de erros) que permitam que o processo de análise prossiga mesmo que erros tenham sido detectados. 1.3 Ferramentas para Geração de Compiladores Existem diversas ferramentas para auxiliar a construção de compiladores chamadas de geradores de compiladores ou sistemas de escritas de tradutores. A seguir são apresentados alguns exemplos: Geradores de Analisadores Gramaticais responsáveis por desenvolver analisadores sintáticos, normalmente a partir de entrada baseada numa gramática livre de contexto. Geradores de Analisadores Léxicos geram automaticamente analisadores léxicos a partir de uma especificação baseada em expressões regulares. Dispositivos de tradução dirigida pela sintaxe produzem coleções de rotinas que percorrem uma árvore gramatical, gerando código intermediário. Geradores automáticos de código tal ferramenta toma uma coleção de regras que definem a tradução de cada operação da linguagem intermediária para linguagem alvo. Tais regras precisam incluir detalhamento suficiente para que possamos lidar com os diferentes métodos de acesso possíveis para os dados. Dispositivos de fluxo de dados Ferramentas que auxiliam na etapa de otimização de código. Não é de escopo desta disciplina o estudo de ferramentas de implementação de compiladores, mais detalhes podem ser obtidos na bibliografia de apoio. 6

11 Capítulo 2 Um Compilador Simples de uma Passagem 2.1 Definição da Sintaxe A especificação da sintaxe de uma linguagem de programação pode ser obtida através de uma gramática livre de contexto. Exemplo: Seja o comando condicional da forma: IF Expressão THEN Comando ELSE Comando se Expr denotar a construção de uma expressão e Cmd denotar um comando (ou enunciado), pode-se usar as regras de produção de uma GLC 1 para representar tal estrutura da seguinte forma: < Cmd > IF < Expr > THEN < Cmd > ELSE < Cmd > as palavras-chave como IF, THEN e ELSE representam os símbolos terminais, enquanto que os termos Cmd e Expr, representam os não-terminais. Exemplo de uma GLC simples para definir expressões aritméticas baseadas apenas em adição e subtração: < Lista > < Lista > + < Digito > < Lista > < Lista > < Digito > < Lista > < Digito > < Digito > onde os símbolos 0 a 9 e + ou - são os elementos terminais, enquanto que Lista e Digito representam os não-terminais. Convencionalmente, o primeiro não-terminal representa o axioma da gramática. Expressões exemplo: 1+1, 3-6+9, Gramática Livre de Contexto 7

12 2.2 Análise Gramatical A análise gramatical é feita através de derivações de cadeias a partir do axioma da gramática. Se um não-terminal A possui uma produção A XYZ então, uma árvore gramatical pode ter um nó rotulado de A com 3 filhos X, Y e Z da esquerda para a direita, conforme a figura 2.1. A X Y Z Figura 2.1: Representação da árvore gramatical da produção A XYZ Formalmente, segundo uma GLC, a árvore gramatical resultante apresenta as seguintes propriedades: A raiz é rotulada pelo símbolo de partida (axioma); Cada folha é rotulada por um terminal ou por ε; Cada nó interno é rotulado por um elemento não-terminal; Se A X 1 X 2... X n é uma produção então, algum nó interno da árvore será rotulado por A sendo X 1 X 2... X n os rótulos dos filhos desse nó. Ambiguidade Uma gramática pode ter mais de uma árvore gramatical gerando uma dada cadeia, neste caso, ela é dita ser ambígua. Ambos os exemplos da figura 2.2 geram a sentença Cadeia Cadeia Cadeia + Cadeia Cadeia - Cadeia Cadeia - Cadeia 2 9 Cadeia + Cadeia Figura 2.2: Ambigüidade Gramatical 8

13 Associatividade de Operadores Convencionalmente, é equivalente à (9+5)+2, pois, ao analisarmos o operando 5 precisamos decidir qual operação será realizada primeiro. Pela convenção da matemática a adição é associativa à esquerda, sendo assim o resultado (9+5)+2 é obtido. Na maioria das linguagens de programação, as quatro operações básicas (adição, subtração, multiplicação e divisão) são associativas à esquerda. A exponenciação é um exemplo de operador associativo à direita (em Fortran) 5**2**3 é equivalente a 5**(2**3). Outro exemplo é o operador de atribuição, onde a expressão a=b=c (em linguagem C) é tratada como a=(b=c). Precedência de Operadores Considere a expressão Existem duas interpretações possíveis: (9+5) 2 e 9+(5 2). Quando mais de um tipo de operadores estiverem presentes em uma expressão é necessário se definir a ordem de precedência entre eles. Na aritmética, os operadores e / tem precedência mais alta do que + e -; assim, na expressão anterior o operador de multiplicação é capturado antes da adição Exercícios Propostos 1. Prova, através da construção da árvore de derivação, que os exemplos anteriores são válidos para a gramática de expressões aritméticas vista. 2. Considere a gramática livre de contexto: S SS+ SS a (a) Mostre que a cadeia aa+a pode ser gerada por esta gramática. (b) Construa a árvore gramatical para esta cadeia. (c) Qual é a linguagem gerada por esta gramática? Justifique sua resposta. 3. Quais são as linguagens geradas pelas seguintes gramáticas? (a) S 0S1 01 (b) S +SS -SS a (c) S S(S)S ε (d) S asbs bsas ε (e) S a S+S SS S* (S) 4. Construa uma gramática livre de contexto para os números romanos (1 a 10). 5. Construa uma G.L.C. para as expressões aritméticas de inteiros e identificadores com as quatro operações básicas (+, -,, /). 9

14 2.3 Características da linguagem P ASCAL jr 1. Não é caso sensitivo ( A = a ) 2. Suporta os tipos: integer, real, char, string e boolean 3. Comandos: Atribuição com operadores: :=, +=, -=, *=, /=, ++, - - Entrada com o comando read( ) Saída com os comandos write( ) e writeln() Condicional com o comando if - then - else Repetições: Pré teste com o comando while - do Pós teste com o comando repeat - until Contada com o comando for - to - do Sub-rotinas através dos comando procedure e function. Retorno de funções com o comando result Nome de identificador de subrotinas inicia obrigatoriamente com (ex.: Tela) 4. Constantes caracteres delimitados por ( ) e constantes strings por ( ) 5. Operadores relacionais: =, >=, <=, >, <, <> 6. Operadores lógicos and, or, xor (ou exclusivo), not 7. Operadores aritméticos: +, -, *, /, ** (potenciação) 8. Suporta operadores ternários: Expr? valor1 : valor2 9. Precedência de operadores: (a) =, +=, -=, *=, /=, ++, - - (b) and, or, xor (c) =, >=, <=, >, <, <> (d) not (e) +, - (f) *, / (g) ** (h) ( ) (i) Símbolos especiais:,, :, ;, (, ),. 10

15 11. Bloco de comandos delimitados por begin e end 12. Comentário de linha com operador // 13. Comentário de bloco com os delimitadores { e } 14. Lista de Palavras Reservadas: var, const, while, do, for, read, write, writeln, if, then, else, true, false, integer, real, char, string, boolean, result, procedure, function,and,or,xor,not,to,repeat,until,program,downto Exemplos de programas a serem reconhecidos pela linguagem P ASCAL jr : { } PILOTO.TXT Exemplo completo de programa na linguagem PASCALjr Desenvolvido por Rogerio Eduardo da Silva Agosto, 2005 Program Piloto; // declaraç~oes de variaveis e constantes globais var: integer cont; real Nota1, Nota2, Media_das_medias, med; const: integer total = 10; // Subrotina de preenchimento de tela procedure _Tela() begin writeln("******** ENTRADA DE DADOS ***************"); writeln("digite os valores da entrada:"); end; // Calculo da media aritmetica entre duas notas func real _Media(real a, b) var: real media; begin media := (a+b)/2.0; result := media; end; // Inicio do Programa Principal begin Media_das_medias := 0; for cont=0 to total do begin _Tela(); read(nota1, Nota2); med := _Media(Nota1, Nota2); Media_das_medias += med; 11

16 write("media = ",med); end; write("media Geral = ",Media_das_medias/total); end Exercícios Propostos Usando a linguagem P ASCAL jr faça: 1. Um programa para cálculo do fatorial de N. 2. Um programa para cálculo de N-ésimo termo da série de Fibonacci 12

17 Capítulo 3 Análise Léxica 3.1 O Papel do Analisador Léxico A análise léxica é a primeira fase de um compilador e tem por objetivo fazer a leitura do programa fonte, caracter a caracter, e traduzi-lo para uma seqüência de símbolos léxicos denominados tokens, os quais são utilizados pelo analisador sintático. Exemplos de tokens são os identificadores, palavras reservadas, operadores da linguagem, etc. A interação entre análise léxica e sintática é normalmente implementada fazendo-se com que o analisador léxico seja uma sub-rotina ou co-rotina do parser (ver figura 3.1). Ao receber do parser um comando do tipo obter próximo token, o analisador léxico lê os caracteres de entrada até que possa identificar o próximo token. Programa Fonte Analisador Léxico Token Obter Próximo Token Analisador Sintático Tabela de Símbolos Figura 3.1: O papel do analisador léxico Um analisador léxico clássico pode ser entendido como um sistema de estados finitos e, portanto, utiliza-se um autômato finito para sua implementação. As principais características desse autômato: O alfabeto de entrada são os caracteres pertencentes ao arquivo fonte Cada estado final reconhece uma classe específica de tokens da linguagem fonte É denominado erro léxico a qualquer evento (durante o processo de análise léxica) que impossibilite a interpretação de um token. Uma lista de tokens é o resultado do processo de análise léxica, caso nenhum erro léxico tenha sido encontrado. 13

18 Porque efetuar análise léxica? Simplificação de Projeto é mais simples implementar dois analisadores distintos (para tarefas distintas) do que um analisador sintático que faça todo trabalho de forma unificada; Melhor Eficiência a análise léxica é potencialmente mais lenta que a sintática (pois efetua leitura de caracteres em disco). Técnicas de buferização de leitura podem acelerar significativamente este processo; Portabilidade as peculiaridades do alfabeto de entrada de cada linguagem podem ser tratadas exclusivamente pelo scanner. Tokens, Padrões e Lexemas Um token é um símbolo terminal da gramática da linguagem fonte sob análise. Em geral, existem diversas cadeias de caracteres para as quais o mesmo token é gerado. Essas cadeias respeitam um determinado padrão ou regra associada a esse token. Um lexema é um conjunto de caracteres que é reconhecido pelo padrão de um determinado token. Exemplo: const pi = ; a subcadeia pi é um lexema para o token identificador, pois respeita o padrão para os identificadores (letra)(letra digito). Atributos para os tokens Um token é comumente representado como um par [LEXEMA, CLASSE], onde a classe indica qual foi o padrão utilizado para reconhecer o lexema. Outras informações adicionais podem ser incorporadas à descrição do token, de acordo com as necessidades das fases subseqüentes, como por exemplo, número da linha e coluna onde o token foi reconhecido no arquivo fonte e número de caracteres lidos até o reconhecimento, seria exemplos de informações adicionais úteis caso um erro léxico seja detectado. 3.2 Buferização de Entrada Conforme já visto, o processo de análise léxica é normalmente realizado efetuando-se uma leitura do arquivo fonte de entrada, caracter a caracter, o que resulta em um processo significativamente lento. Existem 3 alternativas de implementação de analisadores léxicos (listados em ordem crescente de complexidade de implementação): 1. Usar ferramentas de construção de analisadores léxicos (como o Lex), através de expressões regulares; 14

19 2. Escrever um programa numa linguagem de programação convencional, usando seus recursos de entrada e saída; 3. Escrever um programa numa linguagem de montagem e manipular explicitamente a entrada e a saída. Alguns aspectos a serem considerados no projeto de implementação de um scanner: Buffer Em muitas linguagens, existem momentos que o analisador léxico precisa examinar vários caracteres à frente do lexema, antes que seja anunciado um reconhecimento. Os caracteres que foram lidos e não foram aproveitados no lexema sob análise, são então, devolvidos ao fluxo de entrada para que possam ser lidos novamente na análise de outro lexema posterior. Assim sendo, um buffer de entrada que acumula vários caracteres é criado, conforme a figura 3.2. O processo de análise léxica é realizado sobre este buffer. Os tokens que foram reconhecidos são eliminados do buffer e novos caracteres são adicionados a ele até que todo o arquivo fonte seja lido e analisado. E = m * c * c eof apontador Figura 3.2: Buffer de entrada para um analisador léxico Em casos mais simples, a entrada pode ser realizada caracter a caracter, contendo apenas um buffer de armazenamento dos caracteres lidos. 3.3 Gramáticas e Linguagens Regulares A seguir, serão revisados alguns conceitos importantes da disciplina linguagens formais e máquinas (LFM) para então prosseguir na análise léxica. Gramática Uma gramática é um mecanismo gerador de sentenças de uma dada linguagem. É definida pela quádrupla (V N, V T, P, S), onde: V N representa o conjunto de símbolos não-terminais da linguagem; V T representa o conjunto de símbolos terminais ou alfabeto; P é um conjunto de regras de produção e S é o axioma da gramática (símbolo inicial). As regras de produção são definidas na forma α β 1 β 2... β N, onde α representa um símbolo não-terminal e os β N representam sentenças podendo conter tanto símbolos terminais quanto não-terminais. 15

20 Seqüência de Derivação Entende-se por derivação ao processo de substituição de α por um dos β N na regra de produção, desta forma obtendo-se uma nova sentença que por sua vez, pode ser novamente derivada por outra regra. Uma seqüência de derivação é uma série de derivações sucessivas que permitem a geração de uma determinada sentença da linguagem. Gramática Regular Uma gramática é dita ser regular se todas as suas regras de produção respeitam a forma A αb ou A α, onde A,B são símbolos não-terminais e α é uma sentença contendo somente símbolos terminais. Gramática Linearmente à Esquerda e à Direita Quando uma regra de produção é da forma A αb, ou seja, novos símbolos não-terminais são inseridos à direita da sentença, diz-se se tratar de uma gramática linearmente à direita. Se a produção for da forma A Bα denomina-se como linearmente à esquerda. Expressões Regulares Uma expressão regular representa uma determinada linguagem através de fórmulas indutivas. Simbologia adotada: ε = sentença vazia (comprimento = 0); a b = representa uma seleção entre a sentença a ou b; A = conjunto de todas as sentenças de comprimento 0 sobre A; A + = A {ε} = fechamento positivos sobre A A? = representa que a expressão A ocorre zero ou uma vez. Exemplos: Digito(Digito) = representa a descrição de números inteiros. Letra(Letra Digito) = representa a descrição de identificadores Exercícios Propostos 1. Defina expressões regulares e sua respectiva gramática regular para as seguintes linguagens: todas as palavras contendo a e/ou b. todas as palavras contendo a e/ou b com sufixo aa. todas as palavras contendo a e/ou b com aaa como sub-palavra. todas as palavras contendo a e/ou b com exatamente dois b. 2. Para a gramática G=({S,A,B},{0,1},P,S), indique a linguagem reconhecida. 16

21 P: S 0S A A A1 B B 0 1 ε 3.4 Especificação e Reconhecimento de Tokens A especificação de tokens é feita através de expressões regulares e reconhecida através dos reconhecedores de gramáticas regulares chamados de autômatos finitos. Exemplo: < Numero > < Digitos >< Frac Opc >< Exp Opc > < Frac Opc >. < Digitos > ε < Exp Opc > (E e)(+ ε) < Digitos > ε < Digitos > < Digito >< Digitos > < Digito > < Digito > esta gramática é capaz de reconhecer números inteiros como 1, 100, 1234, etc. e também números reais expressos ou não por notação exponencial como: 1.5, 10.34, 1.3e15, 1E+2; porém, é incapaz de reconhecer números como 1., sem a parte fracionária. A figura 3.3 reconhece esta gramática, enquanto que a figura 3.4 reconhece identificadores simples 1. OUTRO INICIO DÍGITO DÍGITO DÍGITO 0 1 DIGITO. 2 DIGITO 3 E e DIGITO 6 OUTRO 7 * Retornar(Num_Real, Obter_Token()) OUTRO E e DIGITO 8 * Retornar(Num_Inteiro, Obter_Token()) Figura 3.3: Autômato finito de reconhecimento de números inteiros e reais O reconhecimento de strings é apresentado na figura 3.5, onde caracteres válidos representa o alfabeto válido para strings, geralmente letras, números, espaços e sinais ortográficos. Exercício: Criar um AFD capaz de reconhecer os tokens da linguagem P ASCAL jr : símbolos (Dois Pontos, Ponto e Vírgula, Vírgula, Abre e Fecha Parênteses, Atribuição), Operadores Relacionais e Aritméticos, Constante Caracter e identificadores de sub-rotinas 1 Exceto identificadores de sub-rotinas 17

22 INICIO LETRA OU DÍGITO LETRA OUTRO * Retornar(ID, Obter_Token()) Figura 3.4: AFD de reconhecimento de identificadores simples INICIO CARACTERES VÁLIDOS " 0 1 " 2 Retornar(String,Obter_Token()) Figura 3.5: AFD de reconhecimento de strings (iniciam obrigatoriamente com e tem pelo menos 2 caracteres), e ainda, ser capaz de tratar os caracteres nulos: espaços, enter, tab e comentários, sem reconhecer token. Reconhecendo palavras reservadas como identificadores simples: Criar uma função de identificação de palavras reservadas (enumeração) que retorna a classe palavra reservada ou identificador. USO: Retornar(ObterClasse(Lexema),Lexema) Erros Léxicos 1. Caracter Inválido : uso de um caracter (simbolo) de entrada (arquivo fonte) que não pertença ao alfabeto da linguagem. Exemplo: # ou % 2. Delimitador Não Balanceado : definição de uma cadeia literal (ou constante caracter) sem o correto balanceamento das aspas. Exemplo: Entrada de Dados 3. Número Real Inválido : definição incorreta ou incompleta de um número real. Exemplos: 1., 1.0e3,.8, 1e+ O código abaixo apresenta algum erro léxico? Apresente a lista léxica. begin ; <>media==10.5e-5 /===//%_ Média 1.P Teste? Solução: begin Palavra Reservada ; Símbolo Ponto e Virgula 18

23 <> Operador Relacional Diferente media Identificador = Operador Relacional de Igualdade = Operador Relacional de Igualdade 10.5E-5 Número Real /= Símbolo de Atribuição = Operador Relacional de Igualdade = Operador Relacional de Igualdade Teste Identificador? Símbolo Interrogação Trabalho Prático #1 Implementar um módulo (sub-rotina) analisador léxico para um protótipo de compilador para a linguagem P ASCAL jr vista em aula. Características: Do módulo scanner: A sub-rotina retorna um token (classe e lexema) cada vez que for chamada. Considera que o programa fonte para análise já está aberto. Não retorna nada quando atingir o fim de arquivo (flag de controle). Implementa um AFD para o reconhecimento de tokens. Do programa a ser criado: Abre um arquivo fonte para análise. Chama (sucessivas vezes) a rotina de scanner e exibe o valor do token. Fecha o arquivo fonte ao final da compilação. Pára o processo de compilação caso um erro seja encontrado. Exibe erros de compilação (se ocorrerem) ou mensagem de sucesso. Critérios de Avaliação: Implementação usando linguagem C ou C++. Entrega de fontes e executável (em um arquivo zipado) via disquete/cd ou rsilva@joinville.udesc.br ou professor.rogerio@gmail.com 19

24 Grupo de 02 alunos (máximo). Valor do trabalho: 10.0 (25% da nota prática). Data de Entrega: A Definir Punições: de 10% por cada análise incorreta. de 20% do valor do trabalho por dia de atraso. de 20% do valor do trabalho para a entrega não conforme dos arquivos pedidos. de 50% do valor do trabalho para o caso de não executar ou travar (após teste em 2 computadores, sendo um o do professor). de 100% do valor do trabalho para o caso de cópias (mesmo de trabalhos de semestres anteriores). Prazo máximo para defesa e arguição sobre o trabalho: 5 dias letivos após entrega. Punições: de 25% para arguição não respondida ou respondida incorretamente. Obs.: A arguição é individual. de 33% ponto por dia de atraso da defesa. 20

25 Capítulo 4 Análise Sintática 4.1 O Papel do Analisador Sintático A análise sintática constitui a segunda etapa de um tradutor. Sua função é verificar se as construções usadas no programa estão gramaticalmente corretas. Normalmente, as estruturas sintáticas válidas são especificadas através de uma gramática livre de contexto. Dada uma GLC e uma sentença (programa fonte) s, o objetivo do parser é verificar se s pertence a GLC, através da construção de uma árvore de derivação. O processo de construção dessa árvore pode ser feito de forma explícita (construindose o TDA) ou implícita, através de chamadas recursivas das rotinas que aplicam as regras de produção da gramática durante o reconhecimento. Existem duas estratégias básicas: Descendente (Top-Down) e Ascendente (Bottom- Up). Na estratégia top-down constrói-se a árvore a partir da raiz em direção às folhas (tokens), enquanto que na bottom-up, o processo é invertido e a construção é realizada partindo-se das folhas, agrupando-se os tokens até que a raiz da árvore seja gerada. A árvore gramatical é então a saída para as próximas fases da compilação. Revisão sobre Gramáticas Livre de Contexto (GLC) Uma gramática livre de contexto é qualquer gramática da forma: A α, onde A é um símbolo não-terminal e α um elemento pertencente a (V N V T ). Exemplo de produções de uma G.L.C.: S SS+ SS a. Árvores de Derivação Árvore de derivação é a representação gráfica de uma derivação de sentença. Exemplo: Considerando a gramática abaixo, gerar árvore de derivação que comprova que a sentença 45 é válida (ver Figura 4.1). 21

26 < Numero > < Num > < Num > < Num >< Digito > < Digito > < Digito > <Numero> <Num> <Num> <Digito> <Digito> 5 4 Figura 4.1: Exemplo de Árvore Sintática Derivação mais à Esquerda e mais à Direita Derivação mais à esquerda é obtida por gramáticas que geram inicialmente, os símbolos mais à esquerda da sentença sob análise; analogamente para as derivação mais à direita. Exemplo: Seja a gramática: E E + E E E E E E/E (E) x. Pode obter a expressão x+x*x de duas formas, conforme a figura 4.2: E E E * E E + E E + E X X E * E X X X X Figura 4.2: Derivação à Esquerda e à Direita Exercício: Para a gramática G = ({S,A},{0,1},P,S) sendo P: S 0S A A 1A 1, provar as seguintes sentenças: 0001, 01,

27 4.2 Análise Sintática Ascendente - BOTTOM UP A criação da árvore gramatical é realizada no sentido folhas raiz, ou seja, geração de sentenças é feita através do processo de empilhar e reduzir. A idéia é reduzir a sentença original até o axioma da gramática através de sucessivas substituições por não-terminais. Exemplo: S aabe A Abc b B d Verificar se a sentença abbcde pode ser reduzida pela gramática: abbcde aabcde aade aabe S Algoritmo Empilhar-e-Reduzir Este procedimento de análise sintática ascendente consiste de dois passos: 1. Escolha de um candidato α a redução (handle); 2. Redução do candidato pelo não-terminal A à esquerda da produção A α; 3. Repetir os passos 1 e 2 até que a sentença tenha sido reduzida ao axioma da gramática. Um candidato é uma subcadeia que reconhece o lado direito de uma produção e cuja redução ao não-terminal do lado esquerdo da produção representa um passo ao longo do percurso de uma derivação. É denominado de poda do candidato ao processo de substituí-lo pelo não-terminal à esquerda da regra de produção, obtendo desta forma, uma redução na sentença sob análise. Uma forma conveniente de implementar um analisador sintático de empilhar e reduzir é usar uma pilha para guardar os símbolos gramaticais. O analisador sintático opera empilhando zero ou mais símbolos até que um candidato surja no topo da pilha. Uma poda do candidato é então feita. Repete-se este processo até que no topo da pilha esteja o axioma da gramática ou um erro seja encontrado (nenhuma poda seja possível). Exemplo: E E + E E E E E E/E (E) id. Sentença sob análise: id + id * id 23

28 Entrada Pilha Ação id+id*id $ empilhar +id*id $id reduzir E id +id*id $E empilhar id*id $E+ empilhar *id $E+id reduzir E id *id $E+E reduzir E E + E *id $E empilhar id $E* empilhar $ $E*id reduzir E id $ $E*E reduzir E E E $ $E aceitar São apenas 4 as operações possíveis por este método: empilhar, reduzir, aceitar ou erro. Conflitos durante a Análise Sintática de Empilhar e Reduzir Existem gramáticas livres de contexto para as quais o procedimento empilhar-e-reduzir não pode ser utilizado, porque, em certos casos, o analisador pode atingir um estado tal, que: Mesmo conhecendo toda a pilha e o próximo símbolo de entrada, não pode decidir entre empilhar e reduzir. Isto é chamado de conflito empilhar/reduzir. Outro conflito possível, o reduzir/reduzir, ocorre quando não é possível optar entre as diversas reduções possíveis. 4.3 Análise Sintática Descendente - TOP DOWN A análise sintática top-down pode ser vista como uma tentativa de se encontrar uma derivação mais à esquerda para uma cadeia de entrada, ou ainda, como de se construir a árvore gramatical a partir da raiz em direção às folhas. O processo de análise pode ser feito de forma recursiva ou não, onde a forma recursiva pode ser realizada com ou sem retrocesso (backtracking), dependendo das regras de produção gramática. Análise Sintática Recursiva com Retrocesso A construção da árvore é feita a partir da raiz, expandindo sempre o não-terminal mais à esquerda primeiro. Quando existe mais de uma regra de produção para o não-terminal a ser expandido, a opção escolhida é função do símbolo corrente na fita de entrada (token sob análise). Se o token não define a produção a ser usada, então todas as alternativas vão ser tentadas até que se obtenha sucesso (ou todas falhem). Exemplo 1:S cad A ab a. Verificar se a gramática gera a sentença cad. Exemplo 2: S ca A ab B D bd D d 24

29 S c A d falha! S S a b c A d S c A d sucesso! a Figura 4.3: Análise descendente com backtracking A análise sintática é dita ser uma análise sintática preditiva caso não seja necessário a realização de retrocesso no processo e pode ser implementada de forma recursiva ou não (através da utilização de uma pilha) Análise Sintática Preditiva O processo de análise preditiva (sem retrocesso) exige modificações na gramática original para análise: eliminação de recursão à esquerda; fatoração à esquerda das regras de produção; os não-terminais que apresentarem mais de uma regra de produção, tenham o primeiro terminal derivável único (capaz de identificar a produção a ser analisada). Ou seja, deve ser possível determinar, para um dado símbolo a, qual das produções deve ser derivada. Exemplo: No exemplo 2 visto acima a produção B D bd D d apresenta duas alternativas de derivação. A escolha é feita a partir do primeiro terminal para cada regra (d ou b). O conjunto de símbolos terminais que iniciam sentenças deriváveis a partir de uma produção b é denominado FIRST(β) ou PRIMEIRO(β). Exemplo: FIRST(S) = {c}; FIRST(A) = {a}; FIRST(B) = {b, d}; FIRST(D) = {d}. As regras que definem o conjunto FIRST são: 25

30 Se β ε, então ε é um elemento de FIRST. Se β aδ, sendo a um símbolo terminal, então a pertence a FIRST. Se β X 1 X 2... X N, sendo X 1 X 2... X N elementos não-terminais, então FIRST(β) = FIRST(X 1 ). Se em FIRST(X 1 ) constar o elemento ε, então incluir FIRST(X 2 ) em FIRST(β) e assim por diante. Eliminação da Recursão à Esquerda É possível que um analisador gramatical descendente recursivo execute indefinidamente. O problema ocorre em produções recursivas à esquerda, tais como: A A0 1. Este tipo de produção gera uma árvore que cresce recursivamente à esquerda até que um terminal 1 seja gerado à esquerda da seqüência de 0 s. Para se evitar isso deve-se substituir o elemento causador da recursão à esquerda, que é do tipo A Aα β, onde α, β representam outras seqüências de terminais e não-terminais não iniciadas por A. Para eliminar a recursão à esquerda deve-se reescrever essa produção, da seguinte forma: A βa e A αa ε. A figura 4.4 apresenta as árvors de derivação para uma sentença qualquer da forma βαααα Exercícios Propostos Para as gramáticas abaixo elimine sua recursão à esquerda. 1. G=({S,A,B},{a,b},P,S) onde P: S Sa Sb A B A Aa a B bb b 2. G=({S,A},{0,1,2},P,S) onde P: S S0 S1 A 0 A S2 3. G=({S,A,B},{0,1},P,S) onde P: S SA A A A0B 0 B B1 ε 4. G=({A},{0,1},P,A) onde P: A A0A 1 Apresente a cláusula First para as produções das gramáticas abaixo: 1. G=({S,X,Y,Z},{0,1,2,3},P,S) onde P: S XY Z X OXO 1 Y 2Y 2 3 Z 0Z1 ε 2. G=({S,A,B,C},{a,b,c},P,S) onde P: S Sa aa A aa Bb B cb ε 3. G=({S,X,Y,Z},{0,1},P,S) onde P: S XY Z X 0X 1Y ε Y 1Y ε Z 01Z ε Fatoração à Esquerda A fatoração à esquerda é uma transformação gramatical útil para a criação de uma gramática adequada à análise sintática preditiva. A idéia básica está em, quando não estiver claro qual das duas produções alternativas usar para expandir um não-terminal A, estarmos capacitados a reescrever as produções A e postergar a decisão até que tenhamos visto o suficiente da entrada para realizarmos a escolha certa. Exemplo: S axby cz axby 26

31 A A A β A α A α A α α β α A' A' α A' α A' α A' ε Figura 4.4: Exemplos de Recursão à Esquerda e à Direita Ao analisarmos o token a não há como saber qual das duas alternativas utilizar (o comando com ou sem o cz ). Quando houver duas produções A αβ 1 αβ 2, devemos postergar a decisão expandindo A para αa e então expandir A para β 1 β 2. Fatorando esta gramática temos: S axby S S cz ε. 4.4 Reconhecedor de Gramáticas Preditivas Descendentes Um reconhecedor preditivo descendente (orientado por tabela) compreende uma fita de entrada, uma pilha e uma tabela de análise, conforme é mostrado na figura 4.5. A fita contém a sentença a ser analisada seguida de $. A pilha contém os símbolos utilizados durante o processo de análise. A tabela de análise é uma matriz com n linhas (correspondendo aos símbolos não-terminais) e t+1 colunas (correspondendo aos símbolos terminais mais o símbolo especial $). Considerando X o elemento no topo da pilha e a o símbolo de entrada sob análise, o analisador executa uma de três ações possíveis: 1. se X = a = $, o analisador pára, aceitando a sentença; 2. se X = a $, o analisador desempilha a e avança o cabeçote de leitura para o próximo símbolo na fita de entrada; 3. se X é um símbolo não-terminal, o analisador consulta a tabela M[X,a] da tabela de análise. Essa entrada poderá conter uma produção da gramática ou ser vazia. Supondo M[X,a] = { X XY Z }, o analisador substitui X (no topo da pilha) por ZYX (ficando X no topo). Se M[X,a] for vazio isto é um erro sintático. Na implementação de um analisador sintático, a maior dificuldade está na construção da tabela de análise. Para construir essa tabela, é necessário computar duas funções associadas à gramática: FIRST e FOLLOW. 27

32 a + b $ X Y Z Parser Tabela de Análise Figura 4.5: Funcionamento de um Analisador Sintático Descendente O algoritmo para calcular a função FIRST já foi visto anteriormente. O algoritmo para calcular a função FOLLOW é apresentado a seguir: 1. Se S é o símbolo inicial da gramática e $ é o marcador de fim de sentença, então $ está em FOLLOW(S); 2. Se existe produção do tipo A αxβ, então todos os terminais de FIRST(β), fazem parte de FOLLOW(X); 3. Se existe produção do tipo A αx, ou A αxβ, sendo que β ε, então todos os terminais que estiverem em FOLLOW(A) fazem parte de FOLLOW(X). Dada a gramática G = ({E, E, T, T, F }, {,,, id}, P, E) para expressões lógicas: Cláusula First E T E E T E ε T F T T F T ε F F id Convém iniciar o processo pelos não-terminais que gerem conjuntos triviais. No exemplo, temos os não-terminais F, E e T que só geram elementos terminais (ou vazio): F = {, id} E = {, ε} T = {, ε} Como T deriva apenas em FT e F não leva em vazio, conclui-se que FIRST(T) = FIRST(F). E ainda, FIRST(E) = FIRST(T) = FIRST(F) = {, id}. 28

33 Cláusula Follow Pela regra 1 temos que FOLLOW(E) = {$}. Pela regra 3 tem-se que FOLLOW(E) = FOLLOW(E ). FOLLOW(T) é obtido a partir da união dos conjuntos obtidos pela aplicação da regra 2 em (E T E ) e regra 3 em (E ε). Sendo assim temos: FOLLOW(T) = FIRST(E ) + FOLLOW(E ) = {, $}. FOLLOW(T ) = FOLLOW(T) pela aplicação da regra 3 em T F T. E finalmente, FOLLOW(F) = FIRST(T ) + FOLLOW(T ). Aplicação das regras 2 e 3 em T F T ε, ou seja FOLLOW(F) = {,, $} Algoritmo para Construção da Tabela de Análise Método: Para cada produção X α, execute os passos 2 e 3 (para criar a linha X da tabela M); Para cada terminal a de FIRST(α), adicione a produção X α a M[X,a]; Se FIRST(α) inclui a palavra vazia, então adicione X α a M[X,b] para cada b em FOLLOW(X); Aplicando-se o algoritmo acima à gramática de expressões lógicas temos: Para E T E tem-se FIRST(TE ) = {, id} então, M[E, ] = M[E,id] = E T E. Para E T E tem-se FIRST( T E ) = { } então, M[E, ] = E T E. Para E ε tem-se FOLLOW(E ) = {$} então, M[E, $] = E ε. Para T F T tem-se FIRST(FT ) = {, id} então, M[T, ] = M[T,id] = T F T. Para T F T tem-se FIRST( F T ) = { } então, M[T, ] = T F T. Para T ε tem-se FOLLOW(T ) = {, $} então, M[T, ] = M[T,$] = T ε. Para F F tem-se FIRST( F ) = { } então, M[F, ] = F F. Para F id tem-se FIRST(id) = {id} então,m[f,id] = F id. id $ E E T E E T E E E T E E ε T T F T T F T T T ε T F T T ε F F id F id Se, em cada entrada da Tabela de Análise, existe apenas uma produção, então a gramática que originou a tabela é dita ser do tipo LL(1), ou seja: as sentenças geradas pela gramática são passíveis de serem analisadas da esquerda para a direita (Left to Right), produzindo uma derivação mais à esquerda (Leftmost Derivation), levando em conta apenas um símbolo da entrada. Exercício: Considerando a gramática para a linguagem a ser reconhecida pelo protótipo de compilador para análise descendente, construir a tabela de análise resultante. 29

34 4.4.2 Projeto de uma Gramática para um Analisador Sintático Preditivo Ascendente Analisa gramáticas do tipo LR(k), ou seja, left-to-right e rightmost derivation com k símbolos lidos da entrada a cada etapa de análise. Porque usar análise sintática ascendente LR? porque é possível ser elaborados reconhecedores para todas as GLC, sem restrição; porque o método de análise LR é tão eficiente quanto os demais métodos de análise; porque um analisador LR consegue encontrar um erro sintático o mais cedo possível em uma análise da esquerda para a direita. As gramáticas GLC para as quais é viável a implementação manual de reconhecedores ascendentes (devido à complexidade de implementação) apresentam as seguintes restrições: nenhum lado direito das produções seja ε nenhum lado direito tenha dois não-terminais adjacentes (gramática de operadores) Exemplo: E E + E E E E E E/E (E) E id Um forma simples de se implementar um reconhecedor ascendente é através da análise de precedência de operadores, porém, justamente devido à sua simplicidade, uma série de restrições estão associadas a estes: dificuldades de analisar operadores com mais de um significado semântico (ex.: operador unário e binário de subtração) somente uma pequena classe de linguagens pode ser analisada por esta alternativa, apesar disso, já foram desenvolvidos analisadores de precedência para linguagens inteiras. Na análise de precedência temos definidos as relações de precedência entre os operadores, sendo (a < b) onde a confere precedência a b; (a = b) onde a possui a mesma precedência de b e (a > b) a tem precedência sobre b. Seja o exemplo da gramática anterior onde a precedência dos operadores é dada por: id + * $ id > > > + < > < > * < > > > $ < < < Analisando a expressão: id+id*id temos as seguintes relações de precedência: $ < id > + < id > < id > $ O algoritmo para se determinar o handle para redução é: 30

Tokens, Padroes e Lexemas

Tokens, Padroes e Lexemas O Papel do Analisador Lexico A analise lexica e a primeira fase de um compilador e tem por objetivo fazer a leitura do programa fonte, caracter a caracter, e traduzi-lo para uma sequencia de símbolos lexicos

Leia mais

Compiladores. Análise Sintática

Compiladores. Análise Sintática Compiladores Análise Sintática Cristiano Lehrer, M.Sc. Introdução (1/3) A análise sintática constitui a segunda fase de um tradutor. Sua função é verificar se as construções usadas no programa estão gramaticalmente

Leia mais

Compiladores. Exemplo. Caraterísticas de Gramáticas. A αβ 1 αβ 2. A αx X β 1 β 2. Lembrando... Gramáticas Livres de Contexto

Compiladores. Exemplo. Caraterísticas de Gramáticas. A αβ 1 αβ 2. A αx X β 1 β 2. Lembrando... Gramáticas Livres de Contexto Compiladores Análise sintática (2) Análise Top-Down Lembrando... Gramáticas Livres de Contexto Análise sintática = parsing. Baseada em GLCs Gramática: S A B Top-Down Bottom-Up S AB cb ccbb ccbca S AB A

Leia mais

Introdução à Programação

Introdução à Programação Introdução à Programação Linguagens de Programação: sintaxe e semântica de linguagens de programação e conceitos de linguagens interpretadas e compiladas Engenharia da Computação Professor: Críston Pereira

Leia mais

COMPILADORES. Análise sintática. Prof. Geovane Griesang Universidade de Santa Cruz do Sul UNISC Departamento de informática

COMPILADORES. Análise sintática. Prof. Geovane Griesang Universidade de Santa Cruz do Sul UNISC Departamento de informática Universidade de Santa Cruz do Sul UNISC Departamento de informática COMPILADORES Análise sintática Parte 02 Prof. geovanegriesang@unisc.br Data Conteúdo 23/09/2013 3. Análise Sintática: 3.1 analisadores

Leia mais

Um Compilador Simples. Definição de uma Linguagem. Estrutura de Vanguarda. Gramática Livre de Contexto. Exemplo 1

Um Compilador Simples. Definição de uma Linguagem. Estrutura de Vanguarda. Gramática Livre de Contexto. Exemplo 1 Definição de uma Linguagem Linguagem= sintaxe + semântica Especificação da sintaxe: gramática livre de contexto, BNF (Backus-Naur Form) Especificação Semântica: informal (textual), operacional, denotacional,

Leia mais

Compiladores Analisador Sintático. Prof. Antonio Felicio Netto Ciência da Computação

Compiladores Analisador Sintático. Prof. Antonio Felicio Netto Ciência da Computação Compiladores Analisador Sintático Prof. Antonio Felicio Netto antonio.felicio@anhanguera.com Ciência da Computação 1 Análise Sintática - A Análise Sintática constitui a segunda fase de um tradutor de uma

Leia mais

Compiladores. Análise Sintática

Compiladores. Análise Sintática Compiladores Análise Sintática Análise Sintática Vejamos um exemplo, seja a seguinte instrução de atribuição: posicao = inicial + incremento * 60 Na análise sintática tenta-se construir uma frase correta

Leia mais

V Análise Sintática. V.1.1 Gramáticas Livres de Contexto Definições de GLC

V Análise Sintática. V.1.1 Gramáticas Livres de Contexto Definições de GLC V Análise Sintática V.1 Fundamentos Teóricos V.1.1 G.L.C V.1.2 Teoria de Parsing V.2 Especificação Sintática de Ling. de Prog. V.3 - Implementação de PARSER s V.4 - Especificação Sintática da Linguagem

Leia mais

Compiladores. Motivação. Tradutores. Motivação. Tipos de Tradutores. Tipos de Tradutores

Compiladores. Motivação. Tradutores. Motivação. Tipos de Tradutores. Tipos de Tradutores Motivação Prof. Sérgio Faustino Compiladores Conhecimento das estruturas e algoritmos usados na implementação de linguagens: noções importantes sobre uso de memória, eficiência, etc. Aplicabilidade freqüente

Leia mais

V Teoria de Parsing. Termos Básicos: Parser Analisador Sintático Parsing Analise Sintática Parse Representação da analise efetuada

V Teoria de Parsing. Termos Básicos: Parser Analisador Sintático Parsing Analise Sintática Parse Representação da analise efetuada V Teoria de Parsing Termos Básicos: Parser Analisador Sintático Parsing Analise Sintática Parse Representação da analise efetuada Ascendentes: S + x (* Seq. Invertida Reducao *) dir Exemplo: Descendentes:

Leia mais

Análise Sintática. Fabiano Baldo

Análise Sintática. Fabiano Baldo Compiladores Análise Sintática Fabiano Baldo Gramáticas Livre de Contexto (GLC) É utilizada na especificação formal lda sintaxe de uma linguagem de programação. É um conjunto de produções ou regras gramaticais

Leia mais

Linguagens Livres de Contexto

Linguagens Livres de Contexto Linguagens Livres de Contexto 1 Roteiro Gramáticas livres de contexto Representação de linguagens livres de contexto Formas normais para gramáticas livres de contexto Gramáticas ambíguas Autômatos de Pilha

Leia mais

Plano da aula. Compiladores. Os erros típicos são sintáticos. Análise Sintática. Usando Gramáticas. Os erros típicos são sintáticos

Plano da aula. Compiladores. Os erros típicos são sintáticos. Análise Sintática. Usando Gramáticas. Os erros típicos são sintáticos Plano da aula Compiladores Análise sintática (1) Revisão: Gramáticas Livres de Contexto 1 Introdução: porque a análise sintática? Noções sobre Gramáticas Livres de Contexto: Definição Propriedades Derivações

Leia mais

II.1 Conceitos Fundamentais. Uma delas é programar o =>

II.1 Conceitos Fundamentais. Uma delas é programar o => II.1 Conceitos Fundamentais II.2 Gerações das Linguagens de Programação II.3 Linguagem de Programação II.4 Sistema Operacional II.5 Tradutores II.5.1 Estrutura de um tradutor II.5.1.1 Análise Léxica II.5.1.3

Leia mais

COMPILADORES. Análise sintática. Prof. Geovane Griesang Universidade de Santa Cruz do Sul UNISC Departamento de informática

COMPILADORES. Análise sintática. Prof. Geovane Griesang Universidade de Santa Cruz do Sul UNISC Departamento de informática Universidade de Santa Cruz do Sul UNISC Departamento de informática COPILADORES Análise sintática Parte 03 Prof. geovanegriesang@unisc.br Analisador sem recursão Analisador sintático sem recursão pode

Leia mais

INE5416 Paradigmas de Programação. Ricardo Azambuja Silveira INE CTC UFSC E Mail: URL:

INE5416 Paradigmas de Programação. Ricardo Azambuja Silveira INE CTC UFSC E Mail: URL: INE5416 Paradigmas de Programação Ricardo Azambuja Silveira INE CTC UFSC E Mail: silveira@inf.ufsc.br URL: www.inf.ufsc.br/~silveira Conceitos Léxica estudo dos símbolos que compõem uma linguagem Sintaxe

Leia mais

CAP. VI ANÁLISE SEMÂNTICA

CAP. VI ANÁLISE SEMÂNTICA CAP. VI ANÁLISE SEMÂNTICA VI.1 Introdução Semântica SIGNIFICADO, SENTIDO LÓGICO, COERÊNCIA,... Diferença entre SINTAXE e SEMÂNTICA Sintaxe : descreve as estruturas de uma linguagem; Semântica : descreve

Leia mais

Analisadores Descendentes Tabulares; Cjs First Follow

Analisadores Descendentes Tabulares; Cjs First Follow Conteúdo da aula nalisadores Descendentes Tabulares; Cjs First Follow Marcelo Johann nalisadores Descendentes Recursivos com Retrocesso Recursivos Preditivos Conjunto FIRT e Implementação nalisador Preditivo

Leia mais

LINGUAGEM LIVRE DE CONTEXTO GRAMÁTICA LIVRE DE CONTEXTO

LINGUAGEM LIVRE DE CONTEXTO GRAMÁTICA LIVRE DE CONTEXTO LINGUAGEM LIVRE DE CONTEXTO As Linguagens Livres de Contexto é um reconhecedor de linguagens, capaz de aceitar palavras corretas (cadeia, sentenças) da linguagem. Por exemplo, os autômatos. Um gerador

Leia mais

FACULDADE LEÃO SAMPAIO

FACULDADE LEÃO SAMPAIO FACULDADE LEÃO SAMPAIO Paradigmas de Programação Curso de Análise e Desenvolvimento de Sistemas Turma: 309-5 Semestre - 2014.2 Paradigmas de Programação Prof. MSc. Isaac Bezerra de Oliveira. 1 PARADIGMAS

Leia mais

Análise Sintática I. Eduardo Ferreira dos Santos. Abril, Ciência da Computação Centro Universitário de Brasília UniCEUB 1 / 42

Análise Sintática I. Eduardo Ferreira dos Santos. Abril, Ciência da Computação Centro Universitário de Brasília UniCEUB 1 / 42 Análise Sintática I Eduardo Ferreira dos Santos Ciência da Computação Centro Universitário de Brasília UniCEUB Abril, 2017 1 / 42 Sumário 1 Introdução 2 Derivações 3 Ambiguidade 4 Análise sintática descendente

Leia mais

Compiladores Aula 4. Celso Olivete Júnior.

Compiladores Aula 4. Celso Olivete Júnior. Aula 4 Celso Olivete Júnior olivete@fct.unesp.br Na aula de hoje... Revisão: gramáticas Relações em uma gramática: Cabeça, Último, Primeiro (First) e Seguinte (Follow) Capítulo 4 (seção 4.4.2) do livro

Leia mais

Universidade de Santa Cruz do Sul UNISC Departamento de informática COMPILADORES. Introdução. Geovane Griesang

Universidade de Santa Cruz do Sul UNISC Departamento de informática COMPILADORES. Introdução. Geovane Griesang Universidade de Santa Cruz do Sul UNISC Departamento de informática COMPILADORES Introdução geovanegriesang@unisc.br Processadores de linguagem Linguagens de programação são notações para se descrever

Leia mais

Prof. Adriano Maranhão COMPILADORES

Prof. Adriano Maranhão COMPILADORES Prof. Adriano Maranhão COMPILADORES LINGUAGENS: INTERPRETADAS X COMPILADAS Resumo: Linguagem compilada: Se o método utilizado traduz todo o texto do programa, para só depois executar o programa, então

Leia mais

Compiladores. Introdução

Compiladores. Introdução Compiladores Introdução Apresentação Turma Noite Continuada I 20/03 Continuada II 22/05 Atividades Regimental 05/06 Total 1 Ponto 1 Ponto 1 Ponto 7 Pontos 10 Pontos Aulas expositivas teórico-práticas Exercícios

Leia mais

LFA Aula 09. Gramáticas e Linguagens Livres de Contexto 18/01/2016. Linguagens Formais e Autômatos. Celso Olivete Júnior.

LFA Aula 09. Gramáticas e Linguagens Livres de Contexto 18/01/2016. Linguagens Formais e Autômatos. Celso Olivete Júnior. LFA Aula 09 Gramáticas e Linguagens Livres de Contexto (Hopcroft, 2002) 18/01/2016 Celso Olivete Júnior olivete@fct.unesp.br www.fct.unesp.br/docentes/dmec/olivete/lfa 1 Classes Gramaticais Linguagens

Leia mais

V.2 Especificação Sintática de Linguagens de Programação

V.2 Especificação Sintática de Linguagens de Programação V.2 Especificação Sintática de Linguagens de Programação Deve ser baseada: No planejamento da Linguagem / Compilador Objetivos, Filosofia, Potencialidades,... Nos critérios de projeto/avaliação Legibilidade,

Leia mais

Sintaxe e Semântica. George Darmiton da Cunha Cavalcanti.

Sintaxe e Semântica. George Darmiton da Cunha Cavalcanti. Sintaxe e Semântica George Darmiton da Cunha Cavalcanti (gdcc@cin.ufpe.br) Tópicos Introdução O problema de descrever a sintaxe Métodos formais para descrever a sintaxe Gramáticas de atributos Descrevendo

Leia mais

Análise sintática. Prof. Thiago A. S. Pardo. Análise sintática ascendente

Análise sintática. Prof. Thiago A. S. Pardo. Análise sintática ascendente Análise sintática Função, interação com o compilador Análise descendente e ascendente Especificação e reconhecimento de cadeias de tokens válidas Implementação Tratamento de erros Prof. Thiago A. S. Pardo

Leia mais

Gramáticas Livres de Contexto Parte 1

Gramáticas Livres de Contexto Parte 1 Universidade Estadual de Feira de Santana Engenharia de Computação Gramáticas Livres de Contexto Parte 1 EXA 817 Compiladores Prof. Matheus Giovanni Pires O papel do Analisador Sintático É responsável

Leia mais

Compiladores - Análise Ascendente

Compiladores - Análise Ascendente Compiladores - Análise Ascendente Fabio Mascarenhas - 2013.2 http://www.dcc.ufrj.br/~fabiom/comp Análise Descendente vs. Ascendente As técnicas de análise que vimos até agora (recursiva com retrocesso,

Leia mais

Compiladores. Introdução à Compiladores

Compiladores. Introdução à Compiladores Compiladores Introdução à Compiladores Cristiano Lehrer, M.Sc. Introdução (1/2) O meio mais eficaz de comunicação entre pessoas é a linguagem (língua ou idioma). Na programação de computadores, uma linguagem

Leia mais

Compiladores - Análise Ascendente

Compiladores - Análise Ascendente Compiladores - Análise Ascendente Fabio Mascarenhas - 2013.1 http://www.dcc.ufrj.br/~fabiom/comp Análise Descendente vs. Ascendente As técnicas de análise que vimos até agora (recursiva com retrocesso,

Leia mais

Linguagens Livres do Contexto. Adaptado de H. Brandão

Linguagens Livres do Contexto. Adaptado de H. Brandão Linguagens Livres do Contexto Adaptado de H. Brandão Linguagens Livres do Contexto Para as LLC, temos as Gramáticas Livres do Contexto; Linguagens Livres do Contexto Para as LLC, temos as Gramáticas Livres

Leia mais

Compiladores I Prof. Ricardo Santos (cap 3 Análise Léxica: Introdução, Revisão LFA)

Compiladores I Prof. Ricardo Santos (cap 3 Análise Léxica: Introdução, Revisão LFA) Compiladores I Prof. Ricardo Santos (cap 3 Análise Léxica: Introdução, Revisão LFA) Análise Léxica A primeira fase da compilação Recebe os caracteres de entrada do programa e os converte em um fluxo de

Leia mais

Compiladores. Análise Léxica

Compiladores. Análise Léxica Compiladores Análise Léxica Cristiano Lehrer, M.Sc. Introdução (1/3) Análise léxica é a primeira fase do compilador. A função do analisador léxico, também denominado scanner, é: Fazer a leitura do programa

Leia mais

INE5421 LINGUAGENS FORMAIS E COMPILADORES

INE5421 LINGUAGENS FORMAIS E COMPILADORES INE5421 LINGUAGENS FORMAIS E COMPILADORES PLANO DE ENSINO Objetivo geral Conhecer a teoria das linguagens formais visando sua aplicação na especificação de linguagens de programação e na construção de

Leia mais

Compiladores I Prof. Ricardo Santos (cap 1)

Compiladores I Prof. Ricardo Santos (cap 1) Compiladores I Prof. Ricardo Santos (cap 1) Compiladores Linguagens de programação são notações que permitem descrever como programas devem executar em uma máquina Mas, antes do programa executar, deve

Leia mais

Análise sintática. Análise sintática ascendente. Parte-se dos símbolos terminais em direção ao símbolo inicial da gramática. Derivação mais à direita

Análise sintática. Análise sintática ascendente. Parte-se dos símbolos terminais em direção ao símbolo inicial da gramática. Derivação mais à direita Análise sintática Função, interação com o compilador Análise descendente e ascendente Especificação e reconhecimento de cadeias de tokens válidas Implementação Tratamento de erros Prof. Thiago A. S. Pardo

Leia mais

Compiladores. Fabio Mascarenhas

Compiladores. Fabio Mascarenhas Compiladores Fabio Mascarenhas 2017.1 http://www.dcc.ufrj.br/~fabiom/comp Introdução Compiladores x Interpretadores Offline x Online Um compilador transforma um programa executável de uma linguagem fonte

Leia mais

Análise sintática. Questão. E se a análise sintática pudesse ser modelada por autômatos?

Análise sintática. Questão. E se a análise sintática pudesse ser modelada por autômatos? Análise sintática Função, interação com o compilador Análise descendente e ascendente Especificação e reconhecimento de cadeias de tokens válidas Implementação Tratamento de erros Prof. Thiago A. S. Pardo

Leia mais

Vantagens de uma Gramática. Sintaxe de uma Linguagem. Analisador Sintático - Parser. Papel do Analisador Sintático. Tiposde Parsers para Gramáticas

Vantagens de uma Gramática. Sintaxe de uma Linguagem. Analisador Sintático - Parser. Papel do Analisador Sintático. Tiposde Parsers para Gramáticas Sintaxe de uma Linguagem Cada LP possui regras que descrevem a estrutura sintática dos programas. specificada através de uma gramática livre de contexto, BNF (Backus-Naur Form). 1 Vantagens de uma Gramática

Leia mais

Análise Sintática Introdução

Análise Sintática Introdução Análise Sintática Introdução Renato Ferreira Linguagens e Automatas Linguagens formais são importantes em Computação Especialmente em linguagens de programação Linguagens regulares A linguagem formal mais

Leia mais

CP Compiladores I Prof. Msc.. Carlos de Salles

CP Compiladores I Prof. Msc.. Carlos de Salles CP 5017.9 Prof. Msc.. Carlos de Salles 1 - EMENTA O Processo de Compilação. Deteção e Recuperação de Erros. Introdução à geração de Código Intermediário. Geração de Código de Máquina. Otimização. Uma visão

Leia mais

FERRAMENTA DE AUXÍLIO AO PROCESSO DE DESENVOLVIMENTO DE SOFTWARE INTEGRANDO TECNOLOGIAS OTIMIZADORAS

FERRAMENTA DE AUXÍLIO AO PROCESSO DE DESENVOLVIMENTO DE SOFTWARE INTEGRANDO TECNOLOGIAS OTIMIZADORAS FERRAMENTA DE AUXÍLIO AO PROCESSO DE DESENVOLVIMENTO DE SOFTWARE INTEGRANDO TECNOLOGIAS OTIMIZADORAS Acadêmico: Roger Anderson Schmidt Orientador : Marcel Hugo Supervisor : Ricardo de Freitas Becker Empresa

Leia mais

Construção de Compiladores Aula 16 - Análise Sintática

Construção de Compiladores Aula 16 - Análise Sintática Construção de Compiladores Aula 16 - Análise Sintática Bruno Müller Junior Departamento de Informática UFPR 25 de Setembro de 2014 1 Introdução Hierarquia de Chomsky Reconhecedores Linguagens Livres de

Leia mais

Compiladores Aula 6. Celso Olivete Júnior.

Compiladores Aula 6. Celso Olivete Júnior. Aula 6 Celso Olivete Júnior olivete@fct.unesp.br Na aula passada Analisadores Sintáticos Descendentes ASD com retrocesso ASD preditivo recursivo não-recursivo 2 ASD Preditivo Recursivo Projeto Parte 2

Leia mais

Sintaxe do Pascal Simplificado Estendido de 12 novas construções em Notação EBNF (BNF estendida)

Sintaxe do Pascal Simplificado Estendido de 12 novas construções em Notação EBNF (BNF estendida) Sintaxe do Pascal Simplificado Estendido de 12 novas construções em Notação EBNF (BNF estendida) Não-terminais são nomes mnemônicos colocados entre parênteses angulares. Vocabulário terminal formado por

Leia mais

INE5318 Construção de Compiladores. AULA 4: Análise Sintática

INE5318 Construção de Compiladores. AULA 4: Análise Sintática INE5318 Construção de Compiladores AULA 4: Análise Sintática Ricardo Azambuja Silveira INE CTC UFSC E Mail: silveira@inf.ufsc.br URL: www.inf.ufsc.br/~silveira Definições preliminares Parser (Analisador

Leia mais

Programação Introdução

Programação Introdução PROGRAMAÇÃO Programação Introdução Prof. Dr. Adriano Mauro Cansian 1 Introdução Para armazenar um algoritmo na memória de um computador e para que ele possa, em seguida, comandar as operações a serem executadas,

Leia mais

COMPILADORES. Análise sintática. Prof. Geovane Griesang Universidade de Santa Cruz do Sul UNISC Departamento de informática

COMPILADORES. Análise sintática. Prof. Geovane Griesang Universidade de Santa Cruz do Sul UNISC Departamento de informática Universidade de Santa Cruz do Sul UNISC Departamento de informática COMPILADORES Análise sintática Parte 04 Prof. geovanegriesang@unisc.br Data Conteúdo 23/09/2013 3. Análise Sintática: 3.1 analisadores

Leia mais

LINGUAGENS FORMAIS Definições. Desenvolveram-se na História em função da necessidade dos grupos humanos que as empregavam

LINGUAGENS FORMAIS Definições. Desenvolveram-se na História em função da necessidade dos grupos humanos que as empregavam Linguagens Naturais LINGUAGENS FORMAIS Definições Desenvolveram-se na História em função da necessidade dos grupos humanos que as empregavam São muito ricas, mas também ambíguas e imprecisas. Ex.: João

Leia mais

Análise Sintática Bottom-up

Análise Sintática Bottom-up MAB 471 2011.2 Análise Sintática Bottom-up http://www.dcc.ufrj.br/~fabiom/comp Recapitulando parsers top-down Constróem árvore sintática da raiz até as folhas Recursão à esquerda faz parsers entrarem em

Leia mais

Compiladores. Análise lexical. Plano da aula. Motivação para análise lexical. Vocabulário básico. Estrutura de um compilador

Compiladores. Análise lexical. Plano da aula. Motivação para análise lexical. Vocabulário básico. Estrutura de um compilador Estrutura de um compilador programa fonte Compiladores Análise lexical () Expressões Regulares analisador léxico analisador sintático analisador semântico análise gerador de código intermediário otimizador

Leia mais

Compiladores. Prof. Bruno Moreno Aula 8 02/05/2011

Compiladores. Prof. Bruno Moreno Aula 8 02/05/2011 Compiladores Prof. Bruno Moreno Aula 8 02/05/2011 RECONHECIMENTO DE TOKENS Reconhecimento de Tokens Até aqui aprendemos a identificar tokens Para reconhecimento, a única abordagem utilizada foi árvores

Leia mais

Algoritmos. Algoritmos e Linguagem de Programação - Prof Carlos Vetorazzi

Algoritmos. Algoritmos e Linguagem de Programação - Prof Carlos Vetorazzi Algoritmos Algoritmos e Linguagem de Programação - Prof Carlos Vetorazzi Conceitos Linhas de Código de um Algoritmo ou Programa escrita do programa linha a linha, ou seja, a sintaxe do programa, podendo-se

Leia mais

Compiladores. Análise Léxica

Compiladores. Análise Léxica Compiladores Análise Léxica Regras Léxicas Especificam o conjunto de caracteres que constituem o alfabeto da linguagem, bem como a maneira que eles podem ser combinados; Exemplo Pascal: letras maiúsculas

Leia mais

Autômatos e Linguagens

Autômatos e Linguagens Autômatos e Linguagens Eduardo Ferreira dos Santos Ciência da Computação Centro Universitário de Brasília UniCEUB Agosto, 2016 1 / 41 Sumário 1 Compiladores 2 Linguagens de programação 3 Ciência dos compiladores

Leia mais

INE5317 Linguagens Formais e Compiladores. AULA 10: Anális e S intática

INE5317 Linguagens Formais e Compiladores. AULA 10: Anális e S intática INE5317 Linguagens Formais e Compiladores AULA 10: Anális e S intática baseado em material produzido pelo prof Paulo B auth Menezes e pelo prof Olinto Jos é Varela Furtado Ricardo Azambuja Silveira INE-CTC-UFSC

Leia mais

Linguagens de Programação Aula 4

Linguagens de Programação Aula 4 Aula 4 Celso Olivete Júnior olivete@fct.unesp.br Na aula passada... Autômatos finitos AF:exemplos... Cadeia de caracteres a,b,c 2/82 Na aula passada... Autômatos finitos AF:exemplos... Números inteiros(com

Leia mais

Análise Sintática. Eduardo Ferreira dos Santos. Outubro, Ciência da Computação Centro Universitário de Brasília UniCEUB 1 / 18

Análise Sintática. Eduardo Ferreira dos Santos. Outubro, Ciência da Computação Centro Universitário de Brasília UniCEUB 1 / 18 Análise Sintática Eduardo Ferreira dos Santos Ciência da Computação Centro Universitário de Brasília UniCEUB Outubro, 2016 1 / 18 Sumário 1 Introdução 2 Derivações 2 / 18 1 Introdução 2 Derivações 3 /

Leia mais

Análise Sintática Descendente

Análise Sintática Descendente Análise Sintática Descendente Uma tentativa de construir uma árvore de derivação da esquerda para a direita Cria a raiz e, a seguir, cria as subárvores filhas. Produz uma derivação mais à esquerda da sentença

Leia mais

15/03/2018. Professor Ariel da Silva Dias Aspectos sintáticos e semânticos básicos de linguagens de programação

15/03/2018. Professor Ariel da Silva Dias Aspectos sintáticos e semânticos básicos de linguagens de programação Professor Ariel da Silva Dias Aspectos sintáticos e semânticos básicos de linguagens de programação Conjunto de regras que definem a forma da linguagem; Como as sentenças podem ser formadas como sequências

Leia mais

Introdução. Compiladores Análise Semântica. Introdução. Introdução. Introdução. Introdução 11/3/2008

Introdução. Compiladores Análise Semântica. Introdução. Introdução. Introdução. Introdução 11/3/2008 Compiladores Análise Semântica Fabiano Baldo Análise Semântica é por vezes referenciada como análise sensível ao contexto porque lida com algumas semânticas simples tais como o uso de uma variável somente

Leia mais

Projeto de Compiladores

Projeto de Compiladores Projeto de Compiladores FIR Faculdade Integrada do Recife João Ferreira 12 e 13 de fevereiro de 2007 Questionário 1. Em quais linguagens de programação você já programou? 2. O que você sabe sobre compiladores?

Leia mais

Análise Sintática LL(1)

Análise Sintática LL(1) FACULDADE ANGLO AMERICANO FOZ DO IGUAÇU Curso de Ciência da Computação 7º Periodo Disciplina: Compiladores Prof. Erinaldo Sanches Nascimento Análise Sintática LL(1) Análise Sintática Descendente Introdução

Leia mais

Compiladores - Gramáticas

Compiladores - Gramáticas Compiladores - Gramáticas Fabio Mascarenhas 2018.1 http://www.dcc.ufrj.br/~fabiom/comp Análise Sintática A análise sintática agrupa os tokens em uma árvore sintática de acordo com a estrutura do programa

Leia mais

Concurso Público para provimento de cargo efetivo de Docentes. Edital 20/2015 CIÊNCIA DA COMPUTAÇÃO II Campus Rio Pomba

Concurso Público para provimento de cargo efetivo de Docentes. Edital 20/2015 CIÊNCIA DA COMPUTAÇÃO II Campus Rio Pomba Questão 01 No processo de construção de compiladores, é essencial compreender e manipular as expressões regulares e suas equivalências. Dentro desse contexto, seja o alfabeto = {a, b, c, d, e} e a seguinte

Leia mais

Compiladores. Bruno Lopes. Bruno Lopes Compiladores 1 / 32. Instituto de C

Compiladores. Bruno Lopes. Bruno Lopes Compiladores 1 / 32. Instituto de C ompiladores Introdução Bruno Lopes Bruno Lopes ompiladores 1 / 32 Apresentação Em que período estão? O quanto sabem de programação? Quais linguagens? O quanto sabem de unix? O quanto sabem de Linguagens

Leia mais

Universidade Federal de Alfenas

Universidade Federal de Alfenas Universidade Federal de Alfenas Linguagens Formais e Autômatos Aula 12 Linguagens Livres do Contexto humberto@bcc.unifal-mg.edu.br Linguagens Livres do Contexto Para as LLC, temos as Gramáticas Livres

Leia mais

Compiladores 02 Analise léxica

Compiladores 02 Analise léxica Compiladores 02 Analise léxica Sumário Análise Léxica Definição: Lexema, tokens Tabela símbolos Expressões regulares, automatos Relembrando O compilador é dividido em duas etapas Análise Síntese Análise

Leia mais

Universidade Estadual da Paraíba - UEPB Curso de Licenciatura em Computação

Universidade Estadual da Paraíba - UEPB Curso de Licenciatura em Computação Universidade Estadual da Paraíba - UEPB Curso de Licenciatura em Computação Análise Semântica Disciplina: Compiladores Equipe: Luiz Carlos dos Anjos Filho José Ferreira Júnior Compiladores Um compilador

Leia mais

DESENVOLVIMENTO DO COMPILADOR PARA A LINGUAGEM SIMPLE

DESENVOLVIMENTO DO COMPILADOR PARA A LINGUAGEM SIMPLE DESENVOLVIMENTO DO COMPILADOR PARA A LINGUAGEM SIMPLE Jeferson MENEGAZZO 1, Fernando SCHULZ 2, Munyque MITTELMANN 3, Fábio ALEXANDRINI 4. 1 Aluno 5ª fase do Curso de Ciência da Computação do Instituto

Leia mais

Universidade Federal de Goiás Bacharelado em Ciências da Computacão Compiladores

Universidade Federal de Goiás Bacharelado em Ciências da Computacão Compiladores Universidade Federal de Goiás Bacharelado em Ciências da Computacão Compiladores 2013-2 Compilador para a Linguagem Cafezinho Especificação dos trabalhos: T2 (Geração da Representação Intermediária e Análise

Leia mais

Compiladores - Gramáticas

Compiladores - Gramáticas Compiladores - Gramáticas Fabio Mascarenhas - 2013.1 http://www.dcc.ufrj.br/~fabiom/comp Análise Sintática A análise sintática agrupa os tokens em uma árvore sintática de acordo com a estrutura do programa

Leia mais

Projeto de Compiladores

Projeto de Compiladores Projeto de Compiladores FIR Faculdade Integrada do Recife João Ferreira 26 e 27 de fevereiro de 2007 Agenda da Aula Revisão Linguagem de Programação Tradutores Compilador As Fases de Um Compilador Linguagem

Leia mais

Tratamento dos Erros de Sintaxe. Adriano Maranhão

Tratamento dos Erros de Sintaxe. Adriano Maranhão Tratamento dos Erros de Sintaxe Adriano Maranhão Introdução Se um compilador tivesse que processar somente programas corretos, seu projeto e sua implementação seriam grandemente simplificados. Mas os programadores

Leia mais

BNF (Backus-Naur Form) Gramática Livres de Contexto / Estruturas Recursivas

BNF (Backus-Naur Form) Gramática Livres de Contexto / Estruturas Recursivas Sintae => Usualmente Gramática Livre do Conteto (GLC) BNF (Backus-Naur Form) Gramática Livres de Conteto / struturas Recursivas comando => IF epressao THN epressao LS epressao epressao => (epressao) OR

Leia mais

Conceitos de Linguagens de Programação

Conceitos de Linguagens de Programação Conceitos de Linguagens de Programação Aula 06 Análise Sintática (Implementação) Edirlei Soares de Lima Análise Sintática A maioria dos compiladores separam a tarefa da análise sintática

Leia mais

ACH2043 INTRODUÇÃO À TEORIA DA COMPUTAÇÃO

ACH2043 INTRODUÇÃO À TEORIA DA COMPUTAÇÃO ACH2043 INTRODUÇÃO À TEORIA DA COMPUTAÇÃO 2. Linguagens Livres-do-Contexto Referência: SIPSER, M. Introdução à Teoria da Computação. 2ª edição, Ed. Thomson Prof. Marcelo S. Lauretto marcelolauretto@usp.br

Leia mais

Compiladores. Parser LL 10/13/2008

Compiladores. Parser LL 10/13/2008 Compiladores Fabiano Baldo Usa uma pilha explícita ao invés de chamadas recursivas para realizar a análise sintática. LL(k) parsing significa que ktokensà frente são utilizados. O primeiro L significa

Leia mais

Eduardo Belo de Araújo. Analisador ANSI-C

Eduardo Belo de Araújo. Analisador ANSI-C Eduardo Belo de Araújo Analisador ANSI-C Monografia apresentada ao Departamento de Ciência da Computação da Universidade Federal de Lavras, como parte das exigências do curso de Pós-Graduação Lato Sensu

Leia mais

Capítulo 7. Expressões e Sentenças de Atribuição

Capítulo 7. Expressões e Sentenças de Atribuição Capítulo 7 Expressões e Sentenças de Atribuição Introdução Expressões são os meios fundamentais de especificar computações em uma linguagem de programação Para entender a avaliação de expressões, é necessário

Leia mais

Compiladores. Bruno Lopes. Bruno Lopes Compiladores 1 / 31. Instituto de C

Compiladores. Bruno Lopes. Bruno Lopes Compiladores 1 / 31. Instituto de C ompiladores Análise Léxica Bruno Lopes Bruno Lopes ompiladores 1 / 31 Front-end Lida com a linguagem de entrada Teste de pertinência: código fonte linguagem fonte? Programa está bem formado? Sintaticamente?

Leia mais

TÉCNICO DE INFORMÁTICA - SISTEMAS

TÉCNICO DE INFORMÁTICA - SISTEMAS 782 - Programação em C/C++ - estrutura básica e conceitos fundamentais Linguagens de programação Linguagem de programação são conjuntos de palavras formais, utilizadas na escrita de programas, para enunciar

Leia mais

Apêndice A. Pseudo-Linguagem

Apêndice A. Pseudo-Linguagem Apêndice A. Pseudo-Linguagem Apostila de Programação I A.1 Considerações Preliminares Os computadores convencionais se baseiam no conceito de uma memória principal que consiste de células elementares,

Leia mais

Introdução aos Compiladores

Introdução aos Compiladores Universidade Católica de Pelotas Introdução aos Compiladores André Rauber Du Bois dubois@ucpel.tche.br 1 MOTIVAÇÃO Entender os algor ıtmos e estruturas usados para se implementar linguagens de programação

Leia mais

Paradigmas de Linguagem de Programação

Paradigmas de Linguagem de Programação Paradigmas de Linguagem de Programação Sintaxe Introdução Sintaxe: conjunto de regras que definem a forma da linguagem; Como as sentenças podem ser formadas como sequências de componentes básicos palavras;

Leia mais

Apresentação. !! Familiarização com os métodos de construção de compiladores de linguagens e com as técnicas de compilação mais habituais.

Apresentação. !! Familiarização com os métodos de construção de compiladores de linguagens e com as técnicas de compilação mais habituais. Apresentação Universidade dos Açores Departamento de Matemática www.uac.pt/~hguerra/!! Aquisição de conceitos sobre a definição de linguagens de programação.!! Familiarização com os métodos de construção

Leia mais

Linguagens Formais e Autômatos. Simplificação de Gramáticas Livre do Contexto (GLC)

Linguagens Formais e Autômatos. Simplificação de Gramáticas Livre do Contexto (GLC) Linguagens Formais e Autômatos Simplificação de Gramáticas Livre do Contexto (GLC) Cristiano Lehrer, M.Sc. Gramática Simplificada Gramática simplificada é uma gramática livre do contexto que não apresenta

Leia mais

Linguagens de Programação Aula 3

Linguagens de Programação Aula 3 Aula 3 Celso Olivete Júnior olivete@fct.unesp.br Na aula passada... Classificação das LPs (nível, geração e paradigma) Paradigmas Imperativo, OO, funcional, lógico e concorrente 2/33 Na aula de hoje...

Leia mais

Compiladores - Análise Léxica

Compiladores - Análise Léxica Compiladores - Análise Léxica Fabio Mascarenhas 2017.2 http://www.dcc.ufrj.br/~fabiom/comp Introdução Primeiro passo do front-end: reconhecer tokens Tokens são as palavras do programa O analisador léxico

Leia mais

Compiladores - Especificando Sintaxe

Compiladores - Especificando Sintaxe Compiladores - Especificando Sintaxe Fabio Mascarenhas - 2013.1 http://www.dcc.ufrj.br/~fabiom/comp Análise Sintática A análise sintática agrupa os tokens em uma árvore sintática de acordo com a estrutura

Leia mais

Linguagens Formais e Autômatos

Linguagens Formais e Autômatos Linguagens Formais e Autômatos Gramáticas Livre do Contexto (GLC) Cristiano Lehrer, M.Sc. Linguagens Livres do Contexto (1/2) Seu estudo é de fundamental importância na informática: Compreende um universo

Leia mais

IV Gramáticas Livres de Contexto

IV Gramáticas Livres de Contexto IV Gramáticas Livres de Contexto Introdução Definições de GLC 1 G = (Vn, Vt, P, S) onde P = {A α A Vn α (Vn Vt) + } 2 GLC ε - LIVRE : S ε pode pertencer a P, desde que: S seja o símbolo inicial de G S

Leia mais

Compilação: Erros. Detecção de Erros: * Analisadores Top-Down - Preditivo Tabular (LL) - Feito a mão. * Analisadores Botton-Up: - Shift-Reduce (SLR)

Compilação: Erros. Detecção de Erros: * Analisadores Top-Down - Preditivo Tabular (LL) - Feito a mão. * Analisadores Botton-Up: - Shift-Reduce (SLR) Compilação: Erros Detecção de Erros: * Analisadores Top-Down - Preditivo Tabular (LL) - Feito a mão * Analisadores Botton-Up: - Shift-Reduce (SLR) * Erros no Lex * Erros no Yacc * Erros na Definição da

Leia mais