31
Análise Léxica • Primeira fase de um compilador • Objetivo: ler os caracteres de entrada e produzir como saida uma seqüência de tokens que o parser vai usar para análise sintática.

Análise Léxica Primeira fase de um compilador Objetivo: ler os caracteres de entrada e produzir como saida uma seqüência de tokens que o parser vai usar

Embed Size (px)

Citation preview

Page 1: Análise Léxica Primeira fase de um compilador Objetivo: ler os caracteres de entrada e produzir como saida uma seqüência de tokens que o parser vai usar

Análise Léxica

• Primeira fase de um compilador

• Objetivo: ler os caracteres de entrada e produzir como saida uma seqüência de tokens que o parser vai usar para análise sintática.

Page 2: Análise Léxica Primeira fase de um compilador Objetivo: ler os caracteres de entrada e produzir como saida uma seqüência de tokens que o parser vai usar

Analisador léxico

Analisador léxicoAnalisador léxico parserparser

getNextToken

Programafonte

token

tabela de símbolostabela de símbolos

Page 3: Análise Léxica Primeira fase de um compilador Objetivo: ler os caracteres de entrada e produzir como saida uma seqüência de tokens que o parser vai usar

Construindo um analisador léxico

• Especificar tokens e lexemas da linguagem

• Implementar (ou gerar através de ferramenta) o analisador a partir da especificação

Page 4: Análise Léxica Primeira fase de um compilador Objetivo: ler os caracteres de entrada e produzir como saida uma seqüência de tokens que o parser vai usar

Outras possíveis tarefas do analisador léxico

• Tratamento de espaços em branco e comentários

• Tratamento de mensagens de erro (localização/impressão)

• Tratamento de macros

Page 5: Análise Léxica Primeira fase de um compilador Objetivo: ler os caracteres de entrada e produzir como saida uma seqüência de tokens que o parser vai usar

Organização

• Às vezes dividido em– scanning – remoção de comentários e espaços

em branco duplicados– Análise léxica propriamente dita – parte mais

complexa, onde o scanner produz a sequencia de tokens

Page 6: Análise Léxica Primeira fase de um compilador Objetivo: ler os caracteres de entrada e produzir como saida uma seqüência de tokens que o parser vai usar

Analisador léxico x Parser

• Design mais simples – misturar análise léxica com sintática torna o parser bem mais complicado

• Eficiência – separação possibilita construir processadores léxicos e sintáticos mais eficientes.

• Portabilidade – variações de dispositivos podem ficar restritas ao analisador léxico.

Page 7: Análise Léxica Primeira fase de um compilador Objetivo: ler os caracteres de entrada e produzir como saida uma seqüência de tokens que o parser vai usar

Tokens, Padrões e Lexemas

• Tokens: par com o nome do token e atributos opcionais.

• Padrão: descrição da forma dos lexemas que um token pode ter

• Lexema: sequencia de caracteres que casam com o padrão de um token. Uma instância de um token.

Page 8: Análise Léxica Primeira fase de um compilador Objetivo: ler os caracteres de entrada e produzir como saida uma seqüência de tokens que o parser vai usar

Tokens, padrões e lexemas

• Existem conjuntos de strings na entrada que geram o mesmo token.

• Elas são descritas por padrões associados ao token

• O padrão casa cada string do conjunto• Um lexema é uma seqüência de caracteres do

programa fonte que casa com um padrão de um token.

• Tokens são símbolos terminais da linguagem.

Page 9: Análise Léxica Primeira fase de um compilador Objetivo: ler os caracteres de entrada e produzir como saida uma seqüência de tokens que o parser vai usar

Tokens, padrões e lexemas

• Tokens normalmente são Palavras-chave, operadores, identificadores, constantes, strings literais e símbolos de pontuação, como parenteses e vírgulas.

• Padrões normalmente são especificados por expressões regulares.

• Variações de expressões regulares são usadas em vários outros contextos:– Linguagens de programação: sed, awk, perl– Shells de sistemas operacionais: sh, csh, command

Page 10: Análise Léxica Primeira fase de um compilador Objetivo: ler os caracteres de entrada e produzir como saida uma seqüência de tokens que o parser vai usar

Tokens, padrões e lexemastoken exemplo descrição

if if Caracteres i, f

else else Caracteres e, l, s, e

comp <,<=,=,<>,> < ou <= ou …

id pi, count, D2 Letra seguida de letras e/ou dígitos

num 3.1416, 0, 6.02E23 Constante numérica

literal “core dumped” Quaisquer caracteres entre “” exceto “ e ”

Page 11: Análise Léxica Primeira fase de um compilador Objetivo: ler os caracteres de entrada e produzir como saida uma seqüência de tokens que o parser vai usar

Dificuldades na implementação de um analisador léxico

• Linguagens que requerem determinados construtores em posições (colunas) específicas da linha de entrada (e.g. Fortran).

• Tratamento de espaços em branco.

• Ausência de palavras reservadas.

Page 12: Análise Léxica Primeira fase de um compilador Objetivo: ler os caracteres de entrada e produzir como saida uma seqüência de tokens que o parser vai usar

Dificuldades - Exemplos

• Fortran:DO 5 I = 1.25DO 5 I = 1,25IF (I,J) = 3

• PL/I:IF THEN THEN THEN = ELSE; ELSE ELSE = THEN;

Page 13: Análise Léxica Primeira fase de um compilador Objetivo: ler os caracteres de entrada e produzir como saida uma seqüência de tokens que o parser vai usar

Atributos de um token

• Ao reconhecer um token num é relevante saber se seu valor é zero ou um, por exemplo.

• Geralmente associado a um token existe um atributo.

• Uso da tabela de símbolos para guardar informações auxiliares sobre tokens.

Page 14: Análise Léxica Primeira fase de um compilador Objetivo: ler os caracteres de entrada e produzir como saida uma seqüência de tokens que o parser vai usar

Atributos de um token - Exemplo

• E = M * C ** 2• <id, apontador p/posição de E na tabela de símbolos>

<assign_op,><id, apontador p/posição de M na tabela de símbolos><mult_op,><id, apontador p/posição de C na tabela de símbolos><exp_op,><num, valor 2>

Page 15: Análise Léxica Primeira fase de um compilador Objetivo: ler os caracteres de entrada e produzir como saida uma seqüência de tokens que o parser vai usar

Erros de análise léxica

• Relativamente raros.

• Geralmente o analisador tenta recuperar do erro, ignorando caracteres.

Page 16: Análise Léxica Primeira fase de um compilador Objetivo: ler os caracteres de entrada e produzir como saida uma seqüência de tokens que o parser vai usar

Opções de Implementação de um analisador léxico

• Uso de um gerador de analisadores léxicos, como lex ou flex, que produzem um analisador léxico a partir de uma especificação em expressões regulares.

• Escrever o analisador em uma linguagem de programação convencional, usando as facilidades de E/S da linguagem para ler a entrada.

• Escrever o analisador léxico em assembler, gerenciando explicitamente a leitura.

• Uso de bufferização da entrada é importante para a eficiência de um analisador léxico!

Page 17: Análise Léxica Primeira fase de um compilador Objetivo: ler os caracteres de entrada e produzir como saida uma seqüência de tokens que o parser vai usar

Especificação de Tokens

• Baseado em Teoria de Linguagens:Alfabetos, strings e linguagens

• Operações sobre linguagens

• Exemplo: seja L o conjunto (de letras) {A,B,…,Z,a,b,…,z}e D o conjunto (de dígitos) {0,1,…,9}.

Page 18: Análise Léxica Primeira fase de um compilador Objetivo: ler os caracteres de entrada e produzir como saida uma seqüência de tokens que o parser vai usar

Operações sobre linguagens - Exemplo

• L D conjunto composto de letras e dígitos• LD conjunto de strings compostas de

letras seguidas de dígitos• L4 conjunto de todas as strings

com 4 letras• L* conjunto de todas as strings de letras,

inclusive a string vazia • D+ conjunto de strings de um ou mais dígitos.• L(L D)*

Page 19: Análise Léxica Primeira fase de um compilador Objetivo: ler os caracteres de entrada e produzir como saida uma seqüência de tokens que o parser vai usar

Operadores sobre linguagensOperação Definição

União de L e ML M

L M = {s | s L ou s M }

Concatenação de L e M,LM

{ st | s L e t M }

Fechamento de Kleene de L,L*

L* = i=0,Li

Fechamento positivo de L, L+ L+ = i=1,Li

Page 20: Análise Léxica Primeira fase de um compilador Objetivo: ler os caracteres de entrada e produzir como saida uma seqüência de tokens que o parser vai usar

Expressões regulares

• Permitem a definição de linguagens a partir de definições de expressões regulares mais simples.

• Exemplos:– Identificadores em pascal:letter (letter | digit) *

– a | b– (a | b) (a | b)– a*– (a|b)*– a | a*b

Page 21: Análise Léxica Primeira fase de um compilador Objetivo: ler os caracteres de entrada e produzir como saida uma seqüência de tokens que o parser vai usar

Propriedades algébricas

• | é comutativa e associativa

• Concatenação é associativa

• Concatenação distribui sobre | é o elemento identidade da concatenação

• * é idempotente (r** = r*)

Page 22: Análise Léxica Primeira fase de um compilador Objetivo: ler os caracteres de entrada e produzir como saida uma seqüência de tokens que o parser vai usar

Exemplo - Pascal

• letter A | B | … | Z | a | b | …| zdigit 0 | 1 | … | 9 id letter (letter | digit)*

• digits digit digit*opt_fraction . digits | opt_exponent (E (+|-|) digits) | num digits opt_fraction opt_exponent

Page 23: Análise Léxica Primeira fase de um compilador Objetivo: ler os caracteres de entrada e produzir como saida uma seqüência de tokens que o parser vai usar

Abreviações

• + uma ou mais instâncias.• ? Zero ou uma instância• [ ] classes de caracteres, ex: [A-Za-z][A-Za-z0-9]*

Page 24: Análise Léxica Primeira fase de um compilador Objetivo: ler os caracteres de entrada e produzir como saida uma seqüência de tokens que o parser vai usar

Reconhecimento de Tokens

• Gerar diagramas de transição e depois implementar uma máquina de estados.

• Implentar autômatos finitos determinísticos e não-determinísticos.

Page 25: Análise Léxica Primeira fase de um compilador Objetivo: ler os caracteres de entrada e produzir como saida uma seqüência de tokens que o parser vai usar

Lex

• Linguagem (e compilador) para especificar analisadores léxicos.

Page 26: Análise Léxica Primeira fase de um compilador Objetivo: ler os caracteres de entrada e produzir como saida uma seqüência de tokens que o parser vai usar

Organização

Compilador lex(lex ou flex)

Compilador lex(lex ou flex)

Programa fontelex.l Lex.yy.c

C compilerC compilerlex.yy.c a.out

a.outa.outEntrada Sequencia de tokens

Page 27: Análise Léxica Primeira fase de um compilador Objetivo: ler os caracteres de entrada e produzir como saida uma seqüência de tokens que o parser vai usar

Programas Lex - estrutura

Declarações – variáveis, constantes, defs.regulares%%regras de tradução – expr.regulares e ações em C

Padrão { Ação }%%procedimentos auxiliares

Page 28: Análise Léxica Primeira fase de um compilador Objetivo: ler os caracteres de entrada e produzir como saida uma seqüência de tokens que o parser vai usar

Lex - exemplo

%{ /* definição de constantes LT, LE, EQ, NE,…*/

%}delim [ \t\n]ws {delim}+letter [A-Za-z]digit [0-9]id {letter}({letter}|{digit})*number {digit}+(\.{digit}+)? (E[+\-]?{digit}+)?

%%…

Page 29: Análise Léxica Primeira fase de um compilador Objetivo: ler os caracteres de entrada e produzir como saida uma seqüência de tokens que o parser vai usar

Lex – exemplo (cont.)

…{ws} {/* no action and no return */}if {return(IF);}then {return(THEN);}else {return(ELSE);}{id} {yylval=install_id();return(ID);}{number} {yylval=install_num(); return(NUMBER);}

“<“ {yylval = LT; return(RELOP);}“<=“ {yylval = LE; return(RELOP);}%%…

Page 30: Análise Léxica Primeira fase de um compilador Objetivo: ler os caracteres de entrada e produzir como saida uma seqüência de tokens que o parser vai usar

Lex – exemplo (cont.)

…int install_id() { Copia lexema para a tabela de símbolos. Primeiro caracter do lexema é apontado pela variável yytext e o comprimento é definido pela variável yyleng.

}

Int install_num() { … }

Page 31: Análise Léxica Primeira fase de um compilador Objetivo: ler os caracteres de entrada e produzir como saida uma seqüência de tokens que o parser vai usar

Lex - implementação

• Transforma o programa de entrada em um programa em C que implementa um Autômato Finito

• NFA – Nodeterministic Finite Automata• DFA – Deterministic Finite Automata

• Reconhecem a mesma linguagem, linguagens regulares, expressas por expressões regulares