Análises léxica e sintática

Post on 18-Mar-2016

44 views 0 download

description

Análises léxica e sintática. Teoria e Implementação de Linguagens Computacionais - IF688 Mauro La-Salette C. L. de Araújo Centro de Informática – CIn Universidade Federal de Pernambuco – UFPE mscla@cin.ufpe.br. Roteiro. Visão geral Análise léxica Definição Especificação Implementação - PowerPoint PPT Presentation

Transcript of Análises léxica e sintática

Análises léxica e sintática Teoria e Implementação de Linguagens

Computacionais - IF688

Mauro La-Salette C. L. de AraújoCentro de Informática – CIn

Universidade Federal de Pernambuco – UFPE

mscla@cin.ufpe.br

Roteiro Visão geral Análise léxica

Definição Especificação Implementação Correspondência

Análise sintática Definição Especificação Implementação

Algoritmos de parsing e gramáticas Gramáticas ambíguas Sintaxe abstrata

executável

Visão Geral

Análise sintática

Código fonte

AST

Análise semântica

Geração decódigo

AST decorada

Análiseléxica

Tokens

Análise Léxica

Definição Fase da compilação responsável por

extrair os tokens do código fonte de um programa.

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

RCUR

if LPAR

return

else

"n"id

"0"intLit

assign

"1"intLit ...comm

EspecificaçãoOs tokens de uma linguagem

comumente são especificados através de Expressões Regulares

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

[0-9]+ intLiteral

Implementação Autômatos finitos

1 2

a-z a-z

0-9

ID

21 3

i fIF

Análise Sintática

Definição Fase da compilação responsável por

determinar se uma dada cadeia de entrada pertence ou não à linguagem definida por uma gramática

Tem como entrada os tokens processados pela análise léxica

Produz uma estrutura comumente denominada AST – abstract syntax tree

Especificação

BNF - Backus-Naur form S, A, B, C, D : não-terminais

a,b,d: terminais

S ::= A | BA ::= C | DB ::= bbaC ::= abD ::= dab

Produções

ImplementaçãoAlgoritmos de parsing e gramáticas

ClassificaçãoTop-down

• Recursive-descent / LL(1)

Bottom-up

• LR, SLR, LALR, LR(k)

Recursive descent

Algoritmo baseado em previsões

Funções mutuamente recursivas

Uma função para cada não-terminal

Uma cláusula para cada produção

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

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’); }

Recursive descent Na prática constrói uma tabela de

produções indexadas por não-terminais e terminais

A ::= aBcC

B ::= CB | cC

C ::= da

a c d

A A::= aBcC

B B::= cC B::= CB

C C::= da

Recursive descent

A ::= aBcC

B ::= CB | CA

C ::= da

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

parseB() { case (d): parseC(); parseB(); case (d): parseC(); parseA();}

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

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::= aBC

B B::= CBB::= CA

C C::= da

Recursive descent

Vantagens Fácil de implementar

Desvantagens Performance Gramática reconhecida possui restrições

Sem recursão à esquerdaDeve estar fatorada ...

Recursive descent

A ::= aBC

B ::= CB | CA

C ::= da

A ::= aBC

B ::= CX

X ::= B | A

C ::= da

a c dA A::= aBCB B::= CXC C::= daX X::=A X::=B

GramáticaLL(1)

Gramáticas LL(1)

Left-to-right parse Leftmost-derivation 1-symbol-lookahead

Algoritmos bottom-up

Algoritmos LL(k) precisam decidir que produção usar tendo visto apenas k tokens da entrada

Algoritmos bottom-up são baseados em técnicas LR(k) Left-to-right parse, Right-most derivation,

k-symbol-lookahead

Algoritmos bottom-up

Baseados no conceito de autômato a pilha Pilha + lookahead Duas tipos de ações

Shift: • Coloca o primeiro token da entrada no topo da

pilhaReduce:

• Escolhe a regra X::= A B C • Retira C, B, A da pilha• Coloca X na pilha

Gramáticas 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

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

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

Problemáticas para a compilação

Eliminação de ambigüidade é quase sempre possível Transformações na gramática

Gramáticas Ambíguas Caso clássico: gramática para expressões

aritméticas

E ::= intLiteral | E '*' E | E '/' E | E '+' E | E '-' E |'(' E ')'

Gramáticas Ambíguas

1 + 2 * 3

E

E E

E E

*

+ 3

21

E

E E

EE

+

*1

2 3

Gramáticas Ambíguas Solução:

Transformar a gramática * e / com maior precedência que + ou - Operadores associativos a esquerda

E ::= intLiteral | E '*' E | E '/' E | E '+' E | E '-' E |'(' E ')'

E ::= E '+' T | E '–' T | TT ::= T '*' F | T '/' F | FF ::= intLiteral |'(' E ')'

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 conflictO parser pode realizar uma redução para duas

regras distintas

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

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

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

?

Parsing LR de Gramáticas Ambíguas

if a then if b then s1 else s2Input:

Stack:

if a then if b then s1

reduce St ?shift else ?

St

Optando pelo reduce...

else s2

Parsing LR de Gramáticas Ambíguas

if a then if b then s1 else s2Input:

Stack:

if a then if b then s1

reduce St ?shift else ?

else s2

Optando pelo shift...

St

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

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)

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

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

AST – Abstract Syntax Tree

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

return new IfThenElse(expr, comm1, comm2);

IfThenElseexpr : Expressioncomm1 : Commandcomm2 : Command

Análises léxica e sintática Teoria e Implementação de Linguagens

Computacionais - IF688

Mauro La-Salette C. L. de AraújoCentro de Informática – CIn

Universidade Federal de Pernambuco – UFPE

mscla@cin.ufpe.br