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 linguagem de programação; - Sua função é verificar se as construções usadas no programa estão gramaticamente corretas; 2
Análise Sintática - O Analisador Sintático obtém uma cadeia de tokens proveniente do analisador léxico e verifica se o mesmo pode ser gerado pela gramática da linguagem-fonte. - Espera-se que o analisador sintático relate quaisquer erros de sintaxe e também recupere erros que ocorrem mais comumente, afim de poder continuar processando o resto de sua entrada. 3
Métodos de Análise Sintática - Os Analisadores Sintáticos top-down, constroem uma árvore do topo (raiz) para o fundo (folha). - Os Analisadores Sintáticos botton-up, começam pelas folhas e trabalha a árvore acima até a raiz. 4
Análise Sintática - Objetivo - Se uma cadeia de tokens foi avaliada pelo analisador léxico e pertence a uma linguagem, então o programa pode ser gerado por uma gramática; - Seu objetivo é a construção da árvore sintática ou apenas a decisão se a cadeia fornecida é ou não uma sentença da gramática que define a linguagem. 5
Análise Sintática no compilador 6
Árvore Sintática - Como podemos determinar se uma seqüência de códigos está sintaticamente correta? - Utilizando as regras da gramática, a sintaxe está correta se a string for derivada do símbolo inicial; - Os algoritmos são desenvolvidos para gerar derivações da string na linguagem da gramática. Quando a entrada string não fizer parte da linguagem, o processo deve identificar que não existe derivação. O procedimento que faz esta função é chamado de parsing ; 7
Árvore Sintática - O analisador sintático recebe do analidador léxico o código-fonte na forma de tokens e efetua a análise sintática. Similar à análise gramatical de uma sentença em linguagem natural. A análise sintática determina os elementos estruturais do programa e seus relacionamentos. Os resultados da análise sintática são geralmente representados como uma árvore sintática - Análise do programa fonte considerando-o não mais como uma sequênciade caracteres, mas sim como uma sequência de lexemas; - Verificação a ordem como são colocados os lexemas do programa fonte; 8
Árvore Sintática expressão expressão de atribuição expressão = expressão expressão indexada expressão de adição expressão [ expressão ] expressão + expressão identificador a identificador index identificador b numero 3 9
Análise Sintática - Métodos - Existem métodos universais de análise sintática, como o algoritmo de Cocke-Younger-Kasamie o de Earley que trabalham com qualquer tipo de gramática livre de contexto (GLC); - Mas são ineficientes para se usar na produção de compiladores pois são de ordem de O(n 3 ), com n sendo o tamanho da cadeia de tokens. 10
AS Problemas de uma gramática Ambiguidade: uma gramática e ambígua quando é possível criar árvores de derivações diferentes para gerar a mesma palavra. Recursão à esquerda: quando o primeiro símbolo do lado direito da regra da produção é o mesmo não terminal do lado esquerdo da produção. Fatoração: quando existe um não-determinismo nas regras de produções da gramática. 11
Ambiguidade Uma gramática que produza mais de uma árvore gramática para alguma sentença é dita ambígua. A gramática para gerar palavras b*ab* G 1 G 2 G 3 S bs Sb a S bs aa S bs A A ba λ A Ab a S Sb S bs S bs S bs Sb bs aa A a a ba Ab λ a 12
Recursão a esquerda - Para eliminar a recursividade imediata a direita utilizaremos dois símbolos: α e β, estes símbolos representam sequência de terminais e não terminais que não inicia com o símbolo não terminal responsável pela recorrência. A Aα β Aα Aαα βααα A β X X αx λ 13
Recursão a esquerda - Produções da forma: A αβ 1 αβ 2 αβ 3 αβ 4 αβ 5... αβ n Não serve para reconhecedor por descida recursiva. Solução: adiar a decisão de qual alternativa a ser usada via fatoração. Esta técnica evita um não-determinismo. Regra heurística para se eliminar o não-determinismo. Sempre que A αβ1 αβ2... αβn onde as regras α λ e n 2, então deve-se substitui-las pelas regras A αx e X βi para i = 1,2,...,n, onde X será o novo não-terminal. 14
Análise Sintática - Métodos - Earley, em 1970, apresentou um método de A.S. Top- Down sem Backtracking que reconhece todas as GLCs com O(n3), mas se elas forem não ambíguas, o tempo é O(n2) e chega a ser O(n) para muitas linguagens; - Mais detalhes em : http://en.wikipedia.org/wiki/earley_parser 15
Análise Sintática - Métodos - Os métodos Top-Down e Bottom-Up mais eficientes e interessantes são determinísticos (O(n)). - Eles trabalham somente com subclasses de GLCs, por exemplo; - As gramáticas LL(k) e LR(k), são bastante utilizadas para descrever a maioria das linguagens de programação; 16
Análise Sintática - Métodos - LL(1): Left to left scan, Left-most derivation, 1token lookahead: Se, em cada entrada da Tabela de Análise, existe apenas uma produção, então a gramática é do tipo LL(1). - LR(1): Left to right scan, Right-most derivation, 1token look-ahead: A cadeia de símbolos já está devidamente empilhada e sintaticamente correta não sendo necessário realizar recursão; 17
Análise Sintática Descendente (Top-down) - Recursivo com retrocesso (backtracking); - Recursivo preditivo; - Tabular preditivo; 18
ASD - Recursivo com retrocesso - Foi usada em implementações pioneiras - Ainda é utilizada em aplicações específicas 19
ASD - Recursivo com retrocesso - Faz a expansão da árvore de derivação a partir da raiz, expandindo sempre o não-terminal mais à esquerda; - Quando existe mais de uma regra de produção para o não-terminal a ser expandido, a opção escolhida é a função do símbolo corrente na fia de entrada; - Se o token de entrada não define univocamente a produção a ser usada então todas as alternativas vão ser tentadas até que se obtenha sucesso, ou até que a análise falhe; 20
ASD - Recursivo com retrocesso 21
ASD - Recursivo com retrocesso - A utilização de retrocesso fará com que as ações de modificações da tabela de símbolos e possível geração de código em compiladores de 1 passo sejam anulados. Geralmente esta não é uma tarefa simples; - O número de derivações pode ser uma função exponencial do tamanho da cadeia; - Este algoritmo caracteriza derivações esquerdas de cadeias (substitui o terminal mais a esquerda) 22
ASD - Recursivo com retrocesso - A recursividade a esquerda não é permitida nos métodos de A.S.D. em geral; - Pela ineficiência e problemas, a análise descendente só é usada quando se elimina retrocesso; 23
1 Dada a gramática: Exercícios Analise as seguintes entradas: a) (id) b) id + id * id c) *id *id d) *id (id) e) ++ id (id) 24