Você está na página 1de 27

INF25 Compiladores

Analisador Sinttico de Descida Recursiva

Anlise de Descida Recursiva

uma anlise sinttica top-down ou descendente um parser LL(1)

Left-to-right a ordem de leitura dos tokens da esquerda para a direita Leftmost derivation segue a ordem tpica de uma derivao mais esquerda S olha 1 token por vez
2

Anlise de Descida Recursiva

til para construir parsers manualmente, por ser fcil de implementar Princpio Bsico

Se eu quero produzir um no-terminal e sei qual o terminal corrente eu devo saber que regra deve ser aplicada.

Mostraremos como usar a tcnica, assumindo que o parser final ser uma classe Java

Classe Parser

Atributos tpicos

A classe Lexer (ser o atributo lexer) O ltimo token lido (ser o atributo token)

Operao principal

Mtodo parse()

Mtodos auxiliares

Para aceitar os tokens, se estiverem corretos Para reconhecimento (parsing) de no-terminais


4

Mtodos para Tokens

Sero dois mtodos para aceitar tokens, ambos sero chamados acceptToken() Uma verso receber o tipo do token que o analisador espera

Se o token no for do tipo esperado, reporta um erro

A outra verso no receber parmetro

Usado quando o tipo dele j conhecido e vlido


5

Mtodos para Tokens

Ambos os mtodos acceptToken atualizam o atributo token, lendo o prximo token

A primeira verso (tipo como parmetro) s l se o tipo do token anterior estiver correto

Assim, s esses dois mtodos atualizam o atributo token

Portanto, s eles podem chamar o lexer

Mtodos para No-Terminais

Cada no-terminal N ter um mtodo especfico que chamaremos parseN() O objetivo desse mtodo reconhecer uma sequncia de smbolos que case com alguma das produes de N aqui que est a principal caracterstica da anlise de descida recursiva...
7

Anlise de Descida Recursiva

Portanto, cada mtodo parseN() dever:

Identificar a produo adequada N X1 X2 ...XK Em seguida, dever chamar o mtodo para reconhecer cada smbolo Xi

Se for um no-terminal, chama parseXi() Se for um terminal, chama acceptToken()

Produo nica

Um no-terminal com apenas uma produo o caso mais simples de ser tratado
frase ::= sujeito predicado .

Ficar assim
void parseFrase() { parseSujeito(); parsePredicado(); acceptToken(PONTO); }
9

Mltiplas Produes

Porm, quando houver mais de uma produo, preciso usa um critrio de escolha Por exemplo:
sujeito ::= Eu | Um substantivo | O substantivo

Como escolher a produo certa (ou seja, a que representa o cdigo fonte) durante a anlise?
10

Mltiplas Produes

No exemplo anterior, basta olhar o token atual

void parseSujeito() { TokenType tp = this.token.getType(); if (tp == TokenType.EU) { acceptToken(); } else if (tp == TokenType.UM) { acceptToken(); parseSubstantivo(); } else if (tp == TokenType.O) { acceptToken(); parseSubstantivo(); } else { <.. reportar erro ..> } }

11

Conjunto FIRST

FIRST()

Aplicado a cadeias quaisquer

o conjunto de terminais que podem iniciar a cadeia dada

Se a cadeia derivar vazio, tambm inclui

12

Conjunto FIRST

Se for a cadeia vazia ( = )

FIRST() = { }

Se for um terminal a qualquer

FIRST(a) = { a }

Se for um no-terminal N com as produes N |

FIRST(N) = FIRST() FIRST()


13

Conjunto FIRST

Se for uma cadeia de smbolos = X1X2...Xk

Depende de X1

Se X1 no pode gerar vazio

FIRST (X1X2...Xk) = FIRST(X1)

Se X1 pode gerar vazio


FIRST (X1X2...Xk) = FIRST(X1) FIRST(X2...Xk) Calcula para X1 e continua o clculo recursivamente para o restante da cadeia
14

Fatorao Esquerda

Alguns casos em que as produes tm seus conjuntos FIRST idnticos podem ser tratados Um deles quando as produes tm prefixos comuns Exemplo

cmd ::= if exp then cmd else cmd | if exp then cmd | outro
15

Fatorao Esquerda

A soluo parecida com a fatorao em expresses matemticas


Colocar a parte comum em evidncia A parte diferente pode se tornar outro noterminal

Exemplo anterior

cmd ::= if exp then cmd restoCmd | outro restoCmd ::= else cmd |
16

Recurso Direita para Listas

Exemplo
listaComandos ::= comando listaComandos | comando comando ::= ID "=" expressao

Problemas com listaComandos

Conjuntos FIRST das produes idnticos: { ID } Decidir quando parar de escolher a recurso
17

Recurso Direita para Listas

Uma soluo seria usar a fatorao esquerda, explicada antes


listaComandos ::= comando restoListaCmds restoListaCmds ::= listaComandos | comando ::= ID "=" expressao

Mas tem outra soluo mais simples


18

Recurso Direita para Listas

A recurso anterior pode ser reescrita assim:


listaComandos ::= comando {comando}* comando ::= ID "=" expressao

Foi feita uma fatorao esquerda sem criao de um novo no-terminal Isso foi possvel com o operador regular *

Zero ou mais repeties

19

Recurso Direita para Listas

A parte do operador * pode ser resolvida fazendo um loop

Enquanto o token atual for elemento do FIRST de comando, faz o parsing de mais um comando

void parseListaComandos() { parseComando(); while (token.getType() == ID) { parseComando(); } }


20

Produo Vazia

Um tipo de produo que ainda no foi abordada a produo vazia Um exemplo apareceu quando falamos de fatorao esquerda

restoCmd

cmd ::= if exp then cmd restoCmd | outro restoCmd ::= else cmd |
21

Produo Vazia

Uma soluo simples criar um else com corpo vazio (no lanar erro), aps verificar que o token no casa com as outras produes
void parseRestoCmd() { if (token.getType() == ELSE) { ... } else { /* do nothing! */ } }
22

Produo Vazia

Um pequeno problema da abordagem anterior que erros sintticos no cdigo fonte s sero identificados depois

No mtodo que for chamado aps parseRestoCmd

Uma abordagem mais robusta para tratar a produo vazia consiste em testar se o token um dos tipos esperados depois do noterminal

23

Exemplo

Linguagem XPR-0*

Descrio

uma linguagem simples para reconhecer e calcular expresses matemticas de adio e multiplicao com operandos de apenas um dgito. Os programas desta verso so formados por um nico comando, onde um comando pode ser qualquer expresso terminada com ponto-e-vrgula. A semntica (significado) deste comando a avaliao da expresso seguida de sua impresso na sada padro Sintaxe abstrata Sintaxe concreta Implementacao

Definir

* Continuao do cdigo disponibilizado para o lexer manual

24

Exemplo

Sintaxe Abstrata
<program> ::= <command> <command> ::= <expr> ";" <expr> ::= | | | <expr> "+" <expr> <expr> "*" <expr> NUMERO "(" <expr> ")"

25

Exemplo

Sintaxe Concreta
<program> <command> <expr> <restExpr> ::= ::= ::= ::= | <term> ::= <restTerm> ::= | <factor> ::= | <command> <expr> ";" <term> <restExpr> "+" <term> <restExpr> <factor> <restTerm> "*" <factor> <restTerm> NUMERO "(" <expr> ")"
26

Bibliografia

AHO, A., LAM, M. S., SETHI, R., ULLMAN, J. D., Compiladores: princpios, tcnicas e ferramentas. Ed. Addison Wesley. 2a Edio, 2008 (Captulo 4)

27