Upload
vance
View
52
Download
0
Embed Size (px)
DESCRIPTION
CIn / UFPE. Algoritmos de Parsing. Gustavo Carvalho [email protected] Março 2011. 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 - PowerPoint PPT Presentation
Citation preview
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ódigo Otimização do Cód. Gerado
Tokens
AST
AST decorada
Cód. Interm.
Cód. Interm. Otimizado Cód. Objeto Cód. Objeto Otimizado
Front-end
Back-end
Compilador(1 ou N passos)
Erro
Erro
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ódigo Otimização do Cód. Gerado
Tokens
Front-end
Back-end
Interpretador
Erro
Erro
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 ::= ExpressaoExpressao ::= Valor | ExpUnaria | ExpBinariaValor ::= ValorConcretoValorConcreto ::= ValorInteiro | ValorBooleano | ValorStringExpUnaria ::= "-" Expressao | "not" Expressao | "length" ExpressaoExpBinaria ::= Expressao "+" Expressao
| Expressao "-" Expressao | Expressao "and" Expressao | Expressao "or" Expressao | Expressao "==" Expressao | Expressao "++" ExpressaoValorInteiro ::= [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: 2 + 3 (onde o todo é 2 + 3 + 5)
• Uma sentença – Frase cuja árvore começa a partir do símbolo inicial
• Exemplo: 2 + 3 (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 → Y1Y2…Yk para k >= 1
• Acrescente a em FIRST(X) se, para algum i, a estiver em FIRST(Yi)e ε estiver em todos os FIRST(Y1),…,FIRST(Yi-1)
• Acrescente ε a FIRST(X) se ε está em FIRST(Yj) 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 ::= ExpressaoExpressao ::= Valor | ExpUnaria | ExpBinariaValor ::= ValorConcretoValorConcreto ::= ValorInteiro | ValorBooleano | ValorStringExpUnaria ::= "-" Expressao | "not" Expressao | "length" ExpressaoExpBinaria ::= Expressao "+" Expressao
| Expressao "-" Expressao | Expressao "and" Expressao | Expressao "or" Expressao | Expressao "==" Expressao | Expressao "++" ExpressaoValorInteiro ::= [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 (utilizadas 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 = {anbncn | 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
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
• 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 ::= ExpressaoExpressao ::= Valor | ExpUnaria | ExpBinariaValor ::= ValorConcretoValorConcreto ::= ValorInteiro | ValorBooleano | ValorStringExpUnaria ::= "-" Expressao | "not" Expressao | "length" ExpressaoExpBinaria ::= Expressao "+" Expressao
| Expressao "-" Expressao | Expressao "and" Expressao | Expressao "or" Expressao | Expressao "==" Expressao | Expressao "++" ExpressaoValorInteiro ::= [1-9] [0-9]*ValorBooleano ::= "true" | "false"ValorString ::= ([A-Za-z] | [0-9])*
Programa ::= ExpressaoExpressao ::= ExpCondicionalOrExpCondicionalOr ::= ExpCondicionalOr "or" ExpCondicionalAnd | ExpCondicionalAndExpCondicionalAnd ::= ExpCondicionalAnd "and" ExpIgualdade | ExpIgualdadeExpIgualdade ::= ExpIgualdade "==" ExpAritmetica | ExpAritmeticaExpAritmetica ::= ExpAritmetica "+" ExpConcatenacao | ExpAritmetica "-" ExpConcatenacao | ExpConcatenacaoExpConcatenacao ::= ExpConcatenacao "++" ExpUnaria | ExpUnariaExpUnaria ::= "-" Expressao | "not" Expressao | "length" Expressao | ValorConcretoValorConcreto ::= ValorInteiro | ValorBooleano | ValorStringValorInteiro ::= [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 ::= ExpressaoExpressao ::= ExpCondicionalOr | ValorConcretoExpCondicionalOr ::= ExpCondicionalOr "or" ExpCondicionalAnd | ExpCondicionalAndExpCondicionalAnd ::= ExpCondicionalAnd "and" ExpIgualdade | ExpIgualdadeExpIgualdade ::= ExpIgualdade "==" ExpAritmetica | ExpAritmeticaExpAritmetica ::= ExpAritmetica "+" ExpConcatenacao | ExpAritmetica "-" ExpConcatenacao | ExpConcatenacaoExpConcatenacao ::= ExpConcatenacao "++" ExpUnaria | ExpUnariaExpUnaria ::= "-" Expressao | "not" Expressao | "length" ExpressaoValorConcreto ::= ValorInteiro | ValorBooleano | ValorStringValorInteiro ::= [1-9] [0-9]*ValorBooleano ::= "true" | "false"ValorString ::= ([A-Za-z] | [0-9])*
Programa ::= ExpressaoExpressao ::= ExpCondicionalOrExpCondicionalOr ::= ExpCondicionalAnd ( ("or" ExpCondicionalAnd)* | ε)?ExpCondicionalAnd ::= ExpIgualdade ( ("and" ExpIgualdade)* | ε)?ExpIgualdade ::= ExpAritmetica ( ("==" ExpAritmetica)* | ε)?ExpAritmetica ::= ExpConcatenacao ( (("+" | "-") ExpConcatenacao)* | ε)?ExpConcatenacao ::= ExpUnaria ( ("++" ExpUnaria)* | ε)?ExpUnaria ::= "-" Expressao | "not" Expressao | "length" Expressao | ValorConcretoValorConcreto ::= ValorInteiro | ValorBooleano | ValorStringValorInteiro ::= [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 ::= ExpressaoExpressao ::= ExpCondicionalOrExpCondicionalOr ::= ExpCondicionalAnd ( ("or" ExpCondicionalAnd)* | ε)?ExpCondicionalAnd ::= ExpIgualdade ( ("and" ExpIgualdade)* | ε)?ExpIgualdade ::= ExpAritmetica ( ("==" ExpAritmetica)* | ε)?ExpAritmetica ::= ExpConcatenacao ( (("+" | "-") ExpConcatenacao)* | ε)?ExpConcatenacao ::= ExpUnaria ( ("++" ExpUnaria)* | ε)?ExpUnaria ::= "-" Expressao | "not" Expressao | "length" Expressao | ValorConcretoValorConcreto ::= ValorInteiro | ValorBooleano | ValorStringValorInteiro ::= [1-9] [0-9]*ValorBooleano ::= "true" | "false"ValorString ::= ([A-Za-z] | [0-9])*
Programa ::= ExpressaoExpressao ::= ExpCondicionalOrExpCondicionalOr ::= ExpCondicionalAnd ( ("or" ExpCondicionalAnd)* | ε)?ExpCondicionalAnd ::= ExpIgualdade ( ("and" ExpIgualdade)* | ε)?ExpIgualdade ::= ExpAritmetica ( ("==" ExpAritmetica)? | ε)?ExpAritmetica ::= ExpConcatenacao ( (("+" | "-") ExpConcatenacao)* | ε)?ExpConcatenacao ::= ExpUnaria ( ("++" ExpUnaria)* | ε)?ExpUnaria ::= "-" Expressao | "not" Expressao | "length" Expressao | ValorConcretoValorConcreto ::= ValorInteiro | ValorBooleano | ValorStringValorInteiro ::= [1-9] [0-9]*ValorBooleano ::= "true" | "false"ValorString ::= ([A-Za-z] | [0-9])*
21
Recursive Descent ParserPrograma ::= ExpressaoExpressao ::= ExpCondicionalOrExpCondicionalOr ::= ExpCondicionalAnd ( ("or" ExpCondicionalAnd)* | ε)?ExpCondicionalAnd ::= ExpIgualdade ( ("and" ExpIgualdade)* | ε)?ExpIgualdade ::= ExpAritmetica ( ("==" ExpAritmetica)? | ε)?ExpAritmetica ::= ExpConcatenacao ( (("+" | "-") ExpConcatenacao)* | ε)?ExpConcatenacao ::= ExpUnaria ( ("++" ExpUnaria)* | ε)?ExpUnaria ::= "-" Expressao | "not" Expressao | "length" Expressao | ValorConcretoValorConcreto ::= 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 ::= ExpressaoExpressao ::= ExpCondicionalOrExpCondicionalOr ::= ExpCondicionalAnd ( ("or" ExpCondicionalAnd)* | ε)?ExpCondicionalAnd ::= ExpIgualdade ( ("and" ExpIgualdade)* | ε)?ExpIgualdade ::= ExpAritmetica ( ("==" ExpAritmetica)? | ε)?ExpAritmetica ::= ExpConcatenacao ( (("+" | "-") ExpConcatenacao)* | ε)?ExpConcatenacao ::= ExpUnaria ( ("++" ExpUnaria)* | ε)?ExpUnaria ::= "-" Expressao | "not" Expressao | "length" Expressao | ValorConcretoValorConcreto ::= 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 ::= ExpressaoExpressao ::= ExpCondicionalOrExpCondicionalOr ::= ExpCondicionalAnd ( ("or" ExpCondicionalAnd)* | ε)?ExpCondicionalAnd ::= ExpIgualdade ( ("and" ExpIgualdade)* | ε)?ExpIgualdade ::= ExpAritmetica ( ("==" ExpAritmetica)? | ε)?ExpAritmetica ::= ExpConcatenacao ( (("+" | "-") ExpConcatenacao)* | ε)?ExpConcatenacao ::= ExpUnaria ( ("++" ExpUnaria)* | ε)?ExpUnaria ::= "-" Expressao | "not" Expressao | "length" Expressao | ValorConcretoValorConcreto ::= 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• 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: 2 + 3 $
– 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 | FatorFator ::= ValorInteiro E → E + T | T
T → T * F | FF → ( E ) | id
De formamais geral …
PILHA ENTRADA AÇÃ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 → X•YZ, A → XY•Z, A → XYZ•• A → ε, A → •
– Item LR(1) é um item LR(0) mais o terminal ou $ que pode seguir• A → X•Y, 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 | FatorFator ::= ValorInteiro
Exp’ ::= ExpExp ::= Exp "+" Fator | FatorFator ::= 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’ -> • ExpExp -> • Exp “+” FatorExp -> • FatorFator -> • ValorInteiro
Exp’ -> Exp •Exp -> Exp • “+” Fator
Exp
$
accept
Exp -> Exp “+” • FatorFator -> • ValorInteiro
“+”
Exp -> Exp “+” Fator •
Fator
Fator -> ValorInteiro •
ValorInteiro
Exp -> Fator •Fator
ValorInteiro
I0 I1 I2
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.
ACTION GOTO
+ ValInteiro $ Exp Fator
0 s4 1 5
1 s2 accept
2 s4 3
3 r1 r1
4 r3 r3
5 r2 r2
Exp’ ::= ExpExp ::= 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 pilhaempilhe 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.
ACTION GOTO
+ ValInteiro $ Exp Fator
0 s4 1 5
1 s2 accept
2 s4 3
3 r1 r1
4 r3 r3
5 r2 r2
32
Gramáticas SLR• Exemplo:
– Para o nosso exemplo• 2 + 3 $
LINHA PILHA SÍMBOLOS ENTRADA AÇÃO
1 0 $ 2 + 3 $ Shift 4
2 0 4 $ 2 + 3 $ Reduce 3
3 0 5 $ Fator + 3 $ Reduce 2
4 0 1 $ Exp + 3 $ Shift 2
5 0 1 2 $ Exp + 3 $ Shift 4
6 0 1 2 4 $ Exp + 4 $ Reduce 3
7 0 1 2 3 $ Exp + Fator $ Reduce 1
8 0 1 $ Exp $ accept
Exp’ ::= ExpExp ::= Exp "+" Fator (1) | Fator (2)Fator ::= ValorInteiro (3)
EST.
ACTION GOTO
+ ValInteiro $ Exp Fator
0 s4 1 5
1 s2 accept
2 s4 3
3 r1 r1
4 r3 r3
5 r2 r2
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’ → SS → L=R | RL → *R | idR → 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