Post on 30-Dec-2015
description
CES-41 CES-41 COMPILADORESCOMPILADORES
Capítulo VCapítulo V
Análise SintáticaAnálise Sintática
Capítulo V – Análise Capítulo V – Análise SintáticaSintática
5.1 – Classificação dos analisadores 5.1 – Classificação dos analisadores sintáticossintáticos
5.2 – Tratamento de gramáticas5.2 – Tratamento de gramáticas
5.3 – Escolha de uma derivação5.3 – Escolha de uma derivação
5.4 – Análise top-down5.4 – Análise top-down
5.5 – Análise bottom-up5.5 – Análise bottom-up
5.6 – Complementos de Yacc5.6 – Complementos de Yacc
5.1 – Classificação dos 5.1 – Classificação dos Analisadores SintáticosAnalisadores Sintáticos
Papel do analisador sintático Papel do analisador sintático (visto (visto anteriormente):anteriormente):
– Verificar a Verificar a estrutura sintáticaestrutura sintática de um de um programaprograma
– Detectar, sinalizar e tratar Detectar, sinalizar e tratar erros erros sintáticossintáticos
– Servir de Servir de esqueletoesqueleto para o para o front-endfront-end
ClassesClasses de de métodosmétodos de análise sintática: de análise sintática:
– Analisadores Analisadores universaisuniversais– Analisadores Analisadores top-downtop-down– Analisadores Analisadores bottom-upbottom-up
Analisadores universais:Analisadores universais:
– Conseguem analisar Conseguem analisar qualquer GLCqualquer GLC– São muito São muito ineficientesineficientes para uso em para uso em
compiladores compiladores
Analisadores Analisadores top-downtop-down e e bottom-upbottom-up::
– Varrem o programa Varrem o programa da esquerda para a da esquerda para a direitadireita, um símbolo de cada vez; alguns , um símbolo de cada vez; alguns deles por vezes precisam deles por vezes precisam voltarvoltar da direita da direita para a esquerdapara a esquerda
– Englobam os métodos Englobam os métodos mais comumente mais comumente usadosusados em compiladores em compiladores
– Os métodos Os métodos mais eficientesmais eficientes trabalham trabalham apenas com apenas com subclasses subclasses de gramáticasde gramáticas
– Várias dessas subclasses (gramáticas Várias dessas subclasses (gramáticas LLLL e e LR,LR, descritas mais adiante) conseguem descritas mais adiante) conseguem descrever a descrever a maioria das construções maioria das construções sintáticassintáticas das linguagens de programação das linguagens de programação
Analisadores Analisadores top-downtop-down::
– Caminham pela Caminham pela árvore sintáticaárvore sintática dos dos programas, programas, da raiz para as folhasda raiz para as folhas
– Trabalham com Trabalham com gramáticas LL gramáticas LL (Left-Left)(Left-Left)
– Englobam os Englobam os métodos preditoresmétodos preditores, dentre , dentre os quais, os os quais, os diagramas de transiçõesdiagramas de transições
– As As implementações manuaisimplementações manuais utilizam utilizam métodos métodos top-downtop-down
Analisadores Analisadores bottom-upbottom-up::
– Caminham pela árvore sintática dos Caminham pela árvore sintática dos programas, programas, das folhas para a raizdas folhas para a raiz
– Trabalham com Trabalham com gramáticas LRgramáticas LR (Left- (Left-Right)Right)
– Englobam importantes métodos:Englobam importantes métodos:
• Análise de Análise de precedência de precedência de operadoresoperadores
• Análise Análise LRLR
– São muito usados na São muito usados na geração automáticageração automática de analisadores sintáticosde analisadores sintáticos
5.2 – Tratamento de 5.2 – Tratamento de GramáticasGramáticas
MétodosMétodos de análise sintática se aplicam a de análise sintática se aplicam a determinadas classesdeterminadas classes de GLC’s de GLC’s
Algumas Algumas gramáticasgramáticas devem ser devem ser alteradasalteradas para que um para que um métodométodo possa ser aplicado possa ser aplicado
É a busca por uma É a busca por uma GLCGLC equivalenteequivalente à original à original
Duas GLC’s são Duas GLC’s são equivalentesequivalentes quando quando geram geram a mesma linguagema mesma linguagem
5.2.1 – Eliminação de ambiguidades5.2.1 – Eliminação de ambiguidades
Alguns métodos de análise sintática Alguns métodos de análise sintática exigemexigem que a gramática seja que a gramática seja não-ambíguanão-ambígua
Outros métodos Outros métodos mantém a ambiguidademantém a ambiguidade das das gramáticas e usam gramáticas e usam regrasregras para eliminar para eliminar árvores sintáticas indesejáveisárvores sintáticas indesejáveis
Exemplo: comando IF-ELSE da Linguagem CExemplo: comando IF-ELSE da Linguagem C
Produções típicas:Produções típicas:Cmd Cmd IF IF ExprExpr CmdCmd | IF | IF ExprExpr CmdCmd ELSE ELSE CmdCmd
| | c1 | c2c1 | c2
A sentença: A sentença: IF e1 IF e2 c1 ELSE c2IF e1 IF e2 c1 ELSE c2 tem duas árvores sintáticas: tem duas árvores sintáticas:
A A regraregra usual para resolver a ambiguidade é usual para resolver a ambiguidade é fazer o fazer o ELSEELSE corresponder ao segundo corresponder ao segundo IFIF
Esta regra pode ser Esta regra pode ser incorporadaincorporada à gramática à gramática
Gramática equivalente:Gramática equivalente:
CmdCmd CmdCasado CmdCasado || CmdNãoCasadoCmdNãoCasado
CmdCasadoCmdCasado IF IF Expr CmdCasado Expr CmdCasado ELSE ELSE CmdCasadoCmdCasado
| c1 | c2| c1 | c2
CmdNãoCasadoCmdNãoCasado IF IF Expr Cmd Expr Cmd
| IF | IF Expr CmdCasado Expr CmdCasado ELSE ELSE CmdNãoCasadoCmdNãoCasado
CmdCmd CmdCasado CmdCasado || CmdNãoCasadoCmdNãoCasado
CmdCasadoCmdCasado IF IF Expr CmdCasado Expr CmdCasado ELSE ELSE CmdCasadoCmdCasado
| c1 | c2| c1 | c2
CmdNãoCasadoCmdNãoCasado IF IF Expr Cmd Expr Cmd
| IF | IF Expr CmdCasado Expr CmdCasado ELSE ELSE CmdNãoCasadoCmdNãoCasado
CmdCasadoCmdCasado nunca produz nunca produz IF IF sem sem ELSEELSE
Esta gramática Esta gramática impedeimpede o aparecimento de o aparecimento de comandos comandos não-casadosnão-casados entre entre ExprExpr e e ELSEELSE
CmdCmd CmdCasado CmdCasado || CmdNãoCasadoCmdNãoCasado
CmdCasadoCmdCasado IF IF Expr CmdCasado Expr CmdCasado ELSE ELSE CmdCasadoCmdCasado
| c1 | c2| c1 | c2
CmdNãoCasadoCmdNãoCasado IF IF Expr Cmd Expr Cmd
| IF | IF Expr CmdCasado Expr CmdCasado ELSE ELSE CmdNãoCasadoCmdNãoCasado
Essa nova gramática Essa nova gramática dificultadificulta análise análise preditorapreditora: :
– Em Em CmdCmd, se aparecer um IF, , se aparecer um IF, qual das duasqual das duas produções tomar? produções tomar?
Cada tipoCada tipo de ambiguidade deve ser eliminada de ambiguidade deve ser eliminada mediante um mediante um tratamento particulartratamento particular
5.2.2 – Eliminação de recursividade à 5.2.2 – Eliminação de recursividade à esquerdaesquerda
Uma GLC é Uma GLC é recursiva à esquerdarecursiva à esquerda, se tiver um , se tiver um não-terminal não-terminal AA tal que haja uma derivação tal que haja uma derivação A A ++ A A, onde , onde (N (N ))**
Os métodos de análise Os métodos de análise top-downtop-down não não conseguem trabalharconseguem trabalhar com gramáticas com gramáticas recursivas à esquerdarecursivas à esquerda
Exemplo:Exemplo: sejam as produções sejam as produções
Expr Expr TermTerm ExprExpr + + TermTerm
Num método Num método top-downtop-down típico, há um típico, há um procedimento para cada um dos não-terminais procedimento para cada um dos não-terminais ExprExpr e e TermTerm::
Expr ( ) {Expr ( ) {
if ( func (átomos analisados e/ou futuros) if ( func (átomos analisados e/ou futuros) == TRUE ) {== TRUE ) {
Expr ( );Expr ( );
if (atom != ‘+’) erro (“+ esperado”)if (atom != ‘+’) erro (“+ esperado”)
else Term ( );else Term ( );
}}
else Term ( );else Term ( );
}}
Expr ( ) {Expr ( ) {if ( func (átomos analisados e/ou futuros) if ( func (átomos analisados e/ou futuros)
== TRUE ) {== TRUE ) {Expr ( );Expr ( );if (atom != ‘+’) erro (“+ esperado”)if (atom != ‘+’) erro (“+ esperado”)else Term ( );else Term ( );
}}else Term ( );else Term ( );
}}
CasoCaso func (átomos analisados e/ou futuros) func (átomos analisados e/ou futuros) seja seja TRUETRUE, na chamada interna de , na chamada interna de ExprExpr, os , os átomos serão os mesmosátomos serão os mesmos
O valor de O valor de funcfunc se repete, resultando em se repete, resultando em infinitas chamadas recursivasinfinitas chamadas recursivas
Para aplicar um Para aplicar um método top-downmétodo top-down, toda , toda recursividade à esquerda deve ser recursividade à esquerda deve ser eliminadaeliminada da gramáticada gramática
Há recursividade Há recursividade imediataimediata e e não-imediatanão-imediata à à esquerdaesquerda
Exemplos:Exemplos:
Imediata:Imediata: S S S b S S b S a aNão-imediataNão-imediata:: S S Aa Aa b b ,, A A Sc Sc d d
a) Recursividade imediata à esquerda: a) Recursividade imediata à esquerda:
É o caso de uma É o caso de uma produçãoprodução ser recursiva à ser recursiva à esquerdaesquerda
Um caso bem simples é o das seguintes Um caso bem simples é o das seguintes produções:produções:
A A A A ((, , (N (N )* )* e não iniciam com e não iniciam com AA))
Estas produções podem ser Estas produções podem ser substituídassubstituídas pelas pelas seguintes:seguintes:
A A R R R R R R εε
que geram as que geram as mesmas formasmesmas formas sentenciais que sentenciais que as originais, conforme o próximo slideas originais, conforme o próximo slide
{A {A A A } {A } {A R R R R R R εε}}
Resolve muitos casos, mas não é geralResolve muitos casos, mas não é geral
Exemplo:Exemplo: seja a seguinte gramática, com duas seja a seguinte gramática, com duas produções contendo recursividade imediata à produções contendo recursividade imediata à esquerda:esquerda:
Expr Expr Expr Expr + + Termo Termo TermoTermoTermo Termo Termo Termo * * Fator Fator FatorFator
Fator Fator ( ( Expr Expr ) ) ID ID
Transformação da gramática:Transformação da gramática:
Expr Expr Termo EauxTermo EauxEaux Eaux + + Termo Eaux Termo Eaux εεTermo Termo Fator TauxFator TauxTaux Taux * * Fator Taux Fator Taux εε
Fator Fator ( ( Expr Expr ) | ID ) | ID
{A {A A A } }
{A {A R R R R R R εε}}
Nas produções de Expr, substituindo:
A por Expr por + Termo por TermoR por Eaux
De modo análogo, na produção de Termo
Generalização:Generalização: várias produções do mesmo várias produções do mesmo não-terminal, com recursividade a esquerdanão-terminal, com recursividade a esquerda
Algoritmo 5.1: Algoritmo 5.1: As seguintes produções:As seguintes produções:
A A A A 11 A A 22 - - - - - - A A mm 11 22 - - - - - - nn
Podem ser substituídas por:Podem ser substituídas por:
A A 11 A' A' 22 A' A' - - - - - - nn A' A'
A' A' 11 A' A' 22 A' A' - - - - - - mm A' A' εε
Nenhum Nenhum ii pode ser pode ser εε
b) Recursividade não-imediata à esquerda: b) Recursividade não-imediata à esquerda:
O O algoritmoalgoritmo a seguir elimina a seguir elimina todatoda recursividade à esquerda de uma gramáticarecursividade à esquerda de uma gramática
CondiçõesCondições da gramática: não deve ter da gramática: não deve ter ciclosciclos nem produções nem produções vaziasvazias
Gramática sem ciclos:Gramática sem ciclos: sem derivações da sem derivações da forma forma
A A ++ A A
Gramática sem produções vazias:Gramática sem produções vazias: a única a única produção vazia permitida é produção vazia permitida é S S ( (S:S: símbolo símbolo inicial) e inicial) e SS não aparece do não aparece do lado direitolado direito de de qualquer produçãoqualquer produção
Existem algoritmos para Existem algoritmos para eliminar ciclos e eliminar ciclos e produções vaziasproduções vazias de GLC’s de GLC’s
Algoritmo 5.2: Algoritmo 5.2: eliminação de recursividade à eliminação de recursividade à esquerdaesquerda
Arranjar os não-terminais numa ordem Arranjar os não-terminais numa ordem AA11, A, A22, ... , A, ... , Ann
Para (i = 1; i <= n; i++) {Para (i = 1; i <= n; i++) {
Para (j = 1; j <= i-1; j++) {Para (j = 1; j <= i-1; j++) {
Sendo Sendo AAjj 11 22 - - - - - - mm
as produções de as produções de AAjj, no momento,, no momento,
Substituir cada produção da forma Substituir cada produção da forma AAii A Ajj pelas pelas
produções produções
AAii 11 22 - - - - - - mm
}}
Eliminar as recursividades imediatas a esquerda entre Eliminar as recursividades imediatas a esquerda entre
as produções de as produções de AAii;;
}}
Exemplo:Exemplo: Eliminar as recursividades à esquerda Eliminar as recursividades à esquerda da gramática:da gramática:
S S S a S a T b T b c c
T T S d S d U e U e f fU U S g S g U h U h i i
Renomeando os não-terminais:Renomeando os não-terminais:
S = AS = A11, T = A, T = A22, U = A, U = A33
A gramática torna-se em:A gramática torna-se em:
AA11 A A11 a a A A22 b b c c
AA22 A A11 d d A A33 e e f f
AA33 A A11 g g A A33 h h i i
Para i = 1:Para i = 1:
EliminaçãoEliminação das recursividades imediatas à das recursividades imediatas à esquerda de esquerda de AA11: :
AA11 A A22 b X b X c X c X
X X a X a X εε
A A A A11 11 22
A A 11 A' A' 22 A' A'A' A' 11 A' A' εε
Algoritmo 5.1
A1 A2 b X c X
X a X εA2 A1 d A3 e fA3 A1 g A3 h i
Novo estado das produções
Para i = 2, j = 1:Para i = 2, j = 1:
Produções de Produções de AA22::
AA22 A A11 d d A A33 e e f f
Produções de Produções de AA11 no momento: no momento: AA11 A A22 b X b X c c XX
Substitui-se Substitui-se AA11 d d por por AA22 b X d b X d c X d c X d ::
Produção da forma A2 A1
Para i = 2:Para i = 2:
EliminaçãoEliminação das recursividades imediatas à das recursividades imediatas à esquerda de esquerda de AA22::
A A A A11 11 2 2 33
A A 11 A' A' 22 A' A' 33 A'A'
A' A' 11 A' A' εε
Algoritmo 5.1
A2 c X d Y A3 e Y f YY b X d Y ε
Novo estado das produções
A1 A2 b X c XX a X εA2 c X d Y A3 e Y f Y
Y b X d Y ε
A3 A1 g A3 h i
Para i = 3, j = 1:Para i = 3, j = 1:
Produções de Produções de AA33::
AA33 A A11 g g A A33 h h i i
Produções de Produções de AA11 no momento: no momento: AA11 A A22 b X b X c c XX
Substitui-se Substitui-se AA11 g g por por AA22 b X g b X g c X g c X g : :
AA33 A A22 b X g b X g c X g c X g A A33 h h i i
Produção da forma A3 A1
Para i = 3, j = 2:Para i = 3, j = 2:
Produções de Produções de AA33::
AA33 A A22 b X g b X g c X g c X g A A33 h h i i
Produções de Produções de AA22 no momento: no momento: AA22 c X d Y c X d Y AA33 e Y e Y f f YY
Substitui-se Substitui-se AA22 b X g b X g por por
c X d Y b X g c X d Y b X g A3 e Y b X g A3 e Y b X g f Y b X g f Y b X g : :
Produção da forma A3 A2
Para i = 3:Para i = 3:
EliminaçãoEliminação das recursividades imediatas à das recursividades imediatas à esquerda de esquerda de AA33::
AA33 c X d Y b X g Z c X d Y b X g Z f Y b X g Z f Y b X g Z c X g Z c X g Z i Z i Z
Z Z e Y b X g Z e Y b X g Z h Z h Z εε
A A A A11 A A22 11 2 2 3 3 44
A A 11 A' A' 22 A' A' 33 A' A' 44 A' A'
A' A' 11 A' A' 22 A' A' εε
Algoritmo 5.1
Novo estado das produções:Novo estado das produções:
AA11 A A22 b X b X c X c XX X a X a X εεAA22 c X d Y c X d Y A A33 e Y e Y f f YY
Y Y b X d Y b X d Y εε A3 A3 c X d Y b X g Z c X d Y b X g Z f Y b X g Z f Y b X g Z c X g Z c X g Z
i Zi Z
Z Z e Y b X g Z e Y b X g Z h Z h Z εε
AA11 A A22 b X b X c X c X
AA22 c X d Y c X d Y A A33 e Y e Y f f YYA3 A3 c X d Y b X g Z c X d Y b X g Z f Y b X g Z f Y b X g Z c X g Z c X g Z i Z i ZX X a X a X εεY Y b X d Y b X d Y εε
Z Z e Y b X g Z e Y b X g Z h Z h Z εε
Restaurando os nomes originais dos não-Restaurando os nomes originais dos não-terminais:terminais:
S S T b X T b X c X c XT T c X d Y c X d Y U e Y U e Y f f YYU U c X d Y b X g Z c X d Y b X g Z f Y b X g Z f Y b X g Z c X g Z c X g Z i Z i ZX X a X a X εεY Y b X d Y b X d Y εε Z Z e Y b X g Z e Y b X g Z h Z h Z εε
Não há mais recursividade a esquerda
S = A1, T = A2, U S = A1, T = A2, U = A3 = A3
5.2.3 – Fatoração à esquerda5.2.3 – Fatoração à esquerda
Sejam as seguintes produções do não-terminal Sejam as seguintes produções do não-terminal AA::
A A
onde onde , , , , (N (N )* )* e o primeiro símbolo e o primeiro símbolo de de é diferente do primeiro símbolo de é diferente do primeiro símbolo de
Para um método preditor, Para um método preditor, não é claronão é claro qual qual produção usar para expandir produção usar para expandir AA
Pode-se Pode-se atrasaratrasar a decisão, aplicando nesta a decisão, aplicando nesta gramática a seguinte transformação:gramática a seguinte transformação:
A A A’ A’ , , A’ A’
A A A A A’ A’ , , A’ A’
Isso ainda Isso ainda não garantenão garante a possibilidade de a possibilidade de aplicação de um método aplicação de um método preditorpreditor
- O primeiro símbolo de O primeiro símbolo de e e pode ser um pode ser um não-terminalnão-terminal, permanecendo a , permanecendo a indecisãoindecisão
■ Fatoração é apenas um passoFatoração é apenas um passo para adequar para adequar gramáticas a um método gramáticas a um método preditorpreditor
5.3 – Escolha de uma 5.3 – Escolha de uma DerivaçãoDerivação
Mesmo numa GLC não-ambígua, a sequência de Mesmo numa GLC não-ambígua, a sequência de derivações diretasderivações diretas para produzir uma sentença para produzir uma sentença pode pode variarvariar
Exemplo: Exemplo: seja a gramática seja a gramática S S εε | S ( S ) | S ( S )
A sentença A sentença ( )( ) pode ser gerada pelas seguintes pode ser gerada pelas seguintes derivações:derivações:
S S S(S) S(S) (S) (S) () ()S S S(S) S(S) S() S() () ()
Essas derivações diferem no trecho marcadoEssas derivações diferem no trecho marcado
S S S(S) S(S) (S) (S) () ()S S S(S) S(S) S() S() () ()
Na Na primeiraprimeira, escolheu-se o não-terminal , escolheu-se o não-terminal SS mais à esquerdamais à esquerda para ser expandido para ser expandido
Na Na segundasegunda, foi escolhido o não-terminal , foi escolhido o não-terminal SS mais à direitamais à direita
SimbolicamenteSimbolicamente
S(S) S(S) meme (S) (S) ee S(S) S(S) mdmd S() S()
Ou seja,Ou seja,
S(S) S(S) deriva diretamente mais à esquerda deriva diretamente mais à esquerda (S) (S) S(S) S(S) deriva diretamente mais à direitaderiva diretamente mais à direita S() S()
Derivação mais à esquerda Derivação mais à esquerda ouou mais à mais à direita: direita: quando todas as derivações diretas quando todas as derivações diretas forem forem meme ou ou mdmd
Simbolicamente: Simbolicamente: **meme ou ou **
mdmd
No exemplo anteriorNo exemplo anterior
{ S { S **me me ( ) } = { S ( ) } = { S S(S) S(S) (S) (S) ( ) } ( ) }
{ S { S **md md ( ) } = { S ( ) } = { S S(S) S(S) S( ) S( )
( ) }( ) }
Qualquer árvore sintática tem uma Qualquer árvore sintática tem uma únicaúnica derivação mais à derivação mais à esquerdaesquerda e uma e uma únicaúnica derivação mais à derivação mais à direitadireita
Gramática ambígua – outra definiçãoGramática ambígua – outra definição: : produz mais de uma derivação mais à esquerda produz mais de uma derivação mais à esquerda ou mais à direita para pelo menos uma de suas ou mais à direita para pelo menos uma de suas sentençassentenças
Os analisadores sintáticos Os analisadores sintáticos mais conhecidosmais conhecidos analisam derivações analisam derivações mais à esquerdamais à esquerda ou ou mais à direitamais à direita dos programas dos programas
Exemplo: Exemplo: Produção de derivações mais a Produção de derivações mais a esquerdaesquerda da gramática: da gramática:
E E T | T opad E T | T opad E
T T F | F opmult T F | F opmult T
F F id | cte | ( E ) id | cte | ( E )
Derivação mais à esquerda para a expressão:Derivação mais à esquerda para a expressão:
( x + y ) * 10 / ( n – 2 )( x + y ) * 10 / ( n – 2 )
EE TT FF opmult T opmult T ( ( EE ) opmult T ) opmult T ( ( TT opad E ) opmult T opad E ) opmult T ( ( FF opad E ) opmult T opad E ) opmult T ( id opad ( id opad EE ) opmult T ) opmult T ( id opad ( id opad TT ) opmult T ) opmult T ( id opad ( id opad FF ) opmult T ) opmult T ( id opad id ) opmult ( id opad id ) opmult TT ( id opad id ) opmult ( id opad id ) opmult FF opmult T opmult T ( id opad id ) opmult cte opmult ( id opad id ) opmult cte opmult TT ( id opad id ) opmult cte opmult ( id opad id ) opmult cte opmult FF ( id opad id ) opmult cte opmult ( ( id opad id ) opmult cte opmult ( EE ) ) ( id opad id ) opmult cte opmult ( ( id opad id ) opmult cte opmult ( TT opad E ) opad E ) ( id opad id ) opmult cte opmult ( ( id opad id ) opmult cte opmult ( FF opad E ) opad E ) ( id opad id ) opmult cte opmult ( id opad ( id opad id ) opmult cte opmult ( id opad EE ) ) ( id opad id ) opmult cte opmult ( id opad ( id opad id ) opmult cte opmult ( id opad TT ) ) ( id opad id ) opmult cte opmult ( id opad ( id opad id ) opmult cte opmult ( id opad FF ) ) ( id opad id ) opmult cte opmult ( id opad cte )( id opad id ) opmult cte opmult ( id opad cte )
( x + y ) * 10 / ( n – 2 )( x + y ) * 10 / ( n – 2 )
Analisadores preditores examinam derivações mais a esquerda
Exemplo: Exemplo: Produção de derivações mais a Produção de derivações mais a direitadireita da gramática: da gramática:
E E T | E T | E opadopad T T
T T F | T F | T opmult opmult FF
F F id id | | ctecte | | ( ( EE ) )
Derivação mais à direita para a expressão:Derivação mais à direita para a expressão:
( x + y ) * 10 / ( n – 2 )( x + y ) * 10 / ( n – 2 )
EE TT T opmult T opmult FF T opmult ( T opmult ( EE ) ) T opmult ( E opad T opmult ( E opad TT ) ) T opmult ( E opad T opmult ( E opad FF ) ) T opmult ( T opmult ( EE opad cte ) opad cte ) T opmult ( T opmult ( TT opad cte ) opad cte )
T opmult ( T opmult ( FF opad cte ) opad cte ) TT opmult ( id opad cte ) opmult ( id opad cte )
T opmult T opmult FF opmult ( id opad cte ) opmult ( id opad cte ) TT opmult cte opmult ( id opad cte ) opmult cte opmult ( id opad cte ) FF opmult cte opmult ( id opad cte ) opmult cte opmult ( id opad cte ) ( ( EE ) opmult cte opmult ( id opad cte ) ) opmult cte opmult ( id opad cte ) ( E opad ( E opad TT ) opmult cte opmult ( id opad cte ) ) opmult cte opmult ( id opad cte ) ( E opad ( E opad FF ) opmult cte opmult ( id opad cte ) ) opmult cte opmult ( id opad cte ) ( ( EE opad id ) opmult cte opmult ( id opad cte ) opad id ) opmult cte opmult ( id opad cte ) ( ( TT opad id ) opmult cte opmult ( id opad cte ) opad id ) opmult cte opmult ( id opad cte ) ( ( FF opad id ) opmult cte opmult ( id opad cte ) opad id ) opmult cte opmult ( id opad cte )
( id opad id ) opmult cte opmult ( id opad cte )( id opad id ) opmult cte opmult ( id opad cte )
( x + y ) * 10 / ( n – 2 )( x + y ) * 10 / ( n – 2 )
Analisadores bottom-up examinam derivações mais a direita reversas
( x + y ) * 10 / ( n – 2 )( x + y ) * 10 / ( n – 2 )
( ( idid opad id ) opmult cte opmult ( id opad cte ) opad id ) opmult cte opmult ( id opad cte ) ( ( FF opad id ) opmult cte opmult ( id opad cte ) opad id ) opmult cte opmult ( id opad cte ) ( ( TT opad id ) opmult cte opmult ( id opad cte ) opad id ) opmult cte opmult ( id opad cte ) ( E( E opad opad idid ) opmult cte opmult ( id opad cte ) ) opmult cte opmult ( id opad cte ) ( E opad ( E opad FF ) opmult cte opmult ( id opad cte ) ) opmult cte opmult ( id opad cte ) ( ( E opad TE opad T ) opmult cte opmult ( id opad cte ) ) opmult cte opmult ( id opad cte )
( E )( E ) opmult cte opmult ( id opad cte ) opmult cte opmult ( id opad cte ) FF opmult cte opmult ( id opad cte ) opmult cte opmult ( id opad cte ) T opmult T opmult ctecte opmult ( id opad cte ) opmult ( id opad cte ) T opmult FT opmult F opmult ( id opad cte ) opmult ( id opad cte ) T opmult ( T opmult ( idid opad cte ) opad cte ) T opmult ( T opmult ( FF opad cte ) opad cte )
T opmult ( T opmult ( TT opad cte ) opad cte ) T opmult ( E opad T opmult ( E opad ctecte ) ) T opmult ( E opad T opmult ( E opad FF ) ) T opmult ( T opmult ( E opad TE opad T ) )
T opmult T opmult ( E )( E ) T opmult FT opmult F TT EE
Em negrito, lados direitos a serem reduzidos
5.4 – Análise Top-Down5.4 – Análise Top-Down Tentativa de construir uma árvore sintática Tentativa de construir uma árvore sintática
para a sentença analisada, para a sentença analisada, começando da começando da raizraiz, indo em direção às , indo em direção às folhasfolhas e criando os e criando os nós em nós em pré-ordempré-ordemExemplo:
5.4 – Análise Top-Down5.4 – Análise Top-Down Tentativa de construir uma árvore sintática para Tentativa de construir uma árvore sintática para
a sentença analisada, a sentença analisada, começando da raizcomeçando da raiz, indo , indo em direção às em direção às folhasfolhas e criando os nós em e criando os nós em pré-pré-ordemordem
Também:Também: tentativa de achar uma tentativa de achar uma derivação derivação mais à esquerdamais à esquerda para a sentença ou programa para a sentença ou programa analisadoanalisado
Análise preditora: Análise preditora: os átomos são analisados os átomos são analisados linearmente linearmente da esquerda para a direitada esquerda para a direita, sem a , sem a necessidade de observar necessidade de observar átomos futurosátomos futuros e de e de caminhar de volta, caminhar de volta, da direita para a esquerdada direita para a esquerda, , sobre a sequência de átomossobre a sequência de átomos
5.4.1 – Análise backtracking5.4.1 – Análise backtracking
Por vezes, a Por vezes, a produção escolhidaprodução escolhida para produzir para produzir uma derivação direta mais à esquerda uma derivação direta mais à esquerda não leva não leva à árvore sintáticaà árvore sintática da sentença analisada da sentença analisada
Então, o analisador é obrigado a Então, o analisador é obrigado a voltar para a voltar para a esquerdaesquerda na sequência de átomos e a na sequência de átomos e a eliminar eliminar uma subárvoreuma subárvore da árvore em construção, da árvore em construção, substituindo-a por outrasubstituindo-a por outra
Exemplo:Exemplo: seja a gramática seja a gramática
S S a A d a A d a B a B
A A b b c c
B B ccd ccd ddc ddc
A seguir, análise da sentença:
w = a c c d
S S a A d a A d a B A a B A b b c B c B ccd ccd ddc ddc
w = a c c w = a c c dd
S1) Início:
Árvore contendo somente o símbolo inicial
Cursor na raiz da árvore
Cursor no primeiro átomo da sentença
S S a A d a A d a B A a B A b b c B c B ccd ccd ddc ddc
w = a c c w = a c c dd
S
a A d
2) 1a produção para expandir S
Liga-se S ao átomo da sentença apontado pelo cursor, pois é diante dele que ocorreu a expansão
Cursor da árvore avança em pré-ordem
Os cursores se casam: a = a
S S a A d a A d a B A a B A b b c B c B ccd ccd ddc ddc
w = a c c w = a c c dd
S
a A d
3) Os dois cursores avançam
S S a A d a A d a B A a B A b b c B c B ccd ccd ddc ddc
S
a A d
b
w = a c c w = a c c dd
4) 1a produção para expandir A
Liga-se A ao átomo da sentença apontado pelo cursor, pois é diante dele que ocorreu a expansão
Cursor da árvore avança em pré-ordem
Os cursores não se casam: b ≠ c
S S a A d a A d a B A a B A b b c B c B ccd ccd ddc ddc
S
a A d
b
w = a c c w = a c c dd
5) Elimina-se a subárvore da expansão anterior
2a produção para expandir A
Cursor da sentença retrocede para onde A foi expandido, ou seja, permanece onde está:
Cursor da árvore avança em pré-ordemOs cursores se
casam: c = c
c
S S a A d a A d a B A a B A b b c B c B ccd ccd ddc ddc
S
a A d
c
w = a c c w = a c c dd
Os cursores não se casam: d ≠ c
6) Os dois cursores avançam
S S a A d a A d a B A a B A b b c B c B ccd ccd ddc ddc
S
a A d
c
w = a c c w = a c c dd Os cursores se
casam: a = a
7) Elimina-se a subárvore da expansão anterior
Não existe outra produção para expandir A
Elimina-se também a subárvore da expansão imediatamente anterior, ou seja, a de S
Cursor da sentença retrocede até o ponto em que S foi expandido
2a produção para expandir S
O cursor da árvore avança
a B
S S a A d a A d a B A a B A b b c B c B ccd ccd ddc ddc
S
a B
c c d
w = a c c w = a c c dd
8) Os cursores avançam
1a produção para expandir B
Cursor da árvore avança
Casamento nos três últimos movimentos dos cursores:
c c d = c c d
A sentença é reconhecida
Só se chega à Só se chega à conclusãoconclusão de que há de que há erro na erro na sentençasentença, quando , quando não houver mais opçõesnão houver mais opções para para expandir o não-terminal da expandir o não-terminal da raizraiz
Como detectar e tratar Como detectar e tratar erroserros??
No No pior casopior caso (erro na sentença), o (erro na sentença), o tempotempo gasto gasto na análise cresce na análise cresce exponencialmenteexponencialmente com com tamanho da sentençatamanho da sentença
E se a gramática tivesse E se a gramática tivesse recursividade à recursividade à esquerdaesquerda??
Exemplo: S Exemplo: S b b S b S b
O uso de O uso de backtrackingbacktracking é é raramente necessárioraramente necessário para analisar construções de linguagens de para analisar construções de linguagens de programaçãoprogramação
Análise sem backtracking:Análise sem backtracking: no momento de no momento de expansão escolhe a expansão escolhe a produção corretaprodução correta, , dispensando tentativas desnecessáriasdispensando tentativas desnecessárias
Nem todas as GLC’s podem ser analisadas Nem todas as GLC’s podem ser analisadas semsem backtrackingbacktracking, mas, na prática, , mas, na prática, só ela é só ela é usadausada
Existe análise Existe análise sem backtrackingsem backtracking em que o em que o número de átomosnúmero de átomos necessários para a necessários para a tomada de decisão é tomada de decisão é maior que 1maior que 1
Ou seja, existem métodos Ou seja, existem métodos sem backtrackingsem backtracking também também não preditoresnão preditores
5.4.2 – Gramáticas LL(k) e LL(1)5.4.2 – Gramáticas LL(k) e LL(1)
Gramáticas LL(k):Gramáticas LL(k): admitem analisadores admitem analisadores semsem back-trackingback-tracking que: que:
Analisam as sentenças da Analisam as sentenças da esquerdaesquerda para a para a direita (direita (o primeiro L - lefto primeiro L - left))
Produzem derivações Produzem derivações mais à esquerdamais à esquerda ( (o o segundo Lsegundo L))
Precisam Precisam analisaranalisar no máximo, os próximos no máximo, os próximos k k símbolossímbolos, para , para decidirdecidir que produção usar que produção usar
Gramáticas LL(1): Gramáticas LL(1): gramáticas gramáticas LL(k)LL(k) em que em que k = 1k = 1
Métodos preditoresMétodos preditores só analisam gramáticas só analisam gramáticas LL(1)LL(1)
Nesta disciplinaNesta disciplina serão abordados somente serão abordados somente métodos métodos preditorespreditores
LivroLivro que aborda com detalhes muitos que aborda com detalhes muitos outros outros métodosmétodos::
Aho, A.V., Ullman, J.D. – Aho, A.V., Ullman, J.D. – The Theory of The Theory of Parsing, Translation and CompilingParsing, Translation and Compiling – – Prentice-Hall – 1972 Prentice-Hall – 1972
É o primeiro É o primeiro Livro do DragãoLivro do Dragão – hoje são – hoje são trêstrês
Espectro dos métodos top-down:Espectro dos métodos top-down:
Top-down
Backtracking
Sem Backtracking
Não Preditores
Preditores
5.4.3 – Análise preditora recursiva5.4.3 – Análise preditora recursiva
É uma análise É uma análise preditorapreditora estruturada num estruturada num conjunto de conjunto de subprogramas recursivossubprogramas recursivos
O método dos O método dos diagramas de transiçõesdiagramas de transições é é preditor recursivo preditor recursivo
Outro método:Outro método: também orienta-se por uma também orienta-se por uma gramática fatorada à esquerdagramática fatorada à esquerda, mas , mas dispensa os diagramas de transiçõesdispensa os diagramas de transições
Exemplo: Exemplo: seja a gramáticaseja a gramática
ExpressãoExpressão TermoTermo | | TermoTermo OPAD OPAD ExpressãoExpressão
TermoTermo FatorFator | | FatorFator OPMULT OPMULT TermoTermo
FatorFator ID | CTE | ( ID | CTE | ( ExpressãoExpressão ) | OPNEG ) | OPNEG FatorFator
Fatorando:Fatorando:
ExpressãoExpressão TermoTermo EauxEaux
EauxEaux OPAD OPAD ExpressãoExpressão | | εε
TermoTermo FatorFator TauxTaux
TauxTaux OPMULT OPMULT TermoTermo | | εε
FatorFator ID | CTE | ( ID | CTE | ( ExpressãoExpressão ) | OPNEG ) | OPNEG FatorFator
A seguir:
Esquema de programa analisador sintático em C
Programa principal:Programa principal:
void main () {void main () {
printf ("Digite a expressao:\n\n");printf ("Digite a expressao:\n\n");
gets (expressao);gets (expressao);
printf ("\n"); printf ("\n");
ptexpr = 0;ptexpr = 0;
carac = NovoCarac (); NovoAtomo ();carac = NovoCarac (); NovoAtomo ();
Expressao ();Expressao ();
if (atom.tipo != ENDOFFILE)if (atom.tipo != ENDOFFILE)
Esperado (ENDOFFILE);Esperado (ENDOFFILE);
}}
ExpressãoExpressão TermoTermo EauxEaux
EauxEaux OPAD OPAD ExpressãoExpressão | | εε
void Expressao () {void Expressao () {
Termo (); Termo ();
Eaux ();Eaux ();
}}
void Eaux () {void Eaux () {
if (atom.tipo == OPAD) {if (atom.tipo == OPAD) {
NovoAtomo (); NovoAtomo ();
Expressao ();Expressao ();
}}
}}
TermoTermo FatorFator TauxTaux
TauxTaux OPMULT OPMULT TermoTermo | | εε
void Termo () {void Termo () {
Fator (); Fator ();
Taux ();Taux ();
}}
void Taux () {void Taux () {
if (atom.tipo == OPMULT) {if (atom.tipo == OPMULT) {
NovoAtomo (); Termo ();NovoAtomo (); Termo ();
}}
}}
FatorFator ID | CTE | ( ID | CTE | ( ExpressãoExpressão ) | OPNEG ) | OPNEG FatorFator
void Fator () {void Fator () {
switch (atom.tipo) {switch (atom.tipo) {
case CTE: NovoAtomo (); break;case CTE: NovoAtomo (); break;
case ID: NovoAtomo (); break;case ID: NovoAtomo (); break;
case ABPAR: NovoAtomo (); Expressao ();case ABPAR: NovoAtomo (); Expressao ();
if (atom.tipo != if (atom.tipo != FPAR) FPAR)
Esperado (FPAR);Esperado (FPAR);
NovoAtomo (); break;NovoAtomo (); break;
case OPNEG: NovoAtomo (); Fator (); break;case OPNEG: NovoAtomo (); Fator (); break;
default: NaoEsperado (atom.tipo); default: NaoEsperado (atom.tipo);
NovoAtomo (); break; NovoAtomo (); break;
}}
}}
5.4.4 – Análise preditora não-recursiva5.4.4 – Análise preditora não-recursiva
Para melhor desempenho, é conveniente Para melhor desempenho, é conveniente trocartrocar uma solução uma solução recursivarecursiva por outra por outra não-não-recursivarecursiva, usando pilha, usando pilha
ChamadasChamadas de subprogramas são de subprogramas são consumidoras de consumidoras de tempotempo
Chamadas recursivasChamadas recursivas numa análise preditora numa análise preditora podem ser substituídas por podem ser substituídas por empilhamentosempilhamentos e e por consultas a uma por consultas a uma tabela de produçõestabela de produções
Um analisador Um analisador não-recursivonão-recursivo, diante de um , diante de um átomoátomo da sentença e de um da sentença e de um não-terminalnão-terminal a a ser expandido, no topo da pilha, ser expandido, no topo da pilha, consultaconsulta uma uma tabela de produções para saber tabela de produções para saber como como expandi-loexpandi-lo
Os símbolos do Os símbolos do lado direitolado direito da produção da produção escolhida são então escolhida são então empilhadosempilhados no lugar no lugar desse não-terminaldesse não-terminal
A próxima figura ilustra o A próxima figura ilustra o esquema esquema de um de um analisador sintático preditor não-recursivoanalisador sintático preditor não-recursivo
Pilha: Pilha: local para fazer expansões de não-local para fazer expansões de não-terminaisterminais
Tabela de produções:Tabela de produções: matriz bidimensional matriz bidimensional M M para indicar a produção a ser usada para para indicar a produção a ser usada para expandir um não-terminal, diante de um átomo expandir um não-terminal, diante de um átomo na entradana entrada
Funcionamento:Funcionamento: seja seja XX o elemento do topo da o elemento do topo da pilha e pilha e aa o átomo em análise o átomo em análise
Se Se X = a = $X = a = $: encerra com : encerra com sucessosucesso
Se Se X = a X = a $ $: desempilha : desempilha XX e avança na e avança na entradaentrada
Se Se X X a a e ambos são terminais: e ambos são terminais: erroerro
Se Se XX é um não terminal: é um não terminal: consultaconsulta a a entrada entrada M[X, a]M[X, a] da da tabela tabela MM M[X, a] pode
ser uma produção de X ou um erro
Se, por exemplo, M[X,a] for a produção XYZW:
Desempilhar X
Empilhar W, Z, Y, com Y no topo
Se M[X,a] for um erro:
Acionar tratamento de erro
M[X, a]
X
a
Algoritmo 5.3: Análise preditora não recursivaAlgoritmo 5.3: Análise preditora não recursiva
Empilhar ($); Empilhar (S) /* Empilhar ($); Empilhar (S) /* SS é o símbolo inicial */ ; é o símbolo inicial */ ; w w sentença || $; p sentença || $; p &(w[0]); &(w[0]);Repetir {Repetir {
X X topo da pilha; a topo da pilha; a *p; *p;Se (X = terminal ou X = $) {Se (X = terminal ou X = $) {
Se (X = a) {Desempilhar (X); Avançar (p);}Se (X = a) {Desempilhar (X); Avançar (p);}Senão Erro ( Senão Erro ( XX era esperado ); } era esperado ); }
Senão Senão { /* { /* XX é não-terminal */ é não-terminal */Se M[X, a] = {XSe M[X, a] = {XYY11YY22YY33 ... Y ... Ykk} {} {
Desempilhar (X);Desempilhar (X);Empilhar (YEmpilhar (Ykk ... ... YY33YY33YY11) /* ) /* YY11 no topo */ ; no topo */ ;Imprimir a produção {XImprimir a produção {XYY11YY22YY33 ... Y ... Ykk};}};}
Senão Erro ( Senão Erro ( aa não era esperado ); } não era esperado ); }} enquanto (X } enquanto (X $) $) /* enquanto pilha ainda não /* enquanto pilha ainda não
vazia */vazia */
A saída pode ser a
produção usada
Exemplo: Exemplo: seja a seguinte gramática de seja a seguinte gramática de expressões:expressões:
E E T E’ T E’ E’ E’ + T E’ | + T E’ | εε
T T F T’ F T’ T’ T’ * F T’ | * F T’ | ε ε F F (( E E )) | | idid
Seja a seguinte Seja a seguinte sentençasentença em análise: em análise: id + id id + id * id* id
Supor a seguinte Supor a seguinte tabela de produçõestabela de produções (sua (sua construção é apresentada após o exemplo – as construção é apresentada após o exemplo – as posições vazias são erros):posições vazias são erros):
Estado inicial:Estado inicial:
Programa
analisador preditor
id + id * id $
Sentença de entrada
$E
Pilha
Ação:Expandir
SaídaE’ E TE’
T
Programa
analisador preditor
id + id * id $
Sentença de entrada
$
Pilha
Ação:Expandir
SaídaE’ E TE’
TT’
F
E TE’T FT’
Programa
analisador preditor
id + id * id $
Sentença de entrada
$E’
Pilha
Ação:Expandir
Saída
E TE’T FT’
T’
Fid
E TE’T FT’F id
Programa
analisador preditor
id + id * id $
Sentença de entrada
$E’
Pilha
Ação:Desempilhar
Avançar
Saída
E TE’T FT’F id
T’
id
Programa
analisador preditor
id + id * id $
Sentença de entrada
$E’
Pilha
Ação:Expandir
Saída
E TE’T FT’F id
T’E TE’T FT’F idT’ ε
Programa
analisador preditor
id + id * id $
Sentença de entrada
$E’
Pilha
Ação:Expandir
Saída
E TE’T FT’F idT’ εE’
T+ E TE’
T FT’F idT’ εE’ +T’E’
Programa
analisador preditor
id + id * id $
Sentença de entrada
$E’
Pilha
Ação:Desempilhar
Avançar
Saída
E TE’T FT’F idT’ εE’ +T’E’
T+
Programa
analisador preditor
id + id * id $
Sentença de entrada
$E’
Pilha
Ação:Expandir
Saída
E TE’T FT’F idT’ εE’ +T’E’
TT’
FE TE’T FT’F idT’ εE’ +T’E’T FT’
Programa
analisador preditor
id + id * id $
Sentença de entrada
$E’
Pilha
Ação:Expandir
Saída
E TE’T FT’F idT’ εE’ +T’E’T FT’
T’Fid
E TE’T FT’F idT’ εE’ +T’E’T FT’F id
Programa
analisador preditor
id + id * id $
Sentença de entrada
$E’
Pilha
Ação:Desempilhar
Avançar
Saída
E TE’T FT’F idT’ εE’ +T’E’T FT’F id
T’id
Programa
analisador preditor
id + id * id $
Sentença de entrada
$E’
Pilha
Ação:Expandir
Saída
E TE’T FT’F idT’ εE’ +T’E’T FT’F id
T’F
*E TE’T FT’F idT’ εE’ +T’E’T FT’F idT’ *FT’
Programa
analisador preditor
id + id * id $
Sentença de entrada
$E’
Pilha
Ação:Desempilhar
Avançar
Saída
E TE’T FT’F idT’ εE’ +T’E’T FT’F idT’ *FT’
T’F
*
Programa
analisador preditor
id + id * id $
Sentença de entrada
$E’
Pilha
Ação:Expandir
Saída
E TE’T FT’F idT’ εE’ +T’E’T FT’F idT’ *FT’
T’Fid
E TE’T FT’F idT’ εE’ +T’E’T FT’F idT’ *FT’F id
Programa
analisador preditor
id + id * id $
Sentença de entrada
$E’
Pilha
Ação:Desempilhar
Avançar
Saída
E TE’T FT’F idT’ εE’ +T’E’T FT’F idT’ *FT’F id
T’id
Programa
analisador preditor
id + id * id $
Sentença de entrada
$E’
Pilha
Ação:Expandir
Saída
E TE’T FT’F idT’ εE’ +T’E’T FT’F idT’ *FT’F id
T’
E TE’T FT’F idT’ εE’ +T’E’T FT’F idT’ *FT’F idT’ ε
Programa
analisador preditor
id + id * id $
Sentença de entrada
$E’
Pilha
Ação:Expandir
Saída
E TE’T FT’F idT’ εE’ +T’E’T FT’F idT’ *FT’F idT’ ε
E TE’T FT’F idT’ εE’ +T’E’T FT’F idT’ *FT’F idT’ εE’ ε
Programa
analisador preditor
id + id * id $
Sentença de entrada
$
Pilha
Ação:Desempilhar
Avançar
Saída
E TE’T FT’F idT’ εE’ +T’E’T FT’F idT’ *FT’F idT’ εE’ ε
Ação:Encerrar
com sucesso
Derivação
Resta saber como construir a tabela de produções !!!
E E T E’ E’ T E’ E’ + T E’ | + T E’ | εε T T F T’ T’ F T’ T’ * F T’ | * F T’ | ε ε F F (( E E )) | | idid
Há gramáticas cujas tabelas apresentam Há gramáticas cujas tabelas apresentam duas duas ou maisou mais produções para a mesma entrada produções para a mesma entrada
Então Então nãonão se pode aplicar um método se pode aplicar um método preditorpreditor
E E T E’ E’ T E’ E’ + T E’ | + T E’ | εε T T F T’ T’ F T’ T’ * F T’ | * F T’ | ε ε F F (( E E )) | | idid
Produção de Produção de XX em que o em que o primeiro símboloprimeiro símbolo do do lado direito é um lado direito é um terminal aterminal a: pode ser : pode ser colocada na entrada colocada na entrada [X, a][X, a]
– Prepara um Prepara um casamentocasamento entre entre pilhapilha e e entradaentrada
Exemplos:Exemplos: M[E’M[E’, , +] = E’ +] = E’ +TE’ +TE’ M[F, (] = F M[F, (] = F (E) (E)
M[T’, *] = T’ M[T’, *] = T’ *FT’ *FT’ M[F, id] = F M[F, id] = F id id
E E T E’ E’ T E’ E’ + T E’ | + T E’ | εε T T F T’ T’ F T’ T’ * F T’ | * F T’ | ε ε F F (( E E )) | | idid
Produção de Produção de XX em que o em que o primeiro símboloprimeiro símbolo do do lado direito é um lado direito é um não terminal Ynão terminal Y::
– Para ser colocada numa entrada Para ser colocada numa entrada [X, a][X, a] é é necessário ver se necessário ver se YY pode derivar uma pode derivar uma forma sentencial iniciada por forma sentencial iniciada por aa
É o caso das produções É o caso das produções E E TE’ TE’ e e T T FT’ FT’
E E T E’ E’ T E’ E’ + T E’ | + T E’ | εε T T F T’ T’ F T’ T’ * F T’ | * F T’ | ε ε F F (( E E )) | | idid
Produção vazia de Produção vazia de XX::
– Para ser colocada numa entrada Para ser colocada numa entrada [X, a][X, a] é é necessário ver se necessário ver se aa pode aparecer em pode aparecer em alguma forma sentencial depois de alguma forma sentencial depois de XX
5.4.5 – As funções Primeiro e Seguinte5.4.5 – As funções Primeiro e Seguinte
A construção da A construção da tabela de produçõestabela de produções é é auxiliada por duas auxiliada por duas funçõesfunções: : PrimeiroPrimeiro e e SeguinteSeguinte
Sendo Sendo (N (N )*)*, , Primeiro (Primeiro ()) é o conjunto é o conjunto dos dos terminaisterminais que iniciam todas as sentenças que iniciam todas as sentenças derivadas de derivadas de
Se Se * * εε, então , então εε Primeiro ( Primeiro ())
Observa-se que, se o primeiro símbolo de Observa-se que, se o primeiro símbolo de for for um um terminalterminal qualquer qualquer aa, então , então Primeiro (Primeiro () = ) = {a}{a}
Exemplo: Exemplo: seja seja = A B a C b c d D = A B a C b c d D
++
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ __ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
Todas as possíveis e talvez infinitas cadeias só de terminais
Eliminando-se os terminais repetidos, obtém-se Primeiro()
Como possui
terminais, *
ε portanto:
ε Primeiro ()
Utilidade da função Primeiro (Utilidade da função Primeiro () em análise ) em análise preditora:preditora:
Sejam as produções Sejam as produções A A | |
Na expansão de Na expansão de A A diante do terminal diante do terminal bb, a , a decisão por decisão por ouou , depende de , depende de b b pertencer a pertencer a Primeiro(Primeiro()) ou ou Primeiro(Primeiro())
Caso Caso bb pertença aos dois conjuntos, a pertença aos dois conjuntos, a indecisão persisteindecisão persiste
Caso Caso bb não pertença a nenhum dos dois não pertença a nenhum dos dois conjuntos: conjuntos: erroerro
Sendo Sendo AA um não-terminal qualquer, um não-terminal qualquer, Seguinte Seguinte (A)(A) é o conjunto dos é o conjunto dos terminaisterminais que podem que podem aparecer aparecer imediatamente à direitaimediatamente à direita de de AA, em , em alguma forma sentencialalguma forma sentencial
Mais precisamente, é o conjunto dos terminais Mais precisamente, é o conjunto dos terminais bb, tais que existe uma derivação da forma , tais que existe uma derivação da forma S S * *
AbAb
((,, (N (N )*))*)
Se Se AA for o símbolo for o símbolo mais a direitamais a direita de alguma de alguma forma sentencial, então forma sentencial, então $ $ Seguinte (A) Seguinte (A)
Exemplo: Exemplo: sejam todas as possivelmente infinitas sejam todas as possivelmente infinitas formas sentenciais de uma GLCformas sentenciais de uma GLC
S S ** _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
Em algumas (possivelmente infinitas) o não-terminal A aparece
Exemplo: Exemplo: sejam todas as possivelmente infinitas sejam todas as possivelmente infinitas formas sentenciais de uma GLCformas sentenciais de uma GLC
S S ** _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ A _ _ _ _ _ _ _ _ _ _ _ A _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ A _ _ _ _ _ _ _ _ _ _ _ A _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ A _ _ _ _ _ _ _ _ _ _ _ _ _ _ A
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ A _ _ _ _ _ _ _ _ _ _ _ _ A _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ AA _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
Colocando-se o finalizador ‘$’ em cada uma
Exemplo: Exemplo: sejam todas as possivelmente infinitas sejam todas as possivelmente infinitas formas sentenciais de uma GLCformas sentenciais de uma GLC
S S ** _ _ _ _ _ _ _ _ _ _ _ _ _ _ $_ _ _ _ _ _ _ _ _ _ _ _ _ _ $
_ _ _ _ _ A _ _ _ _ _ _ $_ _ _ _ _ A _ _ _ _ _ _ $
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ $_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ $
_ _ _ _ _ _ _ _ _ _ _ _ _ _ $_ _ _ _ _ _ _ _ _ _ _ _ _ _ $
_ _ _ _ _ _ _ A _ _ _ _ $_ _ _ _ _ _ _ A _ _ _ _ $
_ _ _ _ _ _ _ _ _ _ _ _ _ _ A $_ _ _ _ _ _ _ _ _ _ _ _ _ _ A $
_ _ _ _ _ _ _ _ _ _ _ _ $_ _ _ _ _ _ _ _ _ _ _ _ $
_ _ _ _ A _ _ _ _ _ _ _ _ $_ _ _ _ A _ _ _ _ _ _ _ _ $
_ _ _ _ _ _ _ _ _ _ _ _ $_ _ _ _ _ _ _ _ _ _ _ _ $
_ _ _ _ _ _ _ _ _ _ _ _ _ $_ _ _ _ _ _ _ _ _ _ _ _ _ $
_ _ _ _ _ _ _ _ _ A _ _ $ _ _ _ _ _ _ _ _ _ A _ _ $
_ _ _ _ _ _ _ _ _ _ _ _ _ $ _ _ _ _ _ _ _ _ _ _ _ _ _ $
Colocando-se os símbolos que seguem A
Exemplo: Exemplo: sejam todas as possivelmente infinitas sejam todas as possivelmente infinitas formas sentenciais de uma GLCformas sentenciais de uma GLC
S S ** _ _ _ _ _ _ _ _ _ _ _ _ _ _ $_ _ _ _ _ _ _ _ _ _ _ _ _ _ $
_ _ _ _ _ A B _ _ _ _ _ $_ _ _ _ _ A B _ _ _ _ _ $
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ $_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ $
_ _ _ _ _ _ _ _ _ _ _ _ _ _ $_ _ _ _ _ _ _ _ _ _ _ _ _ _ $
_ _ _ _ _ _ _ A a _ _ _ $_ _ _ _ _ _ _ A a _ _ _ $
_ _ _ _ _ _ _ _ _ _ _ _ _ _ A $_ _ _ _ _ _ _ _ _ _ _ _ _ _ A $
_ _ _ _ _ _ _ _ _ _ _ _ $_ _ _ _ _ _ _ _ _ _ _ _ $
_ _ _ _ A b _ _ _ _ _ _ _ $_ _ _ _ A b _ _ _ _ _ _ _ $
_ _ _ _ _ _ _ _ _ _ _ _ $_ _ _ _ _ _ _ _ _ _ _ _ $
_ _ _ _ _ _ _ _ _ _ _ _ _ $_ _ _ _ _ _ _ _ _ _ _ _ _ $
_ _ _ _ _ _ _ _ _ A D _ $ _ _ _ _ _ _ _ _ _ A D _ $
_ _ _ _ _ _ _ _ _ _ _ _ _ $ _ _ _ _ _ _ _ _ _ _ _ _ _ $
a, b, $ Seguinte (A)
Cálculo do Primeiro (Cálculo do Primeiro ():):
Seja Seja = X = X11 X X22 X X33 ... X ... Xnn, onde , onde XXii (1 (1 i i n) é n) é um terminal ou um não terminal:um terminal ou um não terminal:
O cálculo do O cálculo do Primeiro (Primeiro ()) exige o cálculo de exige o cálculo de Primeiro (XPrimeiro (Xii))
Algoritmo 5.4Algoritmo 5.4: Calcula : Calcula Primeiro (X)Primeiro (X), onde , onde X X (N (N ))
O cálculo é feito simultaneamente para todos os símbolos da gramática
O algoritmo tem 2 etapas:
1. Inicialização2. Processo rotativo convergente
Algoritmo 5.4Algoritmo 5.4: :
1. Inicialização
Para todo símbolo X da gramática {Se (X é terminal) Primeiro (X) {X};Senão se (X é uma produção)
Primeiro (X) {};Senão Primeiro (X) { };
}
2. Processo rotativo convergente
Aplicar a seguinte regra a toda produção não-vazia da gramática de modo rotativo, até que nenhum terminal ou seja acrescentado ao conjunto Primeiro de qualquer não-terminal:
Para cada produção do tipo X Y1Y2Y3 ... Yk (k 1) {Para (i 1; i k; i++)
Se (i = 1) || (j | (1 j i-1), Primeiro (Yj ))
Acrescentar(Primeiro (Yi ) - {}) a Primeiro
(X)Se (i | (1 i k), Primeiro (Yi ))
Acrescentar a Primeiro (X);}
Comentários: seja a produção X Y1Y2Y3 ... Yk (k 1)
Todo o terminal (excluído ) presente em Primeiro (Y1) certamente pertence a Primeiro (X)
Se Y1 não deriva , então nada mais deve ser acrescentado a Primeiro (X)
Mas se Y1 deriva , então deve-se acrescentar a Primeiro (X) todo terminal (excluído ) contido em Primeiro (Y2)
Comentários: seja a produção X Y1Y2Y3 ... Yk (k 1)
Se Y1, Y2 e Y3 derivam , então deve-se acrescentar a Primeiro (X) todo terminal contido em Primeiro (Y4)
E assim por diante
Se Y1, Y2 , Y3, ... , Yk derivam , então deve-se acrescentar a Primeiro (X)
Exemplo:Exemplo: seja a gramática: seja a gramática:
E E T E’ T E’ E’ E’ + T E’ | + T E’ | T T F T’ F T’ T’ T’ * F T’ | * F T’ | F F (( E E )) | | idid
Inicialização do Inicialização do Algoritmo 5.4Algoritmo 5.4::
Primeiro (+) = {+}Primeiro (+) = {+} Primeiro (*) = {*}Primeiro (*) = {*}
Primeiro (‘(’) = { ( }Primeiro (‘(’) = { ( } Primeiro (‘)’) = { ) }Primeiro (‘)’) = { ) }
Primeiro (id) = {id}Primeiro (id) = {id}
Primeiro (E’) = Primeiro (T’) = {Primeiro (E’) = Primeiro (T’) = {}}Primeiro (E) = Primeiro (T) = Primeiro Primeiro (E) = Primeiro (T) = Primeiro (F) = { }(F) = { }
E E T E’ T E’ E’ E’ + T E’ | + T E’ | T T F T’ F T’ T’ T’ * F T’ | * F T’ | F F (( E E )) | | idid
Processo rotativo do Processo rotativo do Algoritmo 5.4Algoritmo 5.4, 1, 1aa rotação: rotação:
Primeiro (+) = {+}Primeiro (+) = {+}
Primeiro (*) = {*}Primeiro (*) = {*}
Primeiro (‘(’) = { ( }Primeiro (‘(’) = { ( }
Primeiro (‘)’) = { ) }Primeiro (‘)’) = { ) }
Primeiro (id) = {id}Primeiro (id) = {id}
Primeiro (E’) = {Primeiro (E’) = {}}Primeiro (T’) = {Primeiro (T’) = {}}Primeiro (E) = { }Primeiro (E) = { }
Primeiro (T) = { }Primeiro (T) = { }
Primeiro (F) = { }Primeiro (F) = { }
E T E’ : Primeiro (T) = { }nada acontece
E’ + T E’ : Primeiro (+) = {+}, então
Primeiro (E’) = {, +}
E E T E’ T E’ E’ E’ + T E’ | + T E’ | T T F T’ F T’ T’ T’ * F T’ | * F T’ | F F (( E E )) | | idid
Processo rotativo do Processo rotativo do Algoritmo 5.4Algoritmo 5.4, 1, 1aa rotação: rotação:
Primeiro (+) = {+}Primeiro (+) = {+}
Primeiro (*) = {*}Primeiro (*) = {*}
Primeiro (‘(’) = { ( }Primeiro (‘(’) = { ( }
Primeiro (‘)’) = { ) }Primeiro (‘)’) = { ) }
Primeiro (id) = {id}Primeiro (id) = {id}
Primeiro (E’) = {Primeiro (E’) = {, +}, +}
Primeiro (T’) = {Primeiro (T’) = {}}Primeiro (E) = { }Primeiro (E) = { }
Primeiro (T) = { }Primeiro (T) = { }
Primeiro (F) = { }Primeiro (F) = { }
T F T’ : Primeiro (F) = { }nada acontece
T’ *F T’ : Primeiro (*) = {*}, então
Primeiro (T’) = {, *}
E E T E’ T E’ E’ E’ + T E’ | + T E’ | T T F T’ F T’ T’ T’ * F T’ | * F T’ | F F (( E E )) | | idid
Processo rotativo do Processo rotativo do Algoritmo 5.4Algoritmo 5.4, 1, 1aa rotação: rotação:
Primeiro (+) = {+}Primeiro (+) = {+}
Primeiro (*) = {*}Primeiro (*) = {*}
Primeiro (‘(’) = { ( }Primeiro (‘(’) = { ( }
Primeiro (‘)’) = { ) }Primeiro (‘)’) = { ) }
Primeiro (id) = {id}Primeiro (id) = {id}
Primeiro (E’) = {Primeiro (E’) = {, +}, +}
Primeiro (T’) = {Primeiro (T’) = {, *}}
Primeiro (E) = { }Primeiro (E) = { }
Primeiro (T) = { }Primeiro (T) = { }
Primeiro (F) = { }Primeiro (F) = { }
F ( E ) : Primeiro (‘(’) = { ( }, então
Primeiro (F) = { ( }
E E T E’ T E’ E’ E’ + T E’ | + T E’ | T T F T’ F T’ T’ T’ * F T’ | * F T’ | F F (( E E )) | | idid
Processo rotativo do Processo rotativo do Algoritmo 5.4Algoritmo 5.4, 1, 1aa rotação: rotação:
Primeiro (+) = {+}Primeiro (+) = {+}
Primeiro (*) = {*}Primeiro (*) = {*}
Primeiro (‘(’) = { ( }Primeiro (‘(’) = { ( }
Primeiro (‘)’) = { ) }Primeiro (‘)’) = { ) }
Primeiro (id) = {id}Primeiro (id) = {id}
Primeiro (E’) = {Primeiro (E’) = {, +}, +}
Primeiro (T’) = {Primeiro (T’) = {, *}}
Primeiro (E) = { }Primeiro (E) = { }
Primeiro (T) = { }Primeiro (T) = { }
Primeiro (F) = { ( }Primeiro (F) = { ( }
F id : Primeiro (id) = { id }, então
Primeiro (F) = { (, id }
E E T E’ T E’ E’ E’ + T E’ | + T E’ | T T F T’ F T’ T’ T’ * F T’ | * F T’ | F F (( E E )) | | idid
Processo rotativo do Processo rotativo do Algoritmo 5.4Algoritmo 5.4, final da 1, final da 1aa rotaçãorotação
Primeiro (+) = {+}Primeiro (+) = {+}
Primeiro (*) = {*}Primeiro (*) = {*}
Primeiro (‘(’) = { ( }Primeiro (‘(’) = { ( }
Primeiro (‘)’) = { ) }Primeiro (‘)’) = { ) }
Primeiro (id) = {id}Primeiro (id) = {id}
Primeiro (E’) = {Primeiro (E’) = {, +}, +}
Primeiro (T’) = {Primeiro (T’) = {, *}}
Primeiro (E) = { }Primeiro (E) = { }
Primeiro (T) = { }Primeiro (T) = { }
Primeiro (F) = { (, id }Primeiro (F) = { (, id }
E E T E’ T E’ E’ E’ + T E’ | + T E’ | T T F T’ F T’ T’ T’ * F T’ | * F T’ | F F (( E E )) | | idid
Processo rotativo do Processo rotativo do Algoritmo 5.4Algoritmo 5.4, 2, 2aa rotação: rotação:
Primeiro (+) = {+}Primeiro (+) = {+}
Primeiro (*) = {*}Primeiro (*) = {*}
Primeiro (‘(’) = { ( }Primeiro (‘(’) = { ( }
Primeiro (‘)’) = { ) }Primeiro (‘)’) = { ) }
Primeiro (id) = {id}Primeiro (id) = {id}
Primeiro (E’) = {Primeiro (E’) = {, +}, +}
Primeiro (T’) = {Primeiro (T’) = {, *}}
Primeiro (E) = { }Primeiro (E) = { }
Primeiro (T) = { }Primeiro (T) = { }
Primeiro (F) = { (, id }Primeiro (F) = { (, id }
E T E’ : Primeiro (T) = { }nada acontece
E’ + T E’ : Primeiro (+) = {+},
nada aconteceT F T’ : Primeiro (F) = { (, id }, então
Primeiro (T) = { (, id }
E E T E’ T E’ E’ E’ + T E’ | + T E’ | T T F T’ F T’ T’ T’ * F T’ | * F T’ | F F (( E E )) | | idid
Processo rotativo do Processo rotativo do Algoritmo 5.4Algoritmo 5.4, 2, 2aa rotação: rotação:
Primeiro (+) = {+}Primeiro (+) = {+}
Primeiro (*) = {*}Primeiro (*) = {*}
Primeiro (‘(’) = { ( }Primeiro (‘(’) = { ( }
Primeiro (‘)’) = { ) }Primeiro (‘)’) = { ) }
Primeiro (id) = {id}Primeiro (id) = {id}
Primeiro (E’) = {Primeiro (E’) = {, +}, +}
Primeiro (T’) = {Primeiro (T’) = {, *}}
Primeiro (E) = { }Primeiro (E) = { }
Primeiro (T) = { (, id }Primeiro (T) = { (, id }
Primeiro (F) = { (, id }Primeiro (F) = { (, id }
T’ * F T’ : Primeiro (*) = {*}, nada acontece
F ( E ) : Primeiro (‘(’) = { ( }, nada acontece
F id : Primeiro (id) = { id }, nada acontece
E E T E’ T E’ E’ E’ + T E’ | + T E’ | T T F T’ F T’ T’ T’ * F T’ | * F T’ | F F (( E E )) | | idid
Processo rotativo do Processo rotativo do Algoritmo 5.4Algoritmo 5.4, final da 2, final da 2aa rotaçãorotação
Primeiro (+) = {+}Primeiro (+) = {+}
Primeiro (*) = {*}Primeiro (*) = {*}
Primeiro (‘(’) = { ( }Primeiro (‘(’) = { ( }
Primeiro (‘)’) = { ) }Primeiro (‘)’) = { ) }
Primeiro (id) = {id}Primeiro (id) = {id}
Primeiro (E’) = {Primeiro (E’) = {, +}, +}
Primeiro (T’) = {Primeiro (T’) = {, *}}
Primeiro (E) = { }Primeiro (E) = { }
Primeiro (T) = { (, id }Primeiro (T) = { (, id }
Primeiro (F) = { (, id }Primeiro (F) = { (, id }
E E T E’ T E’ E’ E’ + T E’ | + T E’ | T T F T’ F T’ T’ T’ * F T’ | * F T’ | F F (( E E )) | | idid
Processo rotativo do Processo rotativo do Algoritmo 5.4Algoritmo 5.4, 3, 3aa rotação: rotação:
Primeiro (+) = {+}Primeiro (+) = {+}
Primeiro (*) = {*}Primeiro (*) = {*}
Primeiro (‘(’) = { ( }Primeiro (‘(’) = { ( }
Primeiro (‘)’) = { ) }Primeiro (‘)’) = { ) }
Primeiro (id) = {id}Primeiro (id) = {id}
Primeiro (E’) = {Primeiro (E’) = {, +}, +}
Primeiro (T’) = {Primeiro (T’) = {, *}}
Primeiro (E) = { }Primeiro (E) = { }
Primeiro (T) = { (, id }Primeiro (T) = { (, id }
Primeiro (F) = { (, id }Primeiro (F) = { (, id }
E T E’ : Primeiro (T) = { (, id }
Primeiro (E) = { (, id }
E E T E’ T E’ E’ E’ + T E’ | + T E’ | T T F T’ F T’ T’ T’ * F T’ | * F T’ | F F (( E E )) | | idid
Processo rotativo do Processo rotativo do Algoritmo 5.4Algoritmo 5.4, 3, 3aa rotação: rotação:
Primeiro (+) = {+}Primeiro (+) = {+}
Primeiro (*) = {*}Primeiro (*) = {*}
Primeiro (‘(’) = { ( }Primeiro (‘(’) = { ( }
Primeiro (‘)’) = { ) }Primeiro (‘)’) = { ) }
Primeiro (id) = {id}Primeiro (id) = {id}
Primeiro (E’) = {Primeiro (E’) = {, +}, +}
Primeiro (T’) = {Primeiro (T’) = {, *}}
Primeiro (E) = { (, id }Primeiro (E) = { (, id }
Primeiro (T) = { (, id }Primeiro (T) = { (, id }
Primeiro (F) = { (, id }Primeiro (F) = { (, id }
Com as outras produçõesnada acontece
E E T E’ T E’ E’ E’ + T E’ | + T E’ | T T F T’ F T’ T’ T’ * F T’ | * F T’ | F F (( E E )) | | idid
Processo rotativo do Processo rotativo do Algoritmo 5.4Algoritmo 5.4, final da 3, final da 3aa rotaçãorotação
Primeiro (+) = {+}Primeiro (+) = {+}
Primeiro (*) = {*}Primeiro (*) = {*}
Primeiro (‘(’) = { ( }Primeiro (‘(’) = { ( }
Primeiro (‘)’) = { ) }Primeiro (‘)’) = { ) }
Primeiro (id) = {id}Primeiro (id) = {id}
Primeiro (E’) = {Primeiro (E’) = {, +}, +}
Primeiro (T’) = {Primeiro (T’) = {, *}}
Primeiro (E) = { (, id }Primeiro (E) = { (, id }
Primeiro (T) = { (, id }Primeiro (T) = { (, id }
Primeiro (F) = { (, id }Primeiro (F) = { (, id }
E E T E’ T E’ E’ E’ + T E’ | + T E’ | T T F T’ F T’ T’ T’ * F T’ | * F T’ | F F (( E E )) | | idid
Processo rotativo do Processo rotativo do Algoritmo 5.4Algoritmo 5.4, 4, 4aa rotação: rotação:
Primeiro (+) = {+}Primeiro (+) = {+}
Primeiro (*) = {*}Primeiro (*) = {*}
Primeiro (‘(’) = { ( }Primeiro (‘(’) = { ( }
Primeiro (‘)’) = { ) }Primeiro (‘)’) = { ) }
Primeiro (id) = {id}Primeiro (id) = {id}
Primeiro (E’) = {Primeiro (E’) = {, +}, +}
Primeiro (T’) = {Primeiro (T’) = {, *}}
Primeiro (E) = { (, id }Primeiro (E) = { (, id }
Primeiro (T) = { (, id }Primeiro (T) = { (, id }
Primeiro (F) = { (, id }Primeiro (F) = { (, id }
Nada acontece
Ficam determinados os Primeiro’s de todos os símbolos
Algoritmo 5.5: Algoritmo 5.5: Cálculo do Cálculo do Primeiro (Primeiro ()), ,
onde onde = X = X11 X X22 X X33 ... X ... Xnn e e XXii (N (N )), (1 , (1 i i n) n)
Primeiro (Primeiro () ) { }; { };
Para (i Para (i 1; i 1; i n; i++) n; i++)
Se (i = 1) || (Se (i = 1) || (j | (1 j | (1 j j i-1), i-1), Primeiro (XPrimeiro (Xjj )) ))
Acrescentar (Primeiro (XAcrescentar (Primeiro (Xii ) - { ) - {}) a }) a Primeiro (Primeiro () ;) ;
Se (Se (i | (1 i | (1 i i n), n), Primeiro (X Primeiro (Xii )) ))
Acrescentar Acrescentar a Primeiro ( a Primeiro (););
Se (Se ( = = ) Primeiro () Primeiro () ) { {};};
Comentários: seja = X = X11 X X22 X X33 ... X ... Xnn
Todos os terminais de Todos os terminais de Primeiro (XPrimeiro (X11)) devem devem pertencer a pertencer a Primeiro (Primeiro ())
Caso (Caso ( Primeiro (XPrimeiro (X11))), todos os terminais ), todos os terminais de de Primeiro (XPrimeiro (X22 ) ) devem pertencer a devem pertencer a Primeiro (Primeiro ())
Caso (Caso ( Primeiro (XPrimeiro (X11)) e e Primeiro (XPrimeiro (X22))),), todos os terminais de todos os terminais de Primeiro (XPrimeiro (X33)) devem devem pertencer a pertencer a Primeiro (Primeiro ())
E assim por dianteE assim por diante
Algoritmo 5.6Algoritmo 5.6: Calcula : Calcula Seguinte (A)Seguinte (A), onde , onde A A é é um não-terminalum não-terminal
O cálculo é feito simultaneamente para todos os não-terminais da gramática
O algoritmo tem 3 etapas
1. Inicialização trivial2. Inicialização não-trivial3. Processo rotativo convergente
Algoritmo 5.6Algoritmo 5.6: :
1. Inicialização trivial
Seguinte (S)Seguinte (S) { {$$}; /* S é o símbolo }; /* S é o símbolo inicial inicial */*/
/* /* $$ é marca de fim da é marca de fim da sentença sentença */*/
Inicializar Inicializar Seguinte Seguinte de todos os outros não-de todos os outros não-terminais com o terminais com o conjuntoconjunto vaziovazio
Comentários:Comentários:
S S ** _ _ _ _ _ _ _ _ _ _ _ _ _ _ $_ _ _ _ _ _ _ _ _ _ _ _ _ _ $
_ _ _ _ _ _ _ _ _ _ _ $_ _ _ _ _ _ _ _ _ _ _ $
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ $_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ $
_ _ _ _ _ _ _ _ _ _ _ _ _ _ $_ _ _ _ _ _ _ _ _ _ _ _ _ _ $
_ _ _ _ _ _ _ _ _ _ _ $_ _ _ _ _ _ _ _ _ _ _ $
_ _ _ _ _ _ _ _ _ _ _ _ _ _ $_ _ _ _ _ _ _ _ _ _ _ _ _ _ $
_ _ _ _ _ _ _ _ _ _ _ _ $_ _ _ _ _ _ _ _ _ _ _ _ $
S $S $
_ _ _ _ _ _ _ _ _ _ _ _ $_ _ _ _ _ _ _ _ _ _ _ _ $
_ _ _ _ _ _ _ _ _ _ _ _ _ $_ _ _ _ _ _ _ _ _ _ _ _ _ $
_ _ _ _ _ _ _ _ _ _ _ $ _ _ _ _ _ _ _ _ _ _ _ $
_ _ _ _ _ _ _ _ _ _ _ _ _ $ _ _ _ _ _ _ _ _ _ _ _ _ _ $
$ Seguinte (S)
2. Inicialização não-trivial
Para toda produção do tipo Para toda produção do tipo
A A w w11 B B11 w w22 B B22 w w33 ... w ... wn n BBnn w wn+1n+1,,
(n (n 1; 1; wwii **, 1 , 1 i i n+1; n+1; BBii N N, , 1 1 i i n) {n) {
ParaPara (i (i 1; i 1; i n; i++) { n; i++) {
Expressão da produção: Expressão da produção: A A ii B Bii ii,,
((ii, , ii (N (N ))**););
Se (Se (ii não é vazia) Acrescentar não é vazia) Acrescentar
((Primeiro (Primeiro (ii ) ) - { - {}) a }) a Seguinte (BSeguinte (Bii)) ;;
}}
}}
Pelo menos um não-terminal do lado direito
Comentários: Comentários: seja a produção seja a produção A A ii B Bii ii
SendoSendo A A um não-terminal útil, haverá pelo um não-terminal útil, haverá pelo menos uma forma sentencial do tipomenos uma forma sentencial do tipo
_ _ _ _ _ _ _ _ _ _ _ _ A _ _ _ _ $_ _ _ _ _ _ _ _ _ _ _ _ A _ _ _ _ $
E haverá outra do tipoE haverá outra do tipo
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ii B Bii i i _ _ _ _ $_ _ _ _ $
Então Então (Primeiro ((Primeiro (ii) – {) – {}) }) Seguinte (B Seguinte (Bii))
i pode ser vazia ou derivar a cadeia vazia
Se for vazia, Primeiro(i) = {}
3. Processo rotativo convergente
Aplicar a seguinte regra a toda produção não-vazia da gramática de modo rotativo, até que nenhum terminal ou $ seja acrescentado ao conjunto Seguinte de qualquer não terminal:
Seja Seja A A w w11 B B11 w w22 B B22 w w33 ... w ... wn n BBnn w wn+1n+1, a produção , a produção em questão, onde (n em questão, onde (n 1; 1; wwii **, 1 , 1 i i n+1; n+1; BBii N N, , 1 1 i i n): n):
ParaPara (i (i 1; i 1; i n; i++) { n; i++) {Expressão da produção: Expressão da produção: A A ii B Bii ii,,
((ii, , ii (N (N ))**););Se ((Se ((ii é vazia) ou (é vazia) ou ( Primeiro (Primeiro (ii))))))
Acrescentar Acrescentar Seguinte (A) Seguinte (A) a a Seguinte Seguinte (B(Bii)) ; ;
}}
Pelo menos um não-terminal do lado direito
Comentários: Comentários: seja a produção seja a produção A A ii B Bii ii
Se Se aa, , bb, , cc, , $ $ Seguinte (A) Seguinte (A), há formas , há formas sentenciais dos tipossentenciais dos tipos
_ _ _ _ _ _ A a _ _ _ $_ _ _ _ _ _ A a _ _ _ $
_ _ _ _ A b _ _ _ $_ _ _ _ A b _ _ _ $
_ _ _ _ _ A c _ _ _ $_ _ _ _ _ A c _ _ _ $
_ _ _ _ _ _ A $_ _ _ _ _ _ A $
E também dos tiposE também dos tipos
_ _ _ _ _ _ _ _ _ _ _ _ ii B Bii ii a _ _ _ $ a _ _ _ $
_ _ _ _ _ _ _ _ ii B Bii ii b _ _ _ $ b _ _ _ $
_ _ _ _ _ _ _ _ _ _ ii B Bii ii c _ _ _ $ c _ _ _ $
_ _ _ _ _ _ _ _ _ _ _ _ ii B Bii ii $ $
Se i é vazia: a, b, c, $ Seguinte (Bi)
Se Primeiro (i), ou seja,se i * : há formas sentenciais em que a, b, c, $ aparecem imediatamente depois de Bi
Então, acrescentar a, b, c, $ ao Seguinte (Bi)
Ou seja, acrescentar Seguinte (A) ao Seguinte (Bi)
Exemplo:Exemplo: seja a mesma gramática: seja a mesma gramática:
E E T E’ T E’ E’ E’ + T E’ | + T E’ | T T F T’ F T’ T’ T’ * F T’ | * F T’ | F F (( E E )) | |
idid
Seja a tabela dos Seja a tabela dos PrimeiroPrimeiro’s de seus não-’s de seus não-terminais calculada no exemplo anterior:terminais calculada no exemplo anterior:
Inicialização trivial do Inicialização trivial do Algoritmo 5.6Algoritmo 5.6:
Seguinte (E) = {$}Seguinte (E’) = { }Seguinte (T) = { }Seguinte (T’) = { }Seguinte (F) = { }
Inicialização não-trivial do Inicialização não-trivial do Algoritmo 5.6Algoritmo 5.6::
Seguinte (E) = {$}Seguinte (E’) = { }Seguinte (T) = { }Seguinte (T’) = { }Seguinte (F) = { }
Produção E E T E’ T E’::
Seguinte (T) = Seguinte (T) (Primeiro (E’) – {ε}) = { } ({+, ε} – {ε}) = {+}
Inicialização não-trivial do Inicialização não-trivial do Algoritmo 5.6Algoritmo 5.6::
Seguinte (E) = {$}Seguinte (E’) = { }Seguinte (T) = {+}Seguinte (T’) = { }Seguinte (F) = { }
Produção E E T E’ T E’::
Seguinte (T) = Seguinte (T) (Primeiro (E’) – {ε}) = { } ({+, ε} – {ε}) = {+}
Inicialização não-trivial do Inicialização não-trivial do Algoritmo 5.6Algoritmo 5.6::
Seguinte (E) = {$}Seguinte (E’) = { }Seguinte (T) = {+}Seguinte (T’) = { }Seguinte (F) = { }
Produção E’ E’ +T E’ +T E’::
Seguinte (T) = Seguinte (T) (Primeiro (E’) – {ε}) = {+} ({+, ε} – {ε}) = {+}
Inicialização não-trivial do Inicialização não-trivial do Algoritmo 5.6Algoritmo 5.6::
Seguinte (E) = {$}Seguinte (E’) = { }Seguinte (T) = {+}Seguinte (T’) = { }Seguinte (F) = { }
Produção T T FT’ FT’::
Seguinte (F) = Seguinte (F) (Primeiro (T’) – {ε}) = { } ({*, ε} – {ε}) = {*}
Inicialização não-trivial do Inicialização não-trivial do Algoritmo 5.6Algoritmo 5.6::
Seguinte (E) = {$}Seguinte (E’) = { }Seguinte (T) = {+}Seguinte (T’) = { }Seguinte (F) = {*}
Produção T T FT’ FT’::
Seguinte (F) = Seguinte (F) (Primeiro (T’) – {ε}) = { } ({*, ε} – {ε}) = {*}
Inicialização não-trivial do Inicialização não-trivial do Algoritmo 5.6Algoritmo 5.6::
Seguinte (E) = {$}Seguinte (E’) = { }Seguinte (T) = {+}Seguinte (T’) = { }Seguinte (F) = {*}
Produção T’ T’ *FT’ *FT’::
Seguinte (F) = Seguinte (F) (Primeiro (T’) – {ε}) = {*} ({*, ε} – {ε}) = {*}
Inicialização não-trivial do Inicialização não-trivial do Algoritmo 5.6Algoritmo 5.6::
Seguinte (E) = {$}Seguinte (E’) = { }Seguinte (T) = {+}Seguinte (T’) = { }Seguinte (F) = {*}
Produção F F (E) (E)::
Seguinte (E) = Seguinte (E) (Primeiro (‘)’) – {ε}) = {$} ({ ) } – {ε}) = {$, )}
Inicialização não-trivial do Inicialização não-trivial do Algoritmo 5.6Algoritmo 5.6::
Seguinte (E) = {$, )}Seguinte (E’) = { }Seguinte (T) = {+}Seguinte (T’) = { }Seguinte (F) = {*}
Final da inicialização não-trivial do Final da inicialização não-trivial do Algoritmo Algoritmo 5.65.6::
Seguinte (E) = {$, )}Seguinte (E’) = { }Seguinte (T) = {+}Seguinte (T’) = { }Seguinte (F) = {*}
Processo rotativo do Processo rotativo do Algoritmo 5.6Algoritmo 5.6, 1, 1aa rotação:rotação:
Seguinte (E) = {$, )}Seguinte (E’) = { }Seguinte (T) = {+}Seguinte (T’) = { }Seguinte (F) = {*}
Produção E E T E’ T E’: (: (ε Primeiro (E’)))
Seguinte (T) = Seguinte (T) Seguinte (E) = {+} {$, )} = {+, $, )}
Processo rotativo do Processo rotativo do Algoritmo 5.6Algoritmo 5.6, 1, 1aa rotação:rotação:
Seguinte (E) = {$, )}Seguinte (E’) = { }Seguinte (T) = {+, $, )}Seguinte (T’) = { }Seguinte (F) = {*}
Produção E E T E’ T E’::
Seguinte (T) = Seguinte (T) Seguinte (E) = {+} {$, )} = {+, $, )}
Seguinte (E’) = Seguinte (E’) Seguinte (E) = { } {$, )} = {$, )}
Processo rotativo do Processo rotativo do Algoritmo 5.6Algoritmo 5.6, 1, 1aa rotação:rotação:
Seguinte (E) = {$, )}Seguinte (E’) = {$, )}Seguinte (T) = {+, $, )}Seguinte (T’) = { }Seguinte (F) = {*}
Produção T T F T’ F T’: (: (ε Primeiro (T’)))
Seguinte (F) = Seguinte (F) Seguinte (T) = {*} {+, $, )} = {*, +, $, )}
Processo rotativo do Processo rotativo do Algoritmo 5.6Algoritmo 5.6, 1, 1aa rotação:rotação:
Seguinte (E) = {$, )}Seguinte (E’) = {$, )}Seguinte (T) = {+, $, )}Seguinte (T’) = { }Seguinte (F) = {*, +, $, )}
Produção T T F T’ F T’::
Seguinte (F) = Seguinte (F) Seguinte (T) = {*} {+, $, )} = {*, +, $, )}
Seguinte (T’) = Seguinte (T’) Seguinte (T) = { } {+, $, )} = {+, $, )}
Processo rotativo do Processo rotativo do Algoritmo 5.6Algoritmo 5.6, 1, 1aa rotação:rotação:
Seguinte (E) = {$, )}Seguinte (E’) = {$, )}Seguinte (T) = {+, $, )}Seguinte (T’) = {+, $, )}Seguinte (F) = {*, +, $, )}
Produção T’ T’ * F T’ * F T’: (: (ε Primeiro (T’)))
Seguinte (F) = Seguinte (F) Seguinte (T’) = {*, +, $, )} {+, $, )} = {*, +, $, )}
Seguinte (T’) = Seguinte (T’) Seguinte (T’) = {+, $, )} {+, $, )} = {+, $, )}
Processo rotativo do Processo rotativo do Algoritmo 5.6Algoritmo 5.6, 1, 1aa rotação:rotação:
Seguinte (E) = {$, )}Seguinte (E’) = {$, )}Seguinte (T) = {+, $, )}Seguinte (T’) = {+, $, )}Seguinte (F) = {*, +, $, )}
Produção FF ( E ) ( E ): (Não se aplica a regra, pois : (Não se aplica a regra, pois ε Primeiro (‘)’)))
Final da 1Final da 1aa rotação do processo rotativo do rotação do processo rotativo do Algoritmo 5.6Algoritmo 5.6::
Seguinte (E) = {$, )}Seguinte (E’) = {$, )}Seguinte (T) = {+, $, )}Seguinte (T’) = {+, $, )}Seguinte (F) = {*, +, $, )}
Processo rotativo do Processo rotativo do Algoritmo 5.6Algoritmo 5.6, 2, 2aa rotação:rotação:
Seguinte (E) = {$, )}Seguinte (E’) = {$, )}Seguinte (T) = {+, $, )}Seguinte (T’) = {+, $, )}Seguinte (F) = {*, +, $, )}
Nada é alterado
Ficam determinados os Seguinte’s de todos os não-terminais
5.4.6 – Construção da tabela de 5.4.6 – Construção da tabela de produçõesproduções
Seja Seja AA um não-terminal e um não-terminal e aa um terminal um terminal
Sejam Sejam A A as produções de as produções de AA
Se Se a a Primeiro ( Primeiro ())
Então:
A pode expandir para , na presença de a na entrada
pode gerar sub-sentenças iniciadas por a, para casar com o a na entrada
Sejam Sejam A A as produções de as produções de AA
Se Se a a (Primeiro ( (Primeiro ()) e Primeiro ( e Primeiro () e ) e Primeiro (Primeiro ()) ))
E se E se ,, e e não derivarem não derivarem εε
Então:
Erro com A na presença de a na entrada
A só gera sub-sentenças não-vazias e não iniciadas por a
Nunca aparecerá um a no topo da pilha para casar com o a na entrada
Sejam Sejam A A as produções de as produções de AA
Se Se a a (Primeiro ( (Primeiro ()) e Primeiro ( e Primeiro () e ) e Primeiro (Primeiro ()))), , mas se pelo menosmas se pelo menos derivar derivar εε
E se E se a a Seguinte (A) Seguinte (A)
Então:
A pode expandir para na presença de a na entrada
Existe a possibilidade de haver um a abaixo do A, na pilha, ou um não-terminal que gere algo iniciado por a
Algoritmo 5.7: Algoritmo 5.7: Construção da tabela de produçõesConstrução da tabela de produções
Para Para cada produção cada produção A A da gramática { da gramática {
Para Para cada terminal cada terminal aa em em Primeiro (Primeiro ())
Acrescentar Acrescentar A A a a M[A, a]M[A, a]; ;
Se Se ((ε ε Primeiro ( Primeiro ())) { ) {
Para Para todo terminal todo terminal bb em em Seguinte (A)Seguinte (A)
Acrescentar Acrescentar A A a a M[A, b]M[A, b]; ;
Se Se (($ $ Seguinte (A) Seguinte (A)))
Acrescentar Acrescentar A A a a M[A, $]M[A, $]; ;
}}
}}
Colocar Colocar ErroErro em cada posição em cada posição indefinidaindefinida da tabela. da tabela.
Exemplo:Exemplo: seja a mesma gramática: seja a mesma gramática:
E E T E’ T E’ E’ E’ + T E’ | + T E’ | T T F T’ F T’ T’ T’ * F T’ | * F T’ | F F (( E E )) | |
idid
Tabelas dos Tabelas dos PrimeiroPrimeiro’s e ’s e SeguinteSeguinte’s já ’s já calculadas:calculadas:
E E T E’ T E’ E’ E’ + T E’ | + T E’ | T T F T’ F T’ T’ T’ * F T’ | * F T’ | F F (( E E )) | |
idid
Tabela de produções:Tabela de produções:
Sejam Sejam A A as produções de as produções de AA
Se Se a a (Primeiro ( (Primeiro ()) e e Primeiro ( Primeiro ())))
Então: indecisão
A pode expandir para ou , na presença de a na entrada
A gramática não é LL(1), ou seja, não admite análise preditora
Sejam Sejam A A as produções de as produções de AA
Se Se a a (Primeiro ( (Primeiro ()) e e Seguinte (A) Seguinte (A)))
e se e se derivar derivar εε
Então: indecisão
A pode expandir para ou , na presença de a na entrada
A gramática não é LL(1), ou seja, não admite análise preditora
Indecisão: duas ou mais produções numa posição M[A, a] da tabela
Exemplo:Exemplo: seja a gramática para seja a gramática para if-elseif-else::
S S i b S S’ | a i b S S’ | a S’ S’ e S | e S |
Tabelas:Tabelas:
M[S’, e] tem duas produções
Tipicamente decide-se por
S’ e S
O else corresponde ao último if
5.4.7 – Tratamento de erros5.4.7 – Tratamento de erros
Um erro é detectado quando:Um erro é detectado quando:
Um terminal no topo da pilha não casa com o próximo símbolo na entrada
b era esperadoO não-terminal no topo da pilha e o próximo símbolo de entrada determinam uma posição de erro na tabela de produções
a não era esperado
O terminal no topo da pilha não casa com o O terminal no topo da pilha não casa com o próximo símbolo na entrada:próximo símbolo na entrada:
Mensagem: Mensagem: b era esperadob era esperado
Ação típica: desempilhar o terminal da pilhaAção típica: desempilhar o terminal da pilha
Resolve o caso de esquecimento de b
O não-terminal no O não-terminal no topotopo da pilha e o próximo da pilha e o próximo símbolo de símbolo de entradaentrada determinam determinam erroerro na na tabela de produções:tabela de produções:
Mensagem: Mensagem: a não era esperadoa não era esperado
É difícil escolher a melhor açãoÉ difícil escolher a melhor ação
Uma das técnicas mais usadas é o uso de um Uma das técnicas mais usadas é o uso de um conjunto de conjunto de terminais de sincronismoterminais de sincronismoDescarta-se terminais de entrada até que se encontre um desses terminais
Seja sincr a designação desse terminal
Terminais de sincronismoTerminais de sincronismo::
Terminais do Terminais do Seguinte (A)Seguinte (A): desempilhar : desempilhar A A - o - o que estiver abaixo do que estiver abaixo do AA na pilha pode ser: na pilha pode ser:
Um terminal também pertencente a Um terminal também pertencente a Seguinte (A) Seguinte (A) que case com que case com sincrsincr
Um não-terminal que expanda para uma Um não-terminal que expanda para uma cadeia iniciada por cadeia iniciada por sincrsincr
Terminais de sincronismoTerminais de sincronismo::
Terminais do Terminais do Primeiro (A)Primeiro (A): não desempilhar : não desempilhar AA::
Haverá uma posição sem erro na tabelaHaverá uma posição sem erro na tabela Há possibilidade de retomar a análiseHá possibilidade de retomar a análise
Ainda para não-terminal Ainda para não-terminal AA no topo da pilha: no topo da pilha:
Se houver a produção Se houver a produção A A εε,, pode-se usá-la pode-se usá-la para expandir para expandir AA, retardando o tratamento do , retardando o tratamento do erroerro
Pode-se incluir também, no conjunto de Pode-se incluir também, no conjunto de terminais de sincronismo, terminais de sincronismo, palavras palavras reservadasreservadas que iniciam comandos que iniciam comandos
Consultar a literatura para mais detalhesConsultar a literatura para mais detalhes