Lex e Yacc n H muita teoria At
- Slides: 34
Lex e Yacc
n . . Há muita teoria. . . Até chegar neste ponto. . .
Definição n n Lex e Yacc são ferramentas que ajudam a criar programas C para analisar e interpretar um arquivo de entrada. Eles podem ser usados para ajudar a escrever montadores, compiladores e interpretadores, ou qualquer outro programa cuja entrada pertence a uma estrutura bem definida, e que se deseja transformar em outra.
Lex n n n Toma um conjunto de descrições de possíveis tokens e produz uma rotina em C que irá identificar estes tokens analisador léxico. Essa rotina lê a entrada e identifica “tokens”. Os “tokens” são definidos a partir de expressões regulares (especificação léxica).
Yacc n n Lê um arquivo que codifica a gramática de uma linguagem e produz uma rotina em C que irá executar a análise sintática, ou parsing, desta gramática. Essa rotina agrupa os “tokens” em uma sequência de interesse e invoca rotinas para realizar ações sobre elas.
Montadores n n Um montador recebe como entrada um programa em linguagem de montagem (que pode ser lido por humanos) e gera como saída um programa em linguagem de máquina (bits: adequado para máquinas). O funcionamento de um montador pode ser decomposto em três etapas: n n n Análise léxica - LEX Análise sintática e semântica - YACC Geração de Código.
Diagrama de um Montador Arquivo texto usuário Montador Programa Executável
Etapas de um montador n Cada estágio prepara a entrada para o próximo estágio. n n n O usuário disponibiliza um arquivo texto (bytes) O analisador léxico detecta e disponibiliza tokens para o parser O parser detecta agrupamentos de tokens segundo os comandos da linguagem de montagem e gera o código (realiza Ações) associado aos comandos.
Modelo básico de processamento para montadores input Analisador Léxico Analisador Sintático (Parser) Ações
Características Gerais n n A análise léxica pode ser vista como a primeira fase de um processo de tradução (compilação). Sua principal tarefa é ler uma seqüência de caracteres de entrada, geralmente associados a um código-fonte, e produzir como saída uma seqüência de itens léxicos. Por outro lado, a análise sintática tem por objetivo agrupar os itens léxicos em blocos de comandos válidos. Os itens léxicos são geralmente denominados tokens e correspondem a palavras-chave, operadores, símbolos especiais, símbolos de pontuação, identificadores (variáveis) e literais (constantes) partes de uma linguagem.
Características Gerais n n n Lex gera código C para análise léxica. Yacc gera código C para um parser. Ambas especificações são menores que um programa e mais fáceis de ler e entender. Por definição, o sufixo de um arquivo Lex é. l e de um arquivo Yacc é. y Lex cria uma rotina chamada yylex em um arquivo lex. yy. c Yacc cria uma rotina chamada yyparse em um arquivo chamado y. tab. c
Especif. LEX *. l lex Especif. YACC yacc lex. yy. c yylex( ) *. y *. c y. tab. c yyparse( ) gcc programa Rotinas C Bibliot. UNIX libl. a liby. a
Análise Léxica n Processo (programa) que classifica partes do arquivo texto de entrada em diversos tipos de tokens: n n números; comandos; strings; comentários. Pode ser especificada por meio de expressões regulares, passíveis de representação na forma de autômatos finitos.
Expressões Regulares n n Forma compacta de descrever uma sequência de caracteres. Ex. : n n ([0 -9]*. )*[0 -9]+ Essa expressão permite reconhecer os seguintes números: n n n 100 6. 8 45. 92
Ações n n n A função básica de uma rotina léxica é retornar tokens ao parser. As ações, em uma especificação Lex, consiste em expressões da linguagem C que retornam o token. Para retornar o token em uma ação, usa-se a expressão return. n [0 -9]+ { } yylval = atoi(yytext); return NUMBER;
Parser n n Um analisador léxico gera uma entrada para um parser interpretar. O parser tenta organizar os tokens de acordo com as regras de uma gramática. A gramática, para uma linguagem de programação, descreve a estrutura de um programa. Quando o parser encontra uma seqüência de tokens que corresponde a um comando da linguagem, a ação associada é executada.
Sumário de Rotinas Léxicas e Sintáticas de um Tradutor n n A rotina main do tradutor invoca (chama) yyparse para avaliar se a entrada é válida. yyparse invoca a rotina yylex cada vez que precisa de um token. A rotina léxica lê a entrada, e a cada token encontrado, retorna o número do token para o parser. A rotina léxica pode também passar o valor do token usando a variável externa yylval (entre outras).
Fluxo de controle de um tradutor main Entrada avaliada Retorna 0 se entrada é valida 1 se não yyparse( ) Valor da ação do processo yylval Requerer próximo token Retornar o token ou 0 se EOF Ler chars da entrada yylex( ) Valor passado do token input
LEX
Lex n n É um gerador de programas (módulo) destinados ao processamento léxico de textos. O módulo gerado pode funcionar como: n n n Filtro para processamento léxico; “Pattern Matching” (expressões regulares); Reconhecedor de linguagens regulares simples; Pré-processador simples; Analisador léxico para uso em conjunto com módulos de reconhecimento sintático.
Usando o LEX n Etapas: n n Escrever um arquivo texto com uma especificação Lex. Esse arquivo, por convenção, tem o sufixo. l. Executar o lex usando como entrada o arquivo. l. Esse passo gera um arquivo chamado lex. yy. c. Compilar lex. yy. c com o gcc, juntamente com quaisquer outros arquivos fonte ou bibliotecas eventualmente necessárias. Usar o executável gerado para análise léxica.
n n n lex. yy. c não contém um programa completo. Ele contém uma rotina léxica chamada yylex. Você pode integrar o analisador léxico com um parser gerado no Yacc. Um programa léxico também assume a existência de outras rotinas de suporte. Você pode fornecer essas rotinas, ou usar aquelas presentes na biblioteca standard do UNIX, a libl. a.
Estrutura de um texto LEX (. l) <definições gerais> /* opcional */ “%%” <regras de tradução> “%%” <rotinas C do usuário > /* opcional */
Estrutura de um texto LEX (. l) n A seção de definições pode possuir: n 1. A definição de macros como: n n digito [01]+ /* substituir {digito} por [01]+ ao processar as regras */ frac. [0 -9]+ /* substituir {frac} por. [0 -9]+ ao processar regras */ nl n /* substituir {nl} por n ao processar as regras */ 2. A inclusão das linhas de comando em C, que devem ser delimitadas por <%{> e <%}>, como: %{ #include <y. tab. h> extern int yylval; %}
Estrutura de um texto LEX (. l) n n n A seção de regras define a funcionalidade do analisador léxico. Cada regra compreende uma seqüência válida de caracteres (descrita utilizando literais e expressões regulares) e as ações semânticas associadas a ela. As regras têm a seguinte estrutura: <Esp. Regular> “{“ <Ação. C> “}”
Estrutura de um texto LEX (. l) n n Lex armazena temporariamente a subseqüência de caracteres identificada na variável yytext do tipo char *. Podemos, então, usar a função sscanf() da biblioteca de C para convertê-la em outros tipos de dados. A variável reservada pelo Lex para armazenar o resultado da conversão é yylval. A seção de rotinas do usuário é opcional; é usada para incluir rotinas em C desenvolvidas pelos usuários.
Estrutura de um texto LEX (. l) n Quando uma seqüência de caracteres de entrada casa com mais de uma regra, Lex adota uma das seguintes estratégias para resolver ambigüidades: n n escolher a regra que consegue casar a maior seqüência de caracteres possível; quando há mais de uma regra que case com a maior seqüência de caracteres, escolher aquela que aparece primeiro na seção de regras.
Um exemplo simples %% zippy %% n n n printf(“Eu reconheci zippy”); Este texto lex especifica um filtro para substituir as ocorrências de “zippy” por “Eu reconheci zippy”. Todo o texto que não se “encaixe” em nenhum pattern é simplesmente copiado para a saída. Neste exemplo, tanto as definições gerais, como as “rotinas C auxiliares” são inexistentes.
Utilização n cat sample. l %% zippy %% n n printf(“Eu reconheci zippy”); lex sample. l ls lex. yy. c sample. l n n gcc -o sample lex. yy. c -ll ls lex. yy. c sample. l
n cat test zippy harry zippy and zip n cat test |. /sample Eu reconheci zippy harry Eu reconheci zippy and zip
Exemplo 2 n cat sample 2. l %% zippy$ %% n n n printf(“ZIP”); printf(“Eu reconheci zippy”); printf(“Achei zippy no final da linha”); lex sample 2. l gcc -o sample 2 lex. yy. c -ll cat test |. /sample 2 Achei zippy na final da linha harry Eu reconheci zippy and ZIP
Exemplo 3 cat sample 3. l %% [A-Z]+[ tn] printf(“%s”, yytext); . ; %% n lex sample 3. l n gcc -o caps lex. yy. c -ll n cat test. caps n Xview é uma API executando sob o X Window que suporta o {pula linha} OPEN LOOK GUI. n . /caps < test. caps API X OPEN LOOK
Trabalho 1 (enviar para sp 1@lcad. inf. ufes. br) n Faça um arquivo. l que detecte: n n n n O mnemônico “add” e retorne o token ADD. Números inteiros em decimal e retorne o token NUMBER e, na variável yylval, o valor do número. Números inteiros em hexadecimal e retorne o token NUMBER e, na variável yylval, o valor do número. Labels e retorne em yytext a string com o label e o token LABEL. A especificação de um registrador ($1, por exemplo) e retorne o token REGISTER e, na variável yylval, o número do registrador Os caracteres: “, ” (COMMA), “(” (OPEN_PARENTHESIS), “)” (CLOSE_PARENTHESIS) O fim de uma linha e retorne END_OF_LINE
- Lex data e lex rogata
- Lex yacc example
- Nthu cs
- Lex & yacc
- Simple calculator using lex and yacc
- Yacc symbol table
- Lex symbol
- Lex orandi
- La ley es dura pero es la ley
- Queijos ricos em proteinas
- Muita paz tem os que amam a tua lei
- Lexical analyzer 구현
- Saumya debray
- Introduction to yacc
- Ntu lhs
- What is yacc in compiler design
- Yacc
- What is yacc
- Yacc program
- What is yacc
- Lexical analyzer generator lex
- Directive 2019/790
- Lex sempronia iudiciaria
- Systematyzacja pionowa
- Lex posterior derogat legi priori
- Lex naturalis
- Lex ovinia
- Lex frieden
- Lex societatis
- Vita flex lex
- Niezgodność prakseologiczna
- Lex rogata
- Lex specialis derogat legi generali
- Lex rogata
- Lex status