Compiladores 02 - .::DCC · Lex regras léxicas Yacc regras sintáticas ... Lex Analisador Léxico...
Transcript of Compiladores 02 - .::DCC · Lex regras léxicas Yacc regras sintáticas ... Lex Analisador Léxico...
Sumário
● Análise Léxica
– Definição: Lexema, tokens
– Tabela símbolos
– Expressões regulares, automatos
Relembrando
● O compilador é dividido em duas etapas
– Análise
– Síntese
● Análise
– Análise léxica
● Quebra a entrada em pedaços conhecidos como tokens
– Análise sintática
● Analisa a estrura de frase do programa
– Análise semântica
● Verifica o “significado” do programa
Relembrando
● O compilador é dividido em duas etapas
– Análise
– Síntese
● Síntese
– Geração de código intermediário
– Otimização de código
– Geração de código objeto
Prof José Rui
Análise – (Front-end)
1.1) Análise léxica
– Organiza caracteres de entrada em grupos, chamados tokens
– Erros: tamanho máximo da variável excedido, formação de identificadores, caracteres inválidos..
1.2) Análise sintática
– Organiza tokens em uma estrutura hierárquica
– Erros: falta de (, ), =, identificador inválido...
1.3) Análise semântica
– Checa se o programa respeita regras básicas de consistência
– Erros: tipos inconsistentes → atribuir uma string em uma variável
Prof José Rui
Análise Léxica
● Também chamado de scanner
● Tarefa principal:
– Ler o arquivo onde se encontra o programa fonte
– Agrupar em sequências o que chamamos de lexemas (tokens)
Prof José Rui
Análise Léxica
● Algumas Definições:
● Lexemes: sequência de caracteres que forma uma unidade léxica
● Tokens: um objeto que contém um par de informações
● Identificador do tipo da unidade léxica● E um valor
Prof José Rui
Análise Léxica
● Exemplos de tokens:
– Identificadores ● nome_de_variavel
● nome_de_classe
– Palavras reservadas● if, while, class, for...
– Números inteiros sem sinal● 10, 234, 0
– Números reais● 1.8, 2.9, 0.1
– Caracteres especiais● $, º, ª
– Comentários● /* isto é um comentário
*/
Prof José Rui
Análise Léxica
● Tokens: um objeto que contém um par de informações
– Identificador do tipo da unidade léxica
– E um valor
● Ao ler um identificador(nome_de_variável) gera os seguintes tokens:
● Tempo → <IDENT, tempo>
● Soma → <IDENT, Soma>
Prof José Rui
Análise Léxica
● Tokens: um objeto que contém um par de informações
– Identificador do tipo da unidade léxica
– E um valor
● Ao ler um identificador(nome_de_variável) gera os seguintes tokens:
● Tempo → <IDENT, tempo>
● Soma → <IDENT, Soma>
Isto é um TOKEN!
Prof José Rui
Análise Léxica
● Tokens: um objeto que contém um par de informações
– Identificador do tipo da unidade léxica
– E um valor
● Ao ler uma palavra-chave, gera os seguintes tokens:
● If → <KW_IF>● while → <KW_WHILE>● Class → <KW_CLASS>● ( → <LEFTPAR>
Estes tokens, não precisam do valor
Prof José Rui
Análise Léxica
● Cada linguagem tem seu conjunto de tokens que são aceitos
● Por exemplo:
– Pascal: existe a palavra-chave then
– C++: não possui
Prof José Rui
Análise Léxica
● Cada linguagem tem seu conjunto de tokens que são aceitos
● Por exemplo:
– Pascal: existe a palavra-chave then
– C++: não possui
● A principal função do ANALISADOR LÉXICO é:
– Ler o arquivo
– E verificar se o que foi lido é um “token válido”
● Ao conjunto de “tokens aceitos” dá-se o nome:
– Tabela de símbolos
Prof José Rui
Análise Léxica
● Tabela de símbolos
– Conjunto de “tokens aceitos”
– Funciona como uma base de consulta para as fases seguintes do compilador
– Também utilizada para armazenar
● o tipo das variaveis● o valor das variáveis ● e seu escopo
Prof José Rui
Análise Léxica
● Tabela de símbolos (exemplo de funcionamento)
– Seja o código:
fi ( a < 10 ) {
return a;}
Prof José Rui
Análise Léxica
● Tabela de símbolos (exemplo de funcionamento)
– Seja o código:
fi ( a < 10 ) {
return a;}
● Inicia a leitura do texto
● Captura as letras “f” e depois “i”
● O analisador léxico verifica na tabela de símbolos se:
– fi é uma palavra reservada ?
Prof José Rui
Análise Léxica
● Tabela de símbolos (exemplo de funcionamento)
– Seja o código:
fi ( a < 10 ) {
return a;}
● Inicia a leitura do texto
● Captura as letras “f” e depois “i”
● O analisador léxico verifica na tabela de símbolos se:
– fi é uma palavra reservada ?
● Como não encontra informa que fi é um identificador
<IDENT, fi >
Análise léxica
● Exemplo
– Soma = a + b * 40; <IDENT, apontador p/ posição soma na tabela de simbolos>, <OP_IGUAL>, <IDENT, apontador p/ posição a na tabela de simbolos>, <OP_SOMA>, <IDENT, apontador p/ posição b na tabela de simbolos>, <OP_MULT>,<NUM, valor 40>
Analisadorléxico
Análise léxica
● Exemplo
– Soma = a + b * 40; <IDENT, apontador p/ posição soma na tabela de simbolos>, <OP_IGUAL>, <IDENT, apontador p/ posição a na tabela de simbolos>, <OP_SOMA>, <IDENT, apontador p/ posição b na tabela de simbolos>, <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
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
● 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
A partir da tabela pronta, todas fases a consultam!
Análise léxica
● Exercicio:
x1 = 60.8 + id2;
flag2 = x1 * 2;
– Faça a analise léxica e construa a tabela de símbolos
Prof José Rui
Análise Léxica
● Seja este fonte:
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
● O analisador léxico, vê o código fonte como uma sequência de caracteres
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
● O analisador léxico une os caracteres de acordo com os tokens da linguagem
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
● O analisador léxico une os caracteres de acordo com os tokens da linguagem
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
● Note que:
– O Analisador Léxico ignora os espaços em branco
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
● Note que:
– O Analisador Léxico ignora os espaços em branco
– Também ignora comentários, newLine...
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
● Note que:
– O Analisador Léxico ignora os espaços em branco
– Também ignora comentários, newLine...
– Fica apenas os tokensint gcd (int a, int b){
while(a != b){if(a > b)
a = b;else
b = a;}return a;
}
Análise léxica
● Lembrando que:
– Cada token tem um codigo/nome
– Ex: while → <KW_WHILE>
int gcd (int a, int b){while(a != b){
if(a > b)a = b;
elseb = a;
}return a;
}
Análise léxica
● Adiante veremos que, além do codigo/nome ele tem um numero que o identifica
– Ex: while → <KW_WHILE> 12→
int gcd (int a, int b){while(a != b){
if(a > b)a = b;
elseb = a;
}return a;
}
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 - Perguntinha básica
● Como ele faz esse scanner(leitura) do arquivo?
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 - Perguntinha básica
● Como ele faz esse scanner(leitura) do arquivo?
– Faça um programa para isso...
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 - Perguntinha básica
● Como ele faz esse scanner(leitura) do arquivo?
– Autômatos!!!
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
● Exemplo dos formalismos:
– letra → [A – Z] [a – z]
– digito → [0 – 9]
– digitos → digito digito*
– ident → letra (letra | digito)*
Expressão Regular Autômato Finito
Prof José Rui
Análise Léxica
● Exemplo dos formalismos:
– letra → [A – Z] [a – z]
– digito → [0 – 9]
– digitos → digito digito*
– ident → letra (letra | digito)*
Expressão Regular Autômato Finito
São eles os responsáveis por ler e validar o texto lido!
Análise léxica
● Algumas definições regulares dos tokens
– letra → [A – Z] [a – z]
– digito → [0 – 9]
– digitos → digito digito*
– ident → letra (letra | digito)*
– fracao → .digitos | ε
– exponencial → E ( + | - | ε) digitos | ε
– num → digitos fracao exponencial
– KW_INT → int
– KW_WHILE → while
Análise léxica
● Operadores
– * Zero ou mais instancias
– + Uma ou mais instancias
– ? Zero ou uma instancia
– [ ... ] Classe de caracteres
● Ex: [A-Z]
– A | B Instancia de A ou de B
– AB Instancia de A seguida da instancia B
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
Análise léxica
● Diagrama scanner-parser:
● Jflex e Jcup
regrasléxicas
regrassintáticas
Expressões regulares
Análise léxica
● Diagrama scanner-parser:
● Jflex e Jcup
Lex
regrasléxicas
Yacc
regrassintáticas
Expressões regulares
Geradores automáticosJflex e jcup
Análise léxica
● Diagrama scanner-parser:
● Jflex e Jcup
Lex
AnalisadorLéxico
regrasléxicas
Yacc
AnalisadorSintático
regrassintáticas
Expressões regulares
Geradores automáticosJflex e jcup
Classes geradas
Análise léxica
● Diagrama scanner-parser:
● Jflex e Jcup
Lex
AnalisadorLéxico
regrasléxicas
entrada
Yacc
AnalisadorSintático
regrassintáticas
saída
Expressões regulares
Geradores automáticosJflex e jcup
Classes geradas
Análise léxica
● Exercício
– Defina os tokens e faça a analise léxica do fonte C++ abaixo:
int main (){float altura, peso, imc;int i;cout << “Informe altura e peso”;cin >> altura;cin >> peso;
while(i <= 10){imc = altura/(peso*peso);
if(imc > 1.89)return altura;
elsereturn peso;
i = i + 1;}
}
Análise léxica
● Construa o automato para a seguinte linguagem
– L = { w | w possui aa ou bb como subpalavra }