Post on 19-Apr-2015
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ção
Os 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 f
IF
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ção
Algoritmos de parsing e gramáticas
Classificação
Top-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
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
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
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
GramáticaLL(1)
Gramáticas LL(1)
Left-to-right parse Leftmost-derivation 1-symbol-lookahead
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 ')'
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);
IfThenElse
expr : 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