análise léxica e sintática

41
Luiz Carlos d´Oleron – [email protected] Análise Léxica e Sintática Teoria e Implementação de Linguagens Computacionais - IF688 – 2007.1

Upload: dusan

Post on 12-Jan-2016

45 views

Category:

Documents


4 download

DESCRIPTION

Análise Léxica e Sintática. Teoria e Implementação de Linguagens Computacionais - IF688 – 2007.1. Fases da compilação Analise Lexica Tokens, lexemas, expressões regulares e autômatos finitos Analise Sintática Gramáticas e parsers Parser trees Derivações Gramáticas ambíguas. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Análise Léxica e SintáticaTeoria e Implementação de Linguagens Computacionais - IF688 – 2007.1

Page 2: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Roteiro Fases da

compilação Analise Lexica Tokens, lexemas,

expressões regulares e autômatos finitos

Analise Sintática Gramáticas e

parsers Parser trees Derivações Gramáticas

ambíguas

Ambigüidade aritméticas

Parser recursive descendent

Recursão à esquerda Gramáticas LL(k) Gramáticas LR(k) Outras gramáticas Dangling else Parsing LR de

gramáticas ambíguas

AST Referências

Page 3: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Atenção!

Este material não substitui a leitura da bibliografia

Sugerimos pesquisar a leitura referenciada no final deste trabalho e no site da disciplina

Page 4: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Processo de Compilação

beginif x = 5 then... 1100111

0011100011

Código Fonte Compilador Programa

output+ params

Page 5: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Fases da compilaçãoab

stra

ção

implem

entação

Código fonte

tokens e lexemas

Árvoresintáticaabstrata

CódigoMáquina

AST decorada

Análise Léxica

Análise SintáticaAnálise Semântica

Geração de Código

Page 6: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Background Acadêmico - CIn

Page 7: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Análise Léxica

O analisador léxico é responsável por traduzir o arquivo fonte em lexemas e tokens

if (n == 0) { return 1;} else { ...} RPAR LCUR

RCUR

if LPAR

return

else

"n"id

"0"intLit

assign

"1"intLit ...comm

Page 8: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Reconhecendo tokens

Expressões regulares (implementadas como Autômatos Finitos) são comumente utilizadas

Exemplos:

if IF

[a-z][a-z0-9]* ID

[0-9]+ NUM

Page 9: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Reconhecendo tokens

1 2

a-z a-z

0-9

ID

21 3

i f

IF

Page 10: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Análise Sintática

“syn-tax: the way in wich words are put together to form phrases, clauses or setences.”

Webster´s Dictionary

A seguinte construção é válida?

int y = 0,k = 0;int x = y+++k;

Page 11: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Análise Sintática

O Analisador Sintático é responsável

por verificar quando uma sentença faz parte da gramática da linguagem.

Entrada: lexemas e tokens gerados pelo analisador léxico

Page 12: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Gramáticas – descrevendo linguagens Gramáticas livres de contexto

são utilizadas para descrever linguagens de programação

Produções Símbolos terminais Símbolos não-terminais Símbolo inicial

Page 13: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Exemplo

S → S ; SS → id := ES → print (L)E → idE → numE → E + EE → (S , E)L → EL → L , E

Terminais: id print , + ; := ( ) Não terminas: S E L Símbolo inicial: S → é utilizado na notação de

produções

A cadeia seguinte pertence à gramática?

a := 7;

b := c + (d := 5 + 6, d)

Page 14: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Derivações Para determinar se uma cadeia pertence à

gramática pode ser utilizado o processo de Derivação:

SS ; SS ; id := Eid := E ; id := Eid := num ; id := Eid := num ; id := E + Eid := num ; id := E + (S, E)id := num ; id := id + (S, E)id := num ; id := id + (id := E, E)id := num ; id := id + (id := E + E, E)id := num ; id := id + (id := E + E, id)id := num ; id := id + (id := num + E, id)id := num ; id := id + (id := num + num, id)

Page 15: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Parse treeS

SS

E

Eid :=;

E:=id

id

+ E

)( , ES

Eid :=id

EE +

num num

num

A Parse Tree é construída conectando cada derivação a sua origem.

Na prática não é implementada pelos compiladores.

Page 16: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Gramáticas ambíguas Uma gramática é ambígua se a partir

dela uma sentença pode dar origem a duas arvores de parsing diferentes

Indeterminismo é problemático para a compilação

Eliminação de ambigüidade é quase sempre possível

Refatoração da gramática

Page 17: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Gramáticas ambíguas

x := 1 + 2 + 3;

S

Eid :=

E + E

E + E num

num num

S

Eid :=

E + E

E + Enum

num num

Page 18: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Gramática refatorada

S → S ; SS → id := ES → print (L)E → idE → numE → E + EE → (S , E)L → EL → L , E

S → S ; SS → id := ES → print (L)E → idE → numE → E + TE → TE → (S , E)L → EL → L , E

Page 19: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Parsers

Utilizados para avaliar uma entrada quanto à sintaxe

Podem ser Top-down

Recursive-descent / LL(k)

Bottom-up

SRL, LR(k)

Page 20: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Parser Recursive descent Algoritmo baseado em previsões Também conhecido como Predictive

Parsing Funções mutuamente recursivas Simples implementação Uma função para cada não-terminal Uma cláusula para cada produção Verifica o primeiro símbolo terminal

para decidir qual função usar

Page 21: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Parser Recursive descent

Desenvolvendo um recursive descent parser

Cada não terminal 'X' dará origem a um método/função parseX();

Produções do tipo 'A | B' darão origem a cláusulas cases

Page 22: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Parser Recursive descent

A ::= aBcC

B ::= CB | cC

C ::= da

parseA() { accept(‘a’); parseB(); accept(‘c’); parseC();}

parseB() { case (d): parseC(); parseB(); case (c): accept(‘c’); parseC();}

parseC() { accept(‘d’); accept(‘a’); }

Page 23: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Recursive descent

Na prática constrói uma tabela de produções indexadas por não-terminais e terminais

A ::= aBcC

B ::= CB | CA

C ::= da

a c d

A A::= aBcC

B B::= CBB::= CA

C C::= da

Page 24: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Recursive descent

Vantagens Fácil de implementar Fácil de entender

Desvantagens Performance deficiente Gramática reconhecida possui

restrições Sem recursão à esquerda Deve estar fatorada

Page 25: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Recursive descent

A ::= aBcC

B ::= CB | CA

C ::= da

A ::= aBcC

B ::= CX

X ::= B | A

C ::= da

a c d

A A::= aBcC

B B::= CX

C C::= da

X X::=A X::=B

GramáticaLL(1)

Page 26: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Gramáticas e Parsers LL(1) Gramáticas SEM entradas duplicadas na

tabela são conhecidas como LL(1) LL(1) - Left-to-right, leftmost-

derivation, 1-symbol lookahead Left-to-right – direção na qual os símbolos

serão examinados Leftmost-derivation – ordem pela qual os

símbolos não-terminais serão expandidos 1-symbol lookahead– não mais que um

símbolo será avaliado por vez Existem LL(2), LL(3),... Toda LL(1) é LL(2), toda LL(2) é LL(3),...

LL(k)

Page 27: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

LL(1) na prática - Applet

http://ag-kastens.uni-paderborn.de/lehre/material/uebi/parsdemo/LL1Parser.html

Page 28: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Recursão à esquerda

Gramáticas LL(1) são vulneráveis às entradas duplicadas. Por exemplo, o fragmento a seguir:

E → E + TE → T

O fato de E aparecer no início do lado direito da produção é a causa do problema. Isso é conhecido como Recursão à Esquerda. Para corrigir isso, vamos refatorar a gramática, com Recursão à Direita:

E → T E´E´ → +T E´ E´ →

Page 29: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Gramáticas e Parsers LR(1) As fraquezas de LL(k) são superadas

pela técnica LR(k) LR(1) - Left-to-right, rightmost-

derivation, 1-symbol lookahead Uso de uma pilha para armazenar

símbolos de forma temporária Possui duas operações, shift e reduce shift: Move o primeiro símbolo para o

topo da pilha reduce: escolhe uma regra da

gramática do tipo X→A B C. push X da pilha e pop C B A.

Page 30: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Outros Parsers LR LR(0)

Olham apenas para a pilha SLR

Melhoramento sobre o LR(0) LR(1)

Lookahead de 1 símbolo Consegue descrever a maioria das

linguagens de programação LALR(1)

Melhoramento sobre o LR(1) Diminuí o tamanho da tabela de parsing

Page 31: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

shift-reduce na prática - Applet

http://ag-kastens.uni-paderborn.de/lehre/material/uebi/parsdemo/SRParser.html

Page 32: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Parsing LR de Gramáticas Ambíguas Gramáticas ambíguas ocasionam

conflitos em parsers LR Shift-reduce conflict

O parser não consegue decidir se empilha o próximo símbolo da entrada, ou se reduz para uma regra já disponível

Reduce-reduce conflict O parser pode realizar uma redução

para duas regras distintas

Page 33: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Parsing LR de Gramáticas Ambíguas Caso clássico: dangling-else

S ::= 'if' E 'then' S 'else' SS ::= 'if' E 'then' SS ::= ...

Page 34: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Parsing LR de Gramáticas Ambíguas

if a then if b then s1 else s2

if a then { if b then s1 else s2 }

if a then { if b then s1 } else s2

?

Page 35: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Parsing LR de Gramáticas Ambíguas Solução:

Transformar a gramática Introdução dos conceitos de matched e

unmatched

S ::= 'if' E 'then' S 'else' SS ::= 'if' E 'then' SS ::= ...

S ::= M | U

M ::= 'if' E 'then' M 'else' M | ...

U ::= 'if' E 'then' S | 'if' E 'then' M 'else' U

Page 36: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

LR(0)LL(0)

SLR

LALR(1)

LL(k)

LL(1)

Gramáticas não-ambíguas Gramáticas ambíguas

LR(1)

LR(k)

Page 37: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Sintaxe abstrata Apenas reconhecer se uma sentença

pertence ou não a linguagem especificada por uma gramática não é o suficiente

É necessário produzir uma estrutura que sirva de base para a próxima fase do processo de compilação Parse trees nunca são montadas na

prática

Page 38: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

AST – Abstract Syntax Tree Capturam a essência da estrutura de

uma gramática abstraindo não-terminais

Representação possível Java: Classes que possam se relacionar

a fim de montar uma árvore

Pode ser produzida através da inserção de ações semânticas no parser

Page 39: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

AST – Abstract Syntax Tree

IfThenElse ::= 'if' expr 'then' comm1 'else' comm2

return new IfThenElse(expr, comm1, comm2);

IfThenElse

expr : Expressioncomm1 : Commandcomm2 : Command

Page 40: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Page 41: Análise Léxica e Sintática

Luiz Carlos d´Oleron – [email protected]

Referências

Análises léxica e sintática, Mauro La-Salette C. L. de Araújo

Modern Compiler implementation in Java, Andrew W. Appel