Compiladores 04 - sistemas.riopomba.ifsudestemg.edu.br · Ou seja, o programa serve para ler um...

Post on 15-May-2018

219 views 2 download

Transcript of Compiladores 04 - sistemas.riopomba.ifsudestemg.edu.br · Ou seja, o programa serve para ler um...

Prof José Rui

Compiladores 04Analise léxica

Jflex

Prof José Rui

Sumário

● Análise Léxica

– Definição: Lexema, tokens

– Tabela símbolos

– Expressões regulares, automatos

– JFlex

Prof José Rui

Análise léxica

● Exemplo

– Soma = a + b * 40;<IDENT, 1>, <OP_IGUAL>, <IDENT, 3>, <OP_SOMA>, <IDENT, 5>, <OP_MULT>,<NUM, valor 40>

Tabela de simbolos

Lexema (lido) token valor

1 soma <IDENT> -

2 = <OP_IGUAL> -

3 a <IDENT> -

4 + <OP_SOMA> -

5 b <IDENT> -

6 * <OP_MULT> -

7 40 <NUM> 40

Analisadorléxico

Prof José Rui

Análise léxica

● A partir dai o compilador une os caracteres de acordo com os tokens da linguagem

● Os tokens são definidos por meio de expressões regulares

int gcd (int a, int b){while(a != b){

if(a > b)a ­= b;

elseb ­= a;

}return a;

}

i n t sp g c d sp ( i n t sp a sp , sp i n t sp b ) { nl w h i l e (a ! = b ) nl { i f sp ( a > b ) nla ­ = b ; nl e l s e nl b ­ = a ; nl } nlr e t u r n sp a ; nl }

Prof José Rui

Análise léxica

● Para fazer o reconhecimento do token o analisador lexico utiliza autômato finito

– letra → [A – Z] [a – z]

– digito → [0 – 9]

– digitos → digito digito*

– ident → letra (letra | digito)*

Prof José Rui

Análise léxica

● Note que:

– O AL ignora os espaços em branco

– Além de espaços ele ignora comentários, newLine...

– Fica apenas os tokens

int gcd (int a, int b){while(a != b){

if(a > b)a ­= b;

elseb ­= a;

}return a;

}

Prof José Rui

Análise Sintática

● Só para se ter uma idéia da análise sintática

– Cria-se uma arvore com os tokens

– Formalismo BNF

int gcd (int a, int b){while(a != b){

if(a > b)a ­= b;

elseb ­= a;

}return a;

}

Prof José Rui

Análise léxica

● Diagrama scanner-parser:

Analisador léxico(Scanner)

Analisador sintático(Parser)

getNextToken()

Programafonte

token

Tabela de símbolos(identificadores e

constantes)

semântico

Prof José Rui

Análise léxica

● Diagrama scanner-parser:

● Jflex e Jcup

Lex

AnalisadorLéxico

regrasléxicas

entrada

AnalisadorSintático

saída

Expressões regulares

Geradores automáticosJflex e jcup

Classes geradas

Prof José Rui

Gerador de analisador léxico - JFLEX

● Ajuda escrever programas cuja entrada é descrita por meio de expressões regulares

Prof José Rui

Gerador de analisador léxico - JFLEX

● Ajuda escrever programas cuja entrada é descrita por meio de expressões regulares

● Principais utilizações

– Transformações simples;

– Extração de padrões em textos;

– Separação da entrada em unidades léxicas; (preparando para o analisador sintático)

Prof José Rui

Gerador de analisador léxico - JFLEX

● Ajuda escrever programas cuja entrada é descrita por meio de expressões regulares

● Principais utilizações

– Transformações simples;

– Extração de padrões em textos;

– Separação da entrada em unidades léxicas; (preparando para o analisador sintático)

● Um texto fonte para LEX é composto de:

– Lista de expressões regulares

– Fragmentos de programas associados a cada expressão

Prof José Rui

JFLEX – Esquema de funcionamento

LexFonte(Expressões regulares)

Prof José Rui

JFLEX – Esquema de funcionamento

● Quando o fonte é submetido ao LEX, um programa yylex é gerado

LexFonte(Expressões regulares)

Yylex(programa gerado)

Prof José Rui

JFLEX – Esquema de funcionamento

● Quando o fonte é submetido ao LEX, um programa yylex é gerado

● Esse programa Yylex:

– Lê um arquivo de entrada

Lex

Yylex

Fonte(Expressões regulares)

Yylex(programa gerado)

entrada

Prof José Rui

JFLEX – Esquema de funcionamento

● Quando o fonte é submetido ao LEX, um programa yylex é gerado

● Esse programa Yylex:

– Lê um arquivo de entrada

– Particiona a entrada em cadeias que “casam” com as expressões regulares definidas → Tokens

– Executa executa os fragmentos de programa associados às expressões “casadas”

Lex

Yylex

Fonte(Expressões regulares)

Yylex(programa gerado)

entrada

Prof José Rui

JFLEX – Esquema de funcionamento

● Quando o fonte é submetido ao LEX, um programa yylex é gerado

● Esse programa Yylex:

– Lê um arquivo de entrada

– Particiona a entrada em cadeias que “casam” com as expressões regulares definidas → Tokens

– Executa executa os fragmentos de programa associados às expressões “casadas”

– Escreve no arquivo de saída

Lex

Yylex

Fonte(Expressões regulares)

Yylex(programa gerado)

entrada saída

Prof José Rui

Lex – exemplo com Jflex

● Exemplo 1

● Os arquivos LEX são divididos em 3 seções, separadas por %%

● No jflex as seções são:

1. Código do usuário a ser incluído

2. Opções e declarações

3. Regras e ações associadas

%%

%standalone

%%

\t { System.out.print(“TAB”); }

ex1.lex1

2

3

Prof José Rui

Lex – exemplo com Jflex

● Exemplo 1

%%

%standalone

%%

\t { System.out.print(“TAB”); }

Essa opção indica que o programa gerado poderá serexecutado diretamente (não será usado dentro de um analisador sintático).

Essa opção indica que o programa gerado poderá serexecutado diretamente (não será usado dentro de um analisador sintático).

ex1.lex

Prof José Rui

Lex – exemplo com Jflex

● Exemplo 1

%%

%standalone

%%

\t { System.out.print(“TAB”); }

Uma regraUma regra

ex1.lex

Prof José Rui

Lex – exemplo com Jflex

● Exemplo 1

%%

%standalone

%%

\t { System.out.print(“TAB”); }

Expressão regularExpressão regular

ex1.lex

Prof José Rui

Lex – exemplo com Jflex

● Exemplo 1

%%

%standalone

%%

\t { System.out.print(“TAB”); }

Ação (fragmento de programa) associada a expressão

Ação (fragmento de programa) associada a expressão

ex1.lex

Prof José Rui

Lex – exemplo com Jflex

● Exemplo 1

● Esta regra “casa” com o caractere “\t” (tabulação)

● Se isso ocorrer, o código entre chaves é executado

● Senão o default é escrever o próprio caractere na saída

● Ou seja, o programa serve para ler um arquivo de entrada e trocar o caractere “\t” pela palavra TAB

%%

%standalone

%%

\t { System.out.print(“TAB”); }

ex1.lex

Prof José Rui

Lex – usando o Jflex

● Exemplo 1

%%

%standalone

%%

\t { System.out.print(“TAB”); }

ex1.lex

> jflex ex1.flex     

Comando jflex para construir o analisador léxico

Comando jflex para construir o analisador léxico

Prof José Rui

Lex – usando o Jflex

● Exemplo 1

%%

%standalone

%%

\t { System.out.print(“TAB”); }

ex1.lex

> jflex ex1.flexReading "ex1.flex"Constructing NFA : 6 states in NFAConverting NFA to DFA : ..4 states before minimization, 3 states in minimized DFAWriting code to "Yylex.java"

Prof José Rui

Lex – usando o Jflex

● Exemplo 1

%%

%standalone

%%

\t { System.out.print(“TAB”); }

ex1.lex

> jflex ex1.flexReading "ex1.flex"Constructing NFA : 6 states in NFAConverting NFA to DFA : ..4 states before minimization, 3 states in minimized DFAWriting code to "Yylex.java"

Note que ele constrói um AFNdepois o converte em AFDe por fim o minimiza

Note que ele constrói um AFNdepois o converte em AFDe por fim o minimiza

Prof José Rui

Lex – usando o Jflex

● Exemplo 1

%%

%standalone

%%

\t { System.out.print(“TAB”); }

ex1.lex

> jflex ex1.flexReading "ex1.flex"Constructing NFA : 6 states in NFAConverting NFA to DFA : ..4 states before minimization, 3 states in minimized DFAWriting code to "Yylex.java"

Ele gerou pra você o código em Java. Agora é só compilá-lo

Ele gerou pra você o código em Java. Agora é só compilá-lo

Prof José Rui

Lex – usando o Jflex

● Exemplo 1

%%

%standalone

%%

\t { System.out.print(“TAB”); }

ex1.lex

> jflex ex1.flexReading "ex1.flex"Constructing NFA : 6 states in NFAConverting NFA to DFA : ..4 states before minimization, 3 states in minimized DFAWriting code to "Yylex.java"

> javac Yylex.java

Comando de compilação JAVA

javac nomearquivo.java

Comando de compilação JAVA

javac nomearquivo.java

Prof José Rui

Lex – usando o Jflex

● Exemplo 1

%%

%standalone

%%

\t { System.out.print(“TAB”); }

ex1.lex

> jflex ex1.flexReading "ex1.flex"Constructing NFA : 6 states in NFAConverting NFA to DFA : ..4 states before minimization, 3 states in minimized DFAWriting code to "Yylex.java"

> javac Yylex.java>

Pronto!

● Gerou o Yylex.class

● Agora é só executá-lo

Pronto!

● Gerou o Yylex.class

● Agora é só executá-lo

Prof José Rui

Lex – executando o analisador gerado

● Exemplo 1

● Suponha o arquivo de entrada chamado teste.txt

Bla bla bla...Esta linha inicia com tabulação

Esta com duas tabulações

teste.txt

Prof José Rui

Lex – executando o analisador gerado

● Exemplo 1

● Suponha o arquivo de entrada chamado teste.txt

Bla bla bla...Esta linha inicia com tabulação

Esta com duas tabulações

teste.txt

Voce pode ate não está vendo, mas aqui

tem uma tabulação

Voce pode ate não está vendo, mas aqui

tem uma tabulação

Prof José Rui

Lex – executando o analisador gerado

● Exemplo 1

● Suponha o arquivo de entrada chamado teste.txt

Bla bla bla...Esta linha inicia com tabulação

Esta com duas tabulações

teste.txt

> java Yylex teste.txt

Ao executar o Yylex passando o arquivo teste.txtcomo parâmetro

Ao executar o Yylex passando o arquivo teste.txtcomo parâmetro

Prof José Rui

Lex – executando o analisador gerado

● Exemplo 1

● Suponha o arquivo de entrada chamado teste.txt

Bla bla bla...Esta linha inicia com tabulação

Esta com duas tabulações

teste.txt

> java Yylex teste.txt

Bla bla blaTABEsta linha inicia com tabulaçãoTABTABEsta com duas tabulações

Temos como saídaTemos como saída

Prof José Rui

Lex – executando o analisador gerado

● Exemplo 1

● Suponha o arquivo de entrada chamado teste.txt

● Se quisermos jogar a saida para uma arquivo

Bla bla bla...Esta linha inicia com tabulação

Esta com duas tabulações

teste.txt

> java Yylex teste.txt

Bla bla blaTABEsta linha inicia com tabulaçãoTABTABEsta com duas tabulações

Temos como saídaTemos como saída

> java Yylex teste.txt > saida.txt

Prof José Rui

Lex – Expressões regulares

● Basicamente:

– Caraceteres de texto: ● letras, dígitos, caracteres especiais como '\t','\n'...

– Operadores: ● Usados como funções especiais das expressões regulares

● Na maioria das versões LEX:

● " \ [ ] ˆ - ? . * + | ( ) $ / { } % < >

– Atenção: ● Nada impede de utilizar os operadores como caracteres, desde que venham

precedidos de espace('\')

● Ou se estiverem entre aspas duplas

Prof José Rui

Lex – Expressões regulares

^ → caracter que o segue inicia o elemento

$ → caracter que o antecede finaliza o elemento

. → caracter é um símbolo qualquer (exceto nova linha)

| → enumerador de alternativas

( ) → agrupador

[ ] → especificificador de classes

* → caracter ocorre 0 ou mais vezes

+ → caracter ocorre 1 ou mais vezes

? → caracter ocorre 1 ou 0 vezes

{n} → caracter ocorre exatamente "n" vezes

{n,} → caracter ocorre pelo menos "n" vezes

{n,m} → caracter ocorre pelo menos "n" vezes e não mais que "m" vezes

Prof José Rui

Lex – Expressões regulares● Especificador de classes

[abc] casa com um dos caracteres a, b ou c

[a-zA-Z]casa com letras maiúsculas ou minúsculas

[^a-zA-Z] casa com qualquer coisa, exceto letras

● ^ na expressao regular

^ab* inicia com a

● ^ na classe

[^a-zA-Z] nega o que tem dentro da classe

● $ , o que antecede finaliza a palavra

(1|0)*(000)$ casa com tudo que finaliza com 000

Prof José Rui

Lex – Expressões regulares

● Expressão opcional (? corresponde a uma ou zero ocorrências ao que vem, antes)

ab?c casa ac ou abc (b pode ocorrer uma ou zero vezes)

(ab|cd+)?(ef)* casa com abef, abefef, efefef, cddddd

● Macros

{digito} casa com a definição da expressão regular digito definido previamente

● Repetição

a{n} casa com n vezes a concatenação de a

Prof José Rui

Lex - Precedência

● Forma de escolha das regras para casamento

1. À medida que a entrada é lida, o analisador procura a regra que possui a cadeia mais longa

2. Se mais de uma regra possibilita o casamento com a seqüência mais longa, a escolha é feita pela ordem em que as regras aparecem na fonte

Prof José Rui

Lex – Relembrando

● Seções

● Os arquivos LEX são divididos em 3 seções, separadas por %%

● No jflex as seções são:

1. Código do usuário a ser incluído

2. Opções e declarações

3. Regras e ações associadas

%%

%standalone

%%

\t { System.out.print(“TAB”); }

ex1.lex1

2

3

Prof José Rui

Lex – Precedência

● Exemplo 2

● Ao encontrar “abcd”, o compilador vai casar com “abc” ou com “ident”?

%%

% standaloneIdent = [a-zA-Z][a-zA-Z0-9]*

%%abc { System.out.println("-----\"abc\""); }{Ident} { System.out.println("-----id"); }

ex2.lex

Prof José Rui

Lex – Precedência

● Exemplo 2

● Ao encontrar “abcd”, o compilador vai casar com “abc” ou com “ident”?

%%

% standaloneDigito = [0-9]Letra = [a-zA-Z]Ident = {Letra} ({Letra} | {Digito})*

%%abc { System.out.println("-----\"abc\""); }{Ident} { System.out.println("-----id"); }

ex2.lex

Observação

● Crie Macros!

● Fica mais organizado!

Observação

● Crie Macros!

● Fica mais organizado!

Prof José Rui

Lex – Precedência

● Exemplo 2

● Ao encontrar “abcd”, o compilador vai casar com “abc” ou com “ident”?

R: Vai casar com “ident”. É a maior!

%%

% standaloneDigito = [0-9]Letra = [a-zA-Z]Ident = {Letra} ({Letra} | {Digito})*

%%abc { System.out.println("-----\"abc\""); }{Ident} { System.out.println("-----id"); }

ex2.lex

Prof José Rui

Lex – Precedência

● Exemplo 2

● Ao encontrar “abcd”, o compilador vai casar com “abc” ou com “ident”?

R: Vai casar com “ident”. É a maior!

%%

% standaloneDigito = [0-9]Letra = [a-zA-Z]Ident = {Letra} ({Letra} | {Digito})*

%%abc { System.out.println("-----\"abc\""); }{Ident} { System.out.println("-----id"); }

ex2.lex

Vamos conferir!Vamos conferir!

Prof José Rui

Lex – Precedência

● Exemplo 2%%

% standaloneDigito = [0-9]Letra = [a-zA-Z]Ident = {Letra} ({Letra} | {Digito})*

%%abc { System.out.println("-----\"abc\""); }{Ident} { System.out.println("-----id"); }

ex2.lex

> jflex ex2.flex 

Comando jflex para construir o analisador léxico Yylex.java

Comando jflex para construir o analisador léxico Yylex.java

Vamos conferir!Vamos conferir!

Prof José Rui

Lex – Precedência

● Exemplo 2%%

% standaloneDigito = [0-9]Letra = [a-zA-Z]Ident = {Letra} ({Letra} | {Digito})*

%%abc { System.out.println("-----\"abc\""); }{Ident} { System.out.println("-----id"); }

ex2.lex

> jflex ex2.flexReading "ex2.flex"Constructing NFA : 16 states in NFAConverting NFA to DFA : ......8 states before minimization, 6 states in minimized DFAWriting code to "Yylex.java"

Comando jflex para construir o analisador léxico Yylex.java

Comando jflex para construir o analisador léxico Yylex.java

Prof José Rui

Lex – Precedência

● Exemplo 2%%

% standaloneDigito = [0-9]Letra = [a-zA-Z]Ident = {Letra} ({Letra} | {Digito})*

%%abc { System.out.println("-----\"abc\""); }{Ident} { System.out.println("-----id"); }

ex2.lex

> jflex ex2.flexReading "ex2.flex"Constructing NFA : 16 states in NFAConverting NFA to DFA : ......8 states before minimization, 6 states in minimized DFAWriting code to "Yylex.java"

> javac Yylex.java● Agora basta compilá-lo e

usar● Este comando gera o

Yylex.class

● Agora basta compilá-lo eusar

● Este comando gera o Yylex.class

Prof José Rui

Lex – executando o analisador gerado

● Exemplo 2

● Suponha o arquivo de entrada chamado teste.txt

● O que será impresso?

abcdeabcabc123123abcd123abc

teste.txt

> java Yylex teste.txt

Prof José Rui

Lex – executando o analisador gerado

● Exemplo 2

● Suponha o arquivo de entrada chamado teste.txt

● O que será impresso?

abcdeabcabc123123abcd123abc

teste.txt

> java Yylex teste.txt­­­­­id

­­­­­abc

­­­­­id

123­­­­­id

123­­­­­abc

Prof José Rui

JFlex

● Exercício:

– Faça o exemplo anterior no computador

● Orientações para instalação e configuração

– Linux

● http://www.skenz.it/compilers/installLinux.html

– Windows

● http://www.skenz.it/compilers/installWindows.html

Prof José Rui

Análise léxica

Exercícios

● Seja as seguintes linguagens abaixo. Construa o autômato(caso necessário) e depois crie a EXPRESSÃO REGULAR de cada linguagem e adicione no arquivo ex1.flex

a) {w {0,1}* | w tem tamanho 3}

b) {w {0,1}* | w tem tamanho maior que 4}

Depois rode para os seguinte arquivo teste.txt informando a qual linguagem cada linha pertence.

010 011001110101010010001101111001

Teste.txt

> jflex ex1.flex     //Gerar o Yylex.java

> javac Yylex.java   //Compilar o Yylex.java

>java Yylex teste.txt   //Rodar o Yylex.class

Prof José Rui

Análise léxica

Exercícios

● Seja as seguintes linguagens abaixo. Construa o autômato(caso necessário) e depois crie a EXPRESSÃO REGULAR de cada linguagem e adicione no arquivo ex1.flex

a) {w {0,1}* | w tem tamanho 3}

b) {w {0,1}* | w tem tamanho maior que 4}

Depois rode para os seguinte arquivo teste.txt informando a qual linguagem cada linha pertence.

010 011001110101010010001101111001

Teste.txt

> jflex ex1.flex     //Gerar o Yylex.java

> javac Yylex.java   //Compilar o Yylex.java

>java Yylex teste.txt   //Rodar o Yylex.class

Ling. a Ling. bLing. aLing. bLing. aLing. aLing. aLing. b

Saída.txt