1 CIn / UFPE Algoritmos de Parsing Gustavo Carvalho Março 2011.

Slides:



Advertisements
Apresentações semelhantes
Software Básico Silvio Fernandes
Advertisements

Tópicos em Compiladores
5.5 – Análise Bottom-Up Tentativa de construir uma árvore sintática para a sentença analisada, começando das folhas, indo em direção à raiz (pós-ordem.
Compiladores Claudio Benossi
III – Análise sintáctica
III – Análise sintáctica
III – Análise sintáctica
III – Análise sintáctica Parsers ascendentes Instruções shift-reduce Bibliografia aconselhada: –Aho, Sethi e Ullman – secção 4.5 LFA 1999/ Jorge.
III – Análise sintáctica
III – Análise sintáctica Geradores de parsers Bibliografia aconselhada: –Aho, Sethi e Ullman – secção 4.9 LFA 1999/ Jorge Morais.
Compiladores I Cristiano Damiani Vasconcellos
Compiladores FIC– Ciência da Computação Professor: Ciro Meneses Santos
Deyvisson, Rafael M.P., Renato, Robson C.F., Rodolfo
Análise Sintática Ascendente ­
Software Básico Silvio Fernandes
Curso Sistemas de Informação Disciplina: Arquitetura de Software
Análise Sintática Ascendente
Relações em uma Gramática
Linguagem de Prog. e Programas
Construção de Compiladores
Construção de Compiladores
Construção de Compiladores
5.6 – Complementos de Yacc – Usando Yacc com gramáticas ambíguas
Denis Pinheiro Teoria de Linguagens Prof. Newton José Vieira
Implementar Listas em Linguagem Funcional II
Análise léxica e sintática
Aula prática - análise contextual
Definição de tipos - LF3Definição de tipos - LF3 PLP - Apresentação 1.
Determinar o tipo de gramática
Compiladores, Aula Nº 19 João M. P. Cardoso
Compiladores, Aula Nº 9 João M. P. Cardoso
Gramáticas Livres de Contexto
Teoria e Implementação de Linguagens Computacionais
Teoria e Implementação de Linguagens Computacionais – IF688
Sintaxe e Semântica Prof.: Gláucya Carreiro Boechat
Estudo dos Conceitos e Paradigmas de Programação
Análises léxica e sintática
Análise Léxica e Sintática
Aulão de Linguagens Formais e Compiladores
Capítulo II Gramáticas e Linguagens
Analise sintática aula-07-analise-sintática.pdf.
Análise Sintática LR Prof. Alexandre Monteiro
Análises léxica e sintática
Analise Semântica aula-10-analise-semântica.pdf.
Aula sobre JavaCC Parsing Tarciana Dias Abril 2013.
Compiladores.
Análise Sintática Prof. Alexandre Monteiro
Tradução Dirigida por Sintaxe
Aula 18 1 Análise Sintáctica Compiladores, Aula Nº 18 João M. P. Cardoso.
Mas para que serve um analisador sintático? Verificar se a estrutura gramatical do programa está correta Escrito de outra forma: O texto segue as regras.
Revisão Compiladores – AP2
Análise Sintática de Descida Recursiva
Compiladores Análise Sintática
Aula de SableCC Teoria e Implementação de Linguagens Computacionais (Compiladores) - IF688 – Artur Ribeiro de Aquino – ara Allan Jefferson – ajss.
COMPILADORES 04 Prof. Marcos.
Um Tradutor Dirigido por Sintaxe Simples
Semântica de Linguagens de Programação
1 CIn / UFPE Parsing Tarciana Dias / Gustavo Carvalho / Março 2012.
Compiladores – IF688 Professor: André Santos
JavaCC.
Compiladores Análise Sintática
Sintaxe de uma Linguagem
PLP – JavaCC Java Compiler Compiler
Teoria e Implementação de Linguagens Computacionais Revisão 1º EE André Ricardo Schäffer Lopes – Rodrigo Diego Melo Amorim–
Analisador sintático: Tipos de análises sintáticas
Compilador Software que traduz o texto (linguagem fonte) que representa um programa para código máquina(linguagem alvo) capaz de ser executado pelo.
Faculdade Pernambuca - FAPE Compiladores Abril/2007 Compiladores Abril/2007.
1 CIn / UFPE Introdução a Parsing Gustavo Carvalho Abril 2015.
Transcrição da apresentação:

1 CIn / UFPE Algoritmos de Parsing Gustavo Carvalho Março 2011

2 Motivação… Em Paradigmas de Linguagens de Programação (PLP) –Conhecer e manipular diferentes paradigmas de programação –Ser capaz de processar (reconhecer) código nestes paradigmas Código sintaticamente correto para uma linguagem… –Análise sintática = parsing Uma das etapas do processo de compilação Uso do JavaCC = gerador automático de parsers –Em particular… »Um parser LL(1) – na maioria dos casos »Um parser LL(k) – em alguns casos Mas… –O que é LL(1), LL(k)? E SLR, LR(1), LALR? –Como funciona o JavaCC? E o o SableCC?

3 Roteiro Processo de Compilação Conceitos Básicos Estratégias de Parsing Gramáticas LL Gramáticas LR Exemplo Prático Referências

4 Processo de Compilação Análise Léxica (Scanning) Análise Sintática (Parsing) Análise Semântica Ger. Código Intermediário Otimização Cód. Interm. Geração de CódigoOtimização do Cód. Gerado Tokens AST AST decorada Cód. Interm. Cód. Interm. OtimizadoCód. ObjetoCód. Objeto Otimizado Front-end Back-end Compilador (1 ou N passos) Erro

5 Processo de Interpretação Análise Léxica (Scanning) Análise Sintática (Parsing) Análise Semântica Ger. Código Intermediário Otimização Cód. Interm. Geração de CódigoOtimização do Cód. Gerado Tokens Front-end Back-end Interpretador Erro Fetch => Analyze => Execute Saídas de forma imediata Talvez não precise de AST Não traduz programa fonte para código objeto (a priori) Ideal (melhor desempenho): instruções com formato simplificado (bytecode) Execução

6 Roteiro Processo de Compilação Conceitos Básicos Estratégias de Parsing Gramáticas LL Gramáticas LR Exemplo Prático Referências

7 Conceitos Básicos Gramáticas livres de contexto (GLC) –Notação BNF: Backus-Naur Form EBNF: Extended Backus-Naur Form G = (V, Σ, R, S) –Conjunto finito de símbolos não-terminais (V) Uma classe particular de frases de uma linguagem Ex.: Programa, Expressao, Valor –Conjunto finito de símbolos terminais (Σ), disjunto de V Símbolos atômicos Ex.: ‘ 23 ’, ‘ + ’, ‘ - ‘, ‘ and ’ –Conjunto finito de regras de produção (R) Sob a forma A → β onde A V e β (V U Σ)* –Símbolo inicial (um dos símbolos de V) (S) Ex.: Programa

8 Conceitos Básicos Exemplo –Terminais +, -, not, length, and, or, ==, ++, 0, …, 9, a, …, z, A, …, Z –Não-terminais Programa, Expressao, Valor, ExpUnaria, ExpBinaria, ValorConcreto, ValorInteiro, ValorBooleano, ValorString –Produções Programa ::= Expressao Expressao ::= Valor | ExpUnaria | ExpBinaria Valor ::= ValorConcreto ValorConcreto ::= ValorInteiro | ValorBooleano | ValorString ExpUnaria ::= "-" Expressao | "not" Expressao | "length" Expressao ExpBinaria ::= Expressao "+" Expressao | Expressao "-" Expressao | Expressao "and" Expressao | Expressao "or" Expressao | Expressao "==" Expressao | Expressao "++" Expressao ValorInteiro ::= [1-9] [0-9]* ValorBooleano ::= "true" | "false" ValorString ::= ([A-Za-z] | [0-9])*

9 Conceitos Básicos Uma árvore sintática para uma gramática G –Árvore com labels em que: As folhas são símbolos terminais Os nós são símbolos não-terminais Uma frase de G –Seqüência de terminais de uma árvore sintática (esquerda p/ direita) Exemplo: (onde o todo é ) Uma sentença –Frase cuja árvore começa a partir do símbolo inicial Exemplo: (onde o todo é 2 + 3) Linguagem gerada por G: todas as sentenças de G Árvore sintática abstrata (AST) –Não gera frases (não mapeia todos os símbolos terminais) De forma geral: identificadores, operadores, literais e números

10 Conceitos Básicos FIRST(X) –Se X é um terminal, FIRST(X) = {X} –Se X é um não-terminal e X → Y 1 Y 2 …Y k para k >= 1 Acrescente a em FIRST(X) se, para algum i, a estiver em FIRST(Y i ) e ε estiver em todos os FIRST(Y 1 ),…,FIRST(Y i-1 ) Acrescente ε a FIRST(X) se ε está em FIRST(Y j ) para todo j = 1…k –Se X → ε é uma produção, então acrescente ε a FIRST(X) FOLLOW(X) –Coloque $ em FOLLOW(S), onde S é o símbolo inicial e $ é o marcador de fim da entrada (arquivo) –Se A → αBβ, tudo em FIRST(β), exceto ε, está em FOLLOW(B) –Se A → αB, ou A → αBβ onde FIRST(β) contém ε, então inclua FOLLOW(A) em FOLLOW(B)

11 Conceitos Básicos Exemplo –Para a gramática… –FIRST(ExpUnaria) = {-, not, length} –FOLLOW(Expressao) = {+, -, and, or, ==, ++, $} Programa ::= Expressao Expressao ::= Valor | ExpUnaria | ExpBinaria Valor ::= ValorConcreto ValorConcreto ::= ValorInteiro | ValorBooleano | ValorString ExpUnaria ::= "-" Expressao | "not" Expressao | "length" Expressao ExpBinaria ::= Expressao "+" Expressao | Expressao "-" Expressao | Expressao "and" Expressao | Expressao "or" Expressao | Expressao "==" Expressao | Expressao "++" Expressao ValorInteiro ::= [1-9] [0-9]* ValorBooleano ::= "true" | "false" ValorString ::= ([A-Za-z] | [0-9])*

12 Conceitos Básicos Importante! –GLC = como o nome já diz, não captura contexto Restrições de tipo e escopo: preocupação do analisador semântico Hierarquia de Chomsky –Tipo 3: gramáticas regulares (u tilizadas pelo analisador léxico) –Tipo 2: gramáticas livres de contexto –Tipo 1: gramáticas sensíveis ao contexto α → β onde A (V U Σ) +, c/ 1 ou mais símbolos de V, e β (V U Σ)* | α| <= |β|, exceto para eventual S → ε Exemplo: L = {a n b n c n | n >= 1} –S→ abc|aAbc, Ab→bA, Ac→Bbcc, bB→Bb, aB→ aa|aaA –Tipo 0: gramáticas irrestritas Exemplo: S→ abc, ab→aabbC, Cb→bC, c→cc Tipo 0 Tipo 1 Tipo 2 Tipo 3

13 Roteiro Processo de Compilação Conceitos Básicos Estratégias de Parsing Gramáticas LL Gramáticas LR Exemplo Prático Referências

14 Estratégias de Parsing Objetivo –Determinar se uma seqüência de tokens formam uma sentença da gramática –Gramática não ambígua: cada sentença tem exatamente uma syntax tree Top-Down –Examina os símbolos terminais da esquerda para a direita –Forma a ST (syntax tree) de cima para baixo –Parsing ok: string de entrada totalmente conectada à ST L(eft-to-right) L(eft-most-derivation) => LL Bottom-Up –Examina os símbolos terminais da esquerda para a direita –Forma a ST (syntax tree) de baixo para cima –Parsing ok: string de entrada reduzida a uma S-tree S(imple) L(eft-to-right) R(ight-most-derivation) => SLR L(eft-to-right) R(ight-most-derivation) => LR L(ook) A(head) L(eft-to-right) R(ight-most-derivation) => LALR

15 Roteiro Processo de Compilação Conceitos Básicos Estratégias de Parsing Gramáticas LL Gramáticas LR Exemplo Prático Referências

16 Gramáticas LL –Processadas por parsers top-down –Expande as produções mais à esquerda Dificuldades: Soluções: –Refatorar a gramática (nem sempre possível tornar uma gramática LL) »Fatoração à esquerda: N ::= XY | XZ  N ::= X (Y | Z) »Eliminação de recursão à esquerda: N ::= NY | X  N ::= X (Y)* –Fazer backtrack –Olhar para mais de um símbolo: LL(k) single-Command ::= if Expression then single-Command | if Expression then single-Command else single-Command Expression ::= Expression + Value | Value single-Command ::= if Expression then single-Command ( ε | else single-Command ) Expression ::= Value (+ Value)*

17 Gramáticas LL(1) LL(1) = LL(k) onde k = 1 –Em BNF, se não quiser backtrack, para toda produção A → α | β FIRST(α) ∩ FIRST(β) = Ø ε FIRST(α) → FIRST(β) ∩ FOLLOW(A) = Ø ε FIRST(β) → FIRST(α) ∩ FOLLOW(A) = Ø Recursive Descent Parser –Algoritmo de parsing para gramáticas LL Versão específica para LL(1) e sem retrocesso –Visão geral Para cada produção N, crie um método parseN Crie uma classe parser com um atributo currentToken –E os métodos parseN –E os métodos auxiliares: accept e acceptIt –E um método público parse que chama parseS O código de cada método parseN depende da produção N A árvore é dada implicitamente pela chamada dos métodos –Pode ser criada explicitamente

18 Recursive Descent Parser Refatorando… –Tirando ambigüidade (várias árvores sintáticas para mesma frase) a - b + c == a - (b + c) ou (a - b) + c ? E ::= E “+” T | T, T ::= T “*” F | F, F ::= … Programa ::= Expressao Expressao ::= Valor | ExpUnaria | ExpBinaria Valor ::= ValorConcreto ValorConcreto ::= ValorInteiro | ValorBooleano | ValorString ExpUnaria ::= "-" Expressao | "not" Expressao | "length" Expressao ExpBinaria ::= Expressao "+" Expressao | Expressao "-" Expressao | Expressao "and" Expressao | Expressao "or" Expressao | Expressao "==" Expressao | Expressao "++" Expressao ValorInteiro ::= [1-9] [0-9]* ValorBooleano ::= "true" | "false" ValorString ::= ([A-Za-z] | [0-9])* Programa ::= Expressao Expressao ::= ExpCondicionalOr ExpCondicionalOr ::= ExpCondicionalOr "or" ExpCondicionalAnd | ExpCondicionalAnd ExpCondicionalAnd ::= ExpCondicionalAnd "and" ExpIgualdade | ExpIgualdade ExpIgualdade ::= ExpIgualdade "==" ExpAritmetica | ExpAritmetica ExpAritmetica ::= ExpAritmetica "+" ExpConcatenacao | ExpAritmetica "-" ExpConcatenacao | ExpConcatenacao ExpConcatenacao ::= ExpConcatenacao "++" ExpUnaria | ExpUnaria ExpUnaria ::= "-" Expressao | "not" Expressao | "length" Expressao | ValorConcreto ValorConcreto ::= ValorInteiro | ValorBooleano | ValorString ValorInteiro ::= [1-9] [0-9]* ValorBooleano ::= "true" | "false" ValorString ::= ([A-Za-z] | [0-9])*

19 Recursive Descent Parser Refatorando… agora é LL(1) –Eliminando recursão à esquerda E ::= E “+” T | T ≡ E ::= TE’, E’ ::= “+” T E’ | ε ≡ E ::= T ( (“+” T)* | ε)? Programa ::= Expressao Expressao ::= ExpCondicionalOr | ValorConcreto ExpCondicionalOr ::= ExpCondicionalOr "or" ExpCondicionalAnd | ExpCondicionalAnd ExpCondicionalAnd ::= ExpCondicionalAnd "and" ExpIgualdade | ExpIgualdade ExpIgualdade ::= ExpIgualdade "==" ExpAritmetica | ExpAritmetica ExpAritmetica ::= ExpAritmetica "+" ExpConcatenacao | ExpAritmetica "-" ExpConcatenacao | ExpConcatenacao ExpConcatenacao ::= ExpConcatenacao "++" ExpUnaria | ExpUnaria ExpUnaria ::= "-" Expressao | "not" Expressao | "length" Expressao ValorConcreto ::= ValorInteiro | ValorBooleano | ValorString ValorInteiro ::= [1-9] [0-9]* ValorBooleano ::= "true" | "false" ValorString ::= ([A-Za-z] | [0-9])* Programa ::= Expressao Expressao ::= ExpCondicionalOr ExpCondicionalOr ::= ExpCondicionalAnd ( ("or" ExpCondicionalAnd)* | ε)? ExpCondicionalAnd ::= ExpIgualdade ( ("and" ExpIgualdade)* | ε)? ExpIgualdade ::= ExpAritmetica ( ("==" ExpAritmetica)* | ε)? ExpAritmetica ::= ExpConcatenacao ( (("+" | "-") ExpConcatenacao)* | ε)? ExpConcatenacao ::= ExpUnaria ( ("++" ExpUnaria)* | ε)? ExpUnaria ::= "-" Expressao | "not" Expressao | "length" Expressao | ValorConcreto ValorConcreto ::= ValorInteiro | ValorBooleano | ValorString ValorInteiro ::= [1-9] [0-9]* ValorBooleano ::= "true" | "false" ValorString ::= ([A-Za-z] | [0-9])*

20 Recursive Descent Parser Refatorando… continua LL(1) –Fazendo uma última alteração Programa ::= Expressao Expressao ::= ExpCondicionalOr ExpCondicionalOr ::= ExpCondicionalAnd ( ("or" ExpCondicionalAnd)* | ε)? ExpCondicionalAnd ::= ExpIgualdade ( ("and" ExpIgualdade)* | ε)? ExpIgualdade ::= ExpAritmetica ( ("==" ExpAritmetica)* | ε)? ExpAritmetica ::= ExpConcatenacao ( (("+" | "-") ExpConcatenacao)* | ε)? ExpConcatenacao ::= ExpUnaria ( ("++" ExpUnaria)* | ε)? ExpUnaria ::= "-" Expressao | "not" Expressao | "length" Expressao | ValorConcreto ValorConcreto ::= ValorInteiro | ValorBooleano | ValorString ValorInteiro ::= [1-9] [0-9]* ValorBooleano ::= "true" | "false" ValorString ::= ([A-Za-z] | [0-9])* Programa ::= Expressao Expressao ::= ExpCondicionalOr ExpCondicionalOr ::= ExpCondicionalAnd ( ("or" ExpCondicionalAnd)* | ε)? ExpCondicionalAnd ::= ExpIgualdade ( ("and" ExpIgualdade)* | ε)? ExpIgualdade ::= ExpAritmetica ( ("==" ExpAritmetica)? | ε)? ExpAritmetica ::= ExpConcatenacao ( (("+" | "-") ExpConcatenacao)* | ε)? ExpConcatenacao ::= ExpUnaria ( ("++" ExpUnaria)* | ε)? ExpUnaria ::= "-" Expressao | "not" Expressao | "length" Expressao | ValorConcreto ValorConcreto ::= ValorInteiro | ValorBooleano | ValorString ValorInteiro ::= [1-9] [0-9]* ValorBooleano ::= "true" | "false" ValorString ::= ([A-Za-z] | [0-9])*

21 Recursive Descent Parser Programa ::= Expressao Expressao ::= ExpCondicionalOr ExpCondicionalOr ::= ExpCondicionalAnd ( ("or" ExpCondicionalAnd)* | ε)? ExpCondicionalAnd ::= ExpIgualdade ( ("and" ExpIgualdade)* | ε)? ExpIgualdade ::= ExpAritmetica ( ("==" ExpAritmetica)? | ε)? ExpAritmetica ::= ExpConcatenacao ( (("+" | "-") ExpConcatenacao)* | ε)? ExpConcatenacao ::= ExpUnaria ( ("++" ExpUnaria)* | ε)? ExpUnaria ::= "-" Expressao | "not" Expressao | "length" Expressao | ValorConcreto ValorConcreto ::= ValorInteiro | ValorBooleano | ValorString accept(int type) { if ( currentToken.getType() == type ) { currentToken = scanner.getNextToken(); } else { // ERRO } acceptIt() { currentToken = scanner.getNextToken(); } Métodos auxiliares

22 Recursive Descent Parser parsePrograma() parseExpressao(); } parseExpressao() { parseExpCondicionalOr(); } parseExpCondicionalOr() { parseExpCondicionalAnd(); while ( currentToken.getType() == Token.OR ) { acceptIt(); parseExpCondicionalAnd(); } parseExpIgualdade() { parseExpAritmetica(); if ( currentToken.getType() == Token.EQUAL ) { acceptIt(); parseExpAritmetica(); } Programa ::= Expressao Expressao ::= ExpCondicionalOr ExpCondicionalOr ::= ExpCondicionalAnd ( ("or" ExpCondicionalAnd)* | ε)? ExpCondicionalAnd ::= ExpIgualdade ( ("and" ExpIgualdade)* | ε)? ExpIgualdade ::= ExpAritmetica ( ("==" ExpAritmetica)? | ε)? ExpAritmetica ::= ExpConcatenacao ( (("+" | "-") ExpConcatenacao)* | ε)? ExpConcatenacao ::= ExpUnaria ( ("++" ExpUnaria)* | ε)? ExpUnaria ::= "-" Expressao | "not" Expressao | "length" Expressao | ValorConcreto ValorConcreto ::= ValorInteiro | ValorBooleano | ValorString parse () { parsePrograma(); if ( currentToken.getType() != Token.EOT ) { // ERRO }

23 Recursive Descent Parser parseExpUnaria() { if ( currentToken.getType() == Token.MINUS ) { acceptIt(); parseExpressao(); } else if ( currentToken.getType() == Token.NOT ) { acceptIt(); parseExpressao(); } else if ( currentToken.getType() == Token.LENGTH ) { acceptIt(); parseExpressao(); } else { parseValorConcreto(); } Programa ::= Expressao Expressao ::= ExpCondicionalOr ExpCondicionalOr ::= ExpCondicionalAnd ( ("or" ExpCondicionalAnd)* | ε)? ExpCondicionalAnd ::= ExpIgualdade ( ("and" ExpIgualdade)* | ε)? ExpIgualdade ::= ExpAritmetica ( ("==" ExpAritmetica)? | ε)? ExpAritmetica ::= ExpConcatenacao ( (("+" | "-") ExpConcatenacao)* | ε)? ExpConcatenacao ::= ExpUnaria ( ("++" ExpUnaria)* | ε)? ExpUnaria ::= "-" Expressao | "not" Expressao | "length" Expressao | ValorConcreto ValorConcreto ::= ValorInteiro | ValorBooleano | ValorString parseValorConcreto() { if ( currentToken.getType() == Token.INT ) { acceptIt(); } else if ( currentToken.getType() == Token.BOOLEAN ) { acceptIt(); } else { accept(Token.STRING); }

24 Roteiro Processo de Compilação Conceitos Básicos Estratégias de Parsing Gramáticas LL Gramáticas LR Exemplo Prático Referências

25 Gramáticas LR –Não possuem as restrições da LL A priori, a gramática não deve ser ambígua –Faz necessariamente uso explícito de uma pilha Abordagem Shift-Reduce –4 ações Shift –Transfere símbolos para pilha até que um handle seja encontrado »Handle: subcadeia que casa com o corpo de uma produção e cuja redução para o não-terminal do lado esquerdo representa um passo da derivação à direita ao inverso Reduce –Quando um handle é identificado reduz este (desempilha) para o não terminal do lado esquerdo (empilha) que representa a produção correspondente Accept –Conclui o parsing Error –Identifica uma situação de erro

26 Gramáticas LR Exemplo –Gramática –Entrada: $ –Simulação (grifado = handle) Como identificar handles? Quando fazer shift? Quando fazer reduce? –Tabela de parsing = diz quando fazer shift, reduce ou accept! Exp ::= Exp "+" Fator | Fator Fator ::= ValorInteiro E → E + T | T T → T * F | F F → ( E ) | id De forma mais geral … PILHAENTRADAAÇÃO $2 + 3 $Shift $ 2+ 3 $Reduz segundo Fator → ValorInteiro $ Fator+ 3 $Reduz segundo Exp → Fator $ Exp+ 3 $Shift $ Exp +3 $Shift $ Exp + 3$Reduz segundo Fator → ValorInteiro $ Exp + Fator$Reduz segundo Exp → Exp + Fator $ Exp$Accept

27 Gramáticas LR Mecanismos de construção da tabela de parsing –SLR => LR(0) (mais fácil de implementar, conflitos s/r e r/r) –LR Canônico => LR(1) (muitos estados, sem conflitos) –LALR => Otimização do LR Canônico (poucos estados, conflitos r/r) Conceito básico: item (o que já foi visto e o que se espera ver) –Item LR(0) é uma produção de G com um ponto em alguma posição A → XYZ => A → XYZ, A → XYZ, A → XYZ, A → XYZ A → ε, A → –Item LR(1) é um item LR(0) mais o terminal ou $ que pode seguir A → XY, a onde a ∑ U {$} Idéia geral do SLR –Autômato cujos estados representam/armazenam itens LR(0) –Reduções são realizadas a partir do FOLLOW

28 Gramáticas SLR Exemplo: –Se G é uma gramática, G’ será sua gramática estendida S’ → S (antigo símbolo inicial) –Ao iniciar, temos S’ → S –Fechamento de um conjunto de itens => CLOSURE(I) Acrescente todo item I em CLOSURE(I) Se A → αBβ está em CLOSURE(I) e B → γ é uma produção, então adicione o item B → γ em CLOSURE(I), se ele ainda não estiver lá. Aplique essa regra até que nenhum outro item possa ser incluído em CLOSURE(I) –Para o nosso exemplo, o estado inicial do autômato seria E’ → Exp Exp → Exp “+” Fator Exp → Fator Fator → ValorInteiro Exp ::= Exp "+" Fator | Fator Fator ::= ValorInteiro Exp’ ::= Exp Exp ::= Exp "+" Fator | Fator Fator ::= ValorInteiro

29 Gramáticas SLR Exemplo: –Autômato: do estado inicial, identificar para que estados pode-se ir consumindo o próximo símbolo (terminal ou não-terminal) Calcular o CLOSURE(I) para cada um destes estados Exp’ -> Exp Exp -> Exp “+” Fator Exp -> Fator Fator -> ValorInteiro Exp’ -> Exp Exp -> Exp “+” Fator Exp $ accept Exp -> Exp “+” Fator Fator -> ValorInteiro “+” Exp -> Exp “+” Fator Fator Fator -> ValorInteiro ValorInteiro Exp -> Fator Fator ValorInteiro I0I1I2 I3 I4 I5

30 Gramáticas SLR Exemplo: –Monta-se a tabela de parsing Transições do autômato: terminais (shifts na action) e não-terminais (goto) Reduces a partir do FOLLOW e dos estados com mais à direita –FOLLOW(Exp) = FOLLOW(Fator) = {+, $} EST. ACTIONGOTO +ValInteiro$ExpFator 0s415 1s2accept 2s43 3r1 4r3 5r2 Exp’ ::= Exp Exp ::= Exp "+" Fator (1) | Fator (2) Fator ::= ValorInteiro (3)

31 Seja a o primeiro símbolo de w$ while (1) { seja s o estado no topo da pilha; if ( ACTION[s,a] = shift t ) { empilha t na pilha; seja a o próximo símbolo da entrada; } else if ( ACTION[s,a] = reduce A → β ) { desempilha símbolos |β| da pilha; faça o estado t agora ser o topo da pilha empilhe GOTO[t,A] na pilha; } else if ( ACTION[s,a] == accept) { código bem formado; break; } else { erro sintático!! } Gramáticas SLR Exemplo: –Algoritmo de parsing O mesmo para todos os LR EST. ACTIONGOTO +ValInteiro$ExpFator 0s415 1s2accept 2s43 3r1 4r3 5r2

32 Gramáticas SLR Exemplo: –Para o nosso exemplo $ LINHAPILHASÍMBOLOSENTRADAAÇÃO 10$2 + 3 $Shift $ 2+ 3 $Reduce $ Fator+ 3 $Reduce $ Exp+ 3 $Shift $ Exp +3 $Shift $ Exp + 4$Reduce $ Exp + Fator$Reduce $ Exp$accept Exp’ ::= Exp Exp ::= Exp "+" Fator (1) | Fator (2) Fator ::= ValorInteiro (3) EST. ACTIONGOTO +ValInteiro$ExpFator 0s415 1s2accept 2s43 3r1 4r3 5r2

33 Gramáticas LR Problema da abordagem SLR –Pode haver conflitos s/r e r/r –Solução: LR(1) Sem conflitos, mas com muitos estados Para uma linguagem feito C… –# estados SLR == LALR (sempre) ~ centenas de estados –# estados LR(1) ~ milhares de estados LALR –Idéia básica: gerar autômato LR(1) e agrupar estados Pode introduzir conflitos R/R –Resolvidos pela tabela de precedência da linguagem –Idéia mais elaborada: gerar autômato LALR direto a partir da gramática Árvore sintática é dada implicitamente pela evolução da pilha S’ → S S → L=R | R L → *R | id R → L

34 Roteiro Processo de Compilação Conceitos Básicos Estratégias de Parsing Gramáticas LL Gramáticas LR Exemplo Prático Referências

35 Exemplo Prático

36 Roteiro Processo de Compilação Conceitos Básicos Estratégias de Parsing Gramáticas LL Gramáticas LR Exemplo Prático Referências

37 Referências WATT, D.; BROWN, D. Programming Language Processors in Java. –Capítulo 4 Foco maior na abordagem LL AHO, A.; LAM, M.; SETHI, R.; ULLMAN, J. Compilers: Principles, Techniques & Tools. –Capítulo 4 Foco maior na abordagem LR

38 CIn / UFPE Algoritmos de Parsing Gustavo Carvalho Março 2011