Introdução. Flex e uma ferramenta para gerar scanners programas que reconhecem padrões lexicais em texto

Documentos relacionados
Lex Adaptação da obra original de Tom Niemann

Compiladores. Lex e Yacc / Flex e Bison. Ferramentas Flex/Bison

1 d=

Compiladores 04 Analise léxica Jflex. Prof José Rui

O que faz/o que é Como usar Como funciona Formato geral do Arquivo Submetido ao Lex ER estendidas Exemplos The Lex & YACC page:

Utiliza Expressões Regulares (ER) Estendidas para definir a especificação da análise léxica desejada

Linguagem C. André Tavares da Silva.

3.1 - Funções para manipular dados de entrada e saída padrão

Construção de Compiladores Aula 2 - Analisador Léxico

Compiladores I Prof. Ricardo Santos (cap 3 Análise Léxica: Introdução, Revisão LFA)

Introdução ao FLEX e expressões regulares

INSTITUTO FEDERAL DE! EDUCAÇÃO, CIÊNCIA E TECNOLOGIA RIO GRANDE DO NORTE

Compiladores. Bruno Lopes. Bruno Lopes Compiladores 1 / 31. Instituto de C

3. Linguagem de Programação C

Algoritmos e Programação

A linguagem C (visão histórica)

Linguagem C Princípios Básicos (parte 1)

5 - COMANDOS DE CONTROLE DE PROGRAMA Em C existem os comandos de decisões, os comandos de iteração (ou de laços) e os comandos de desvios.

Programa fonte token padrões lexema Tokens

Ambiente de desenvolvimento

Conhecendo a Linguagem de Programação C

Compiladores - JFlex. Fabio Mascarenhas

Linguagens de Programação PROGRAMAÇÃO DE COMPUTADORES. Linguagem C. Linguagem C Estrutura Básica. Constante (literais) Linguagem C Primeiro Programa

Compiladores - JFlex. Fabio Mascarenhas Monday, April 15, 13

Computação 2. Aula 8. Profª. Fabiany Arquivos

LISTA DE EXERCÍCIOS MÊS 03

Programação de Computadores I Introdução ao C PROFESSORA CINTIA CAETANO

#include <stdio.h> Void main() { printf( Cheguei!\n"); } INTRODUÇÃO A LINGUAGEM C

ALGORITMOS AULA 01. Baseado nas aulas do Prof. Jorgiano Vidal

Linguagem de Programação C

Linguagem C. IF61A/IF71A - Computação 1 Prof. Leonelo Almeida. Universidade Tecnológica Federal do Paraná

Identificação do discente: Matrícula: Nome completo: Douglas Godeguez Nunes. Curso: Ciência da Computação

Anhanguera Educacional S.A. Centro Universitário Ibero-Americano

Arquitetura e Organização de Computadores. Compiladores e processamento

Linguagem C Entrada/Saída (console)

Linguagens e Programação BISON. Paulo Proença

Comando Switch. Embora a escada if else-if possa executar testes de várias maneiras, ela não é de maneira nenhuma elegante.

Fundamentos de Programação 1

Introdução à Programação

Aula 1 Apresentação do Curso

Universidade Estadual da Paraíba - UEPB Curso de Licenciatura em Computação

Compiladores. Aulas práticas Pedro Freire

Compiladores. Análise Léxica

Figura 1: Operações para gerar um programa executável.

Compiladores 02 Analise léxica

system("pause"); //Envia comando para o sistema operacional solicitando parada de execução do programa } //limitador do corpo do programa

Analisador Léxico parte II

Tópicos em C. Eliade F. Lima

Prof. Marcelo Machado Cunha Faculdade Pio Décimo

Programação Básica. Estrutura de um algoritmo

Computação 2. Aula 9. Diego Addan Arquivos

Linguagem de Programação C. Prof. Fabrício Olivetti de França

Linguagens de Programação

Legibilidade do código fonte

Prática - Linguagem C. Exercícios - Desenvolvendo um pequeno projeto

aceita, l L R L (l) = erro, l L

Aula 6 Oficina de Programação Estruturas Condicionais no C. Profa. Elaine Faria UFU

Aula 5 Oficina de Programação Introdução ao C. Profa. Elaine Faria UFU

1ª Lista de Exercícios

Programação Estruturada Prof. Rodrigo Hausen Entrada e Saída Parte 2

Questão Aula Tipo - Flex+Bison

Compiladores. Conceitos Básicos

A Linguagem C. A forma de um programa em C

Aula 3 Constantes e funções de E/S

Laboratório de Introdução à Ciência da Computação I

Linguagem C Introdução. Contexto Histórico Principais diferenças do Java Funções em C Compilar programas em C no Linux

Função, interação com o compilador Especificação e reconhecimento de tokens Implementação Tratamento de erros. Prof. Thiago A. S.

Licenciatura em Engenharia Informática DEI/ISEP Linguagens de Programação 2006/07. Tópicos avançados

K&R: Capitulo 2 IAED, 2012/2013

Sistemas Operacionais e Introdução à Programação. Programação com linguagem C

Linguagens de Programação I

Linguagem C. Brian W. Kernighan, Dennis Ritchie (K&R) Slides adaptados, inspirados, muitos copiados dos slides do professor Pedro Pereira

Processamento de Linguagens I LESI + LMCC (3 o ano)

Linguagem de Programação C

Programação I A Linguagem C. Prof. Carlos Alberto

Construção de Compiladores Aula 3 - Analisador Sintático

Programação I PRG Engenharia de Telecomunicações 2ª Fase Professor: Cleber Jorge Amaral

Compiladores. Análise lexical. Plano da aula. Motivação para análise lexical. Vocabulário básico. Estrutura de um compilador

Compiladores - Análise Léxica

Linguagem C Controle do Fluxo de Execução. Lógica de Programação

LINGUAGEM C: FUNÇÕES FUNÇÃO 08/01/2018. Funções são blocos de código que podem ser nomeados e chamados de dentro de um programa.

Variáveis e Operadores em C

Compiladores / YACC Professor Ariel da Silva Dias YACC. Adaptação da obra original de Tom Niemann

Aula 3 Primeiros programas

Introdução à Programação

Estruturas da linguagem C. 1. Identificadores, tipos primitivos, variáveis e constantes, operadores e expressões.

Compiladores. Prof. Bruno Moreno Aula 8 02/05/2011

Programação. MEAer e LEE. Manipulação de ficheiros de texto. Bertinho Andrade da Costa. Instituto Superior Técnico. 2010/2011 1º Semestre

Compiladores. Análise Léxica

Fundamentos de Programação

Depuração e Teste de programas C C Depuração e teste de programas C

Identificadores Nome de variáveis, constantes, métodos, etc...

Sumário. Ficheiros. Ficheiros

LINGUAGEM DE PROGRAMAÇÃO C AULA 2. Professor: Rodrigo Rocha

Folha 3 - Análise léxica

Introdução a Programação de Jogos

Manipulação de Arquivos Exercício/Exemplo:

Variáveis, Comandos de Atribuição e Comando de Entrada e Saída

Introdução a Linguagem C. Prof. Me. Hélio Esperidião

Transcrição:

Compiladores Flex

Introdução Flex e uma ferramenta para gerar scanners programas que reconhecem padrões lexicais em texto O flex lê o arquivo de entrada fornecido, para uma descrição de um scanner a ser gerado A descrição está na forma de pares de expressões regulares e código C chamadas de regras Flex gera como saída um arquivo de origem C denominado lex.yy.c, definindo uma rotina yylex() Este arquivo é compilado e vinculado a biblioteca para produzir executável (-lfl) Quando o executável é executado, ele analisa a entrada em busca de ocorrências das expressões regulares Sempre que encontrar uma correspondência, ele executa o código C correspondente

Introdução Instalado o flex sudo apt-get install flex

Introdução Durante a primeira fase, o compilador lê a entrada e converte as strings na origem para os tokens Com expressões regulares, podemos especificar padrões para o flex O flex pode gerar código que permitirá a varredura e a correspondência de strings na entrada Cada padrão na entrada para o flex tem uma ação associada A ação, normalmente, retorna um token que representa a string correspondente, a qual será utilizada subsequentemente pelo analisador A principio, imprimiremos a string correspondida em vez de retornar um valor de token

Introdução A regra a seguir representa um padrão simples, com posto por uma expressão regular que procura por identificadores letra(letra digito)* Esta regra corresponde a uma sequencia de caracteres a qual começa com uma única letra seguida por zero ou mais letras ou dígitos Qualquer expressão regular pode ser expressa como autômato de estado finito letra ou digito inicio letra outro

Introdução O estado 0 é o inicial e o estado 2 é o de aceitação inicio letra letra ou digito outro Conforme os caracteres são lidos, fazemos uma transição de um estado para outro Está máquina de 3 estados é facilmente programada:

Introdução start: goto state0 state0: read c if c = letra goto state1 goto state0 state1: read c if c = letra goto state1 if c = digito goto state1 goto state2 state2: accept string inicio letra letra ou digito outro

Introdução Durante a primeira fase, o compilador lê a entrada e converte as strings na origem para os tokens Com expressões regulares, podemos especificar padrões para o flex O flex pode gerar código que permitirá a varredura e a correspondência de strings na entrada Cada padrão na entrada para o flex tem uma ação associada A ação, normalmente, retorna um token que representa a string correspondente, a qual será utilizada subsequentemente pelo analisador A principio, imprimiremos a string correspondida em vez de retornar um valor de token

Padrões Caracteres especiais Padrão Match. Qualquer caractere, exceto nova linha \. Literal \n Nova linha \t Aba ^ Começo de linha $ Fim de linha

Padrões Operadores Padrão Match? zero ou uma cópia da expressão anterior * zero ou mais cópias da expressão anterior + uma ou mais cópias da expressão precedente a b (ab)+ abc a ou b (alternando) uma ou mais cópias de ab (agrupamento) abc abc* ab abc abcc abccc abcccc... abc* literal abc* abc+ abc abcc abccc abcccc... a(bc)+ abc abcbc abcbcbc... a(bc)? a abc

Padrões Caracteres Padrão Match [abc] um de a b c [a-z] qualquer letra de a a z [a\-z] um de a - z [-az] um de a z [A-Za-z0-9]+ um ou mais caracteres alfanuméricos [ \t\n]+ espaço em branco [^ab] qualquer coisa exceto a b [a^b] um de a ^ b [a b] um de a b

Formato arquivo flex/lex A entrada para Flex é dividido em 3 seções com %% dividindo as seções... definições... %%... regras... %%... sub-rotinas (código C)...

Formato arquivo flex/lex A seção de definições pode ter: %{ Inicializações de variáveis C e funções/protótipos C (opcional, podem também ser linhas indentadas, sem %{ %}) %} %directiva /* Comentário, copiado para o arquivo C final lex.yy.c */ nome expressão regular

Formato arquivo flex/lex A seção de regras pode ter: %{ Inicializações de variáveis e código C locais à função yylex() (opcional, podem também ser linhas indentadas, sem %{ %}) %} expressão regular ação

Gerando o scanner vim nomearquivo.l Salvar no vim :w Salvar e sair :wq Sair sem salvar :!q Sair :q gcc lex.yy.c o scan./scan cria e abre o arquivo para criação do analisador léxico compila o arquivo lex.yy.c com o gcc gerando o executável scan executa o analisador léxico

Variáveis pré-definidas Nome int yylex(void) char *yytext yyleng yylval int yywrap(void) FILE *yyout FILE *yyin INITIAL BEGIN condition ECHO Função Chamada para invocar o lexer, retorna um token ponteiro para string encontrada (correspondente) comprimento da string encontrada (correspondente) valor associado ao token retorna 1 se estiver pronto, 0 se não estiver arquivo de saída arquivo de entrada condição de inicialização condição de inicialização escreve uma string encontrada (correspondente)

Exemplos simples O flex a seguir especifica um scanner que, sempre que encontrar um caracter qualquer mostra uma mensagem na tela

Exemplos simples %%. printf( Encontrei um caracter qualquer ); \n printf( Encontrei uma quebra de linha ); %% int yywrap(void){ return 1; } int main(void){ yylex(); return 0; }

Exemplos simples Grave este arquivo como aula1.l (a extensão é por convenção um L minúsculo Para compilar você precisa ter o flex instalado Então, se tiver, na linha de comando (terminal Linux) execute flex aula1.l Será criado um arquivo chamado lex.yy.c, o qual deve ser compilado na linha de comando. Se for o compilador da GNU, faça gcc lex.yy.c o comp Para executar faça./comp e tecle enter

Exemplos simples O programa parece não fazer nada, no entanto ele está aguardando você entrar com dados Escreva qualquer coisa que inclua letras e números Ele retornará dizendo que encontrou algo Quando terminar de testar, pressione CTRL C

Exemplos simples Você também pode criar um arquivo de texto e inserir valores lá dentro Por exemplo, crie um arquivo chamado teste.txt e adicione algumas palavras Em seguida, execute o programa anterior desta forma./comp < teste.txt Desta vez o programa comp vai mostrar imediatamente os resultados e encerrar

Exemplos simples digito [0-9] letra [A-Za-z] %{ {digito} printf( \nencontrei o digito %s, yytext); {letra} printf( \nencontrei a letra %s, yytext); %} %% int yywrap(void){ return 1; } int main(void){ yylex(); return 0; }

Expressões regulares específicas do flex Caracteres e escapes [[:c:]] Conjunto pré-definido ( Expressões de classes de caracteres ) ver manual do flex s s literal para usar em s o próprio caracter, fazer \, e para usar a própria \, fazer \\ (onde s é um símbolo qualquer) \c Se for o caracter 0, a, b, f, n, r, t ou v, então é o caracter ANSI-C correspondente, caso contrário é um c literal (usado para escaping de caracteres especiais) \### Código octal ASCII de um caracter \x## Código hexadecimal ASCII de um caracter

Expressões regulares específicas do flex Expressões {n} r/s Expansão de n, sendo n um nome (ver exemplo a seguir) Encontra r apenas se for seguido por s (s não fará parte de yytext); nem todos as expressões regulares podem ser usadas em s ver manual do flex

Expressões regulares específicas do flex Âncoras ^ Neste local tem de existir o início de uma linha $ Neste local tem de existir o fim de uma linha <<EOF>> Neste local tem de existir o fim do arquivo/dos dados de entrada; No caso da omissão para este tipo de âncora haverá um return que termina a execução da função gerada pelo Flex Âncoras representam posições no arquivo ou nos dados de entrada (veja exemplo a seguir)

Exemplo digito [0-9] letra [A-Za-z] %{ {digito} printf( \nencontrei o digito %s, yytext); {letra} printf( \nencontrei a letra %s, yytext); aluno[s] puts( \nencontrei a expressão \ aluno[s] ); ^Ze$ puts( \nencontrei \ Ze\ sozinho em uma linha ); <<EOF>> puts( \nencontrei o fim do arquivo ); return; %} %% int yywrap(void){ return 1; } Para testar o EOF, faça CTRL D no UNIX ou CTRL Z no Windows int main(void){ yylex(); return 0; }

Encontrando comentário em C //comentario digito [0-9] letra [A-Za-z] %{ {digito} printf( \nencontrei o digito %s, yytext); {letra} printf( \nencontrei a letra %s, yytext); //.* printf( \nencontrei o comentário %s, yytext); %} %% int yywrap(void){ return 1; } int main(void){ yylex(); return 0; } Para o comentário também poderia ser: [/][/].* ou \/\/.*

Encontrando comentário de bloco em C /*... */ digito [0-9] letra [A-Za-z] %{ {digito} printf( \nencontrei o digito %s, yytext); {letra} printf( \nencontrei a letra %s, yytext); //.* printf( \nencontrei o comentário %s, yytext); /*.* */ printf( \nencontrei comentário de bloco %s, yytext); %} %% int yywrap(void){ return 1; } int main(void){ yylex(); return 0; }

Exemplo 1 Neste primeiro exemplo, construiremos um reconhecedor de calculadora pós-fixa Neste modelo de calculadora o operador segue os dois operandos 8 9 + 17 3 7 + 10

Exemplo 1 Calculadora de inteiros, pós-fixa %option main #include <stdio.h> #include <stdlib.h> int a=0; int b=0; %% int r; [+-]?[0-9]+ a=b; b=atoi(yytext); [+] r=a+b; printf( %d + %d = %d\n, a,b,r); a=b; b=r; [-] r=a-b; printf( %d - %d = %d\n, a,b,r); a=b; b=r; [*] r=a*b; printf( %d * %d = %d\n, a,b,r); a=b; b=r; [/] r=a/b; printf( %d / %d = %d\n, a,b,r); a=b; b=r;. \r \n Exemplo de entrada: 2 3 + será 5; 8 2 + será 10

Exemplo 2 Neste exemplo, criaremos um analisador no flex responsável por ser um contador de ids e números inteiros em um código fonte de uma linguagem qualquer O id é uma sequencia de um ou mais caracteres alfanuméricos ele não pode começar com um caracter numérico, apenas letras

Exemplo 2 Contador de identificadores %option noyywrap #include <stdio.h> enum { TOKEN_IDENT, TOKEN_INT, TOKEN_MISC, TOKEN_EOF }; %% [a-za-z][a-za-z0-9]* return TOKEN_IDENT; [+-]?[0-9]+ return TOKEN_INT;. \r \n return TOKEN_MISC; <<EOF>> return TOKEN_EOF; %%

Exemplo 2 Contador de identificadores int main() { int num_id = 0; int num_int = 0; int token; do{ switch(token=yylex()){ case TOKEN_IDENT: ++num_id; break; case TOKEN_INT: ++num_int; break; } }while(token!= TOKEN_EOF); printf( Identificadores %d\n, num_id); printf( Inteiros %d\n, num_int); return 0; }

Exemplo 2 As ações fazem um return, saindo assim da função yylex() Desta forma, a função yylex() apenas auxilia na detecção dos tokens e não tem o trabalho de processar os mesmos Quando trabalharmos com o bison, utilizaremos o flex desta forma

Atividade Agora, combine os dois exemplos anteriores, criando uma calculadora infixa de números reais. A leitura de cada token deve ser feita pela função main(), chamando o yylex() para ler cada token (como no exemplo 2).