YACC.

Slides:



Advertisements
Apresentações semelhantes
Software Básico Silvio Fernandes
Advertisements

Tópicos em Compiladores
Laboratório de Programação
Laboratório de Programação Prof. Oscar Luiz Monteiro de Farias
Introdução à Ciência da Computação Linguagens de Programação.
Compiladores Claudio Benossi
II – Análise léxica DEI lex: linguagem de especificação para analisadores léxicos Implementação de simuladores de autómatos finitos Bibliografia aconselhada:
III – Análise sintáctica Geradores de parsers Bibliografia aconselhada: –Aho, Sethi e Ullman – secção 4.9 LFA 1999/ Jorge Morais.
Algoritmo e Programação
Compiladores I Cristiano Damiani Vasconcellos
Deyvisson, Rafael M.P., Renato, Robson C.F., Rodolfo
Programação para Engenharia I
Software Básico Silvio Fernandes
JavaCC e JJTree Geração de compiladores implementados em Java
LINGUAGEM C.
Lex e Yacc.
Implementando um Montador com LEX e YACC
Linguagem de Prog. e Programas
Construção de Compiladores
5.6 – Complementos de Yacc – Usando Yacc com gramáticas ambíguas
Linguagem C Strings.
Linguagem C Funções.
INTRODUÇÃ A COMPUTAÇÃO ENG. CIVIL
JAVA: Conceitos Iniciais
Introdução a Computação e Cálculo Numérico
Introdução a Computação e Cálculo Numérico
Introdução a Computação e Cálculo Numérico
PROGRAMAÇÃO I UNIDADE 1.
Análise léxica e sintática
Aula prática 7 Strings Monitoria de Introdução à Programação
Lex Linguagem (e compilador) para especificar analisadores léxicos.
1 Ponteiros Ponteiros são variáveis que guardam localizações em memória. A declaração de uma variável ponteiro x para um dado tipo type é type *x; Essa.
Ferramentas para a Construção de Compiladores: Lex & Yacc
Compiladores, Aula Nº 9 João M. P. Cardoso
Introdução a aplicativos Java
Análise Léxica Primeira fase de um compilador
Mayerber Carvalho Neto
Técnicas de Desenvolvimento de Programas
Análise Léxica.
Capítulo II Gramáticas e Linguagens
Linguagem de programação I A Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação.
Analise sintática aula-07-analise-sintática.pdf.
Estruturas de Dados Aula 2: Estruturas Estáticas 07/04/2014.
3. Introdução à Linguagem C
Analise Semântica aula-10-analise-semântica.pdf.
Analisador Léxico Prof. Alexandre Monteiro
Uso de parâmetros na linha de comando. Parâmetros da função main:
Compiladores Análise Léxica
Análise Léxica Prof. Alexandre Monteiro
Tradução Dirigida por Sintaxe
Aula Prática 3 Funções Monitoria Introdução à Programação.
CES-41 COMPILADORES Aulas Práticas Capítulo II A Ferramenta Yacc.
Programação Funcional
Analisador Léxico.
CES-41 COMPILADORES Aulas Práticas
Faculdade Pernambucana - FAPE Setembro/2007
COMPILADORES 04 Prof. Marcos.
Geradores de analisadores léxicos
Linguagem de programação I A Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação.
DSC/CCT/UFCG Carga Horária: 60 h Profs.: José Eustáquio Rangel de Queiroz Roberto Medeiros de Faria Ulrich Schiel José Eustáquio Rangel.
DSC/CCT/UFCG Carga Horária: 60 h Profs.: José Eustáquio Rangel de Queiroz Roberto Medeiros de Faria Ulrich Schiel José Eustáquio Rangel.
Programação Computacional Aula 8: Entrada e Saída pelo Console Prof a. Madeleine Medrano
Sintaxe de uma Linguagem
Lex e Yacc Compiladores Giovani Rubert Librelotto
Analisador sintático: Tipos de análises sintáticas
Compilador Software que traduz o texto (linguagem fonte) que representa um programa para código máquina(linguagem alvo) capaz de ser executado pelo.
Faculdade Pernambuca - FAPE Compiladores Abril/2007 Compiladores Abril/2007.
Informática Teórica Engenharia da Computação. Teoria da Computação Contexto do que vamos começar a estudar As linguagens também podem ser definidas formalmente.
Linguagem de Programação
Programação II Arquivos Autoria: Ernani Santos Modificação: Clebson Oliveira Adaptação: Claudia Boeres.
Transcrição da apresentação:

YACC

Introdução YACC significa – Yet Another Compiler Compiler O programa YACC recebe um texto com a descrição de uma gramática e ações associadas. A gramática em questão é uma série de regras de formação de strings. As regras descrevem como formar strings válidas (produções) a partir do alfabeto da linguagem (tokens).

Introdução A cada possível produção da gramática está associada uma ação. As ações são escritas em C e indicam o que é que se deve fazer cada vez que se reconhece uma produção. O YACC transforma esta descrição da gramática e ações associadas em um parser  programa capaz de analisar uma sequência de tokens de entrada, detectar produções e agir sobre elas.

Usando Yacc São 4 os passos para se criar um parser: Escrever uma especificação de uma gramática no formato do yacc. O arquivo terá a extensão .y Escrever uma especificação de um analisador léxico que pode produzir tokens; extensão .l Executar o yacc sobre a especificação .y e o lex sobre a especificação .l Compilar e linkar os códigos fontes do parser, do analisador léxico e suas rotinas auxiliares.

A saída do yacc, y.tab.c, contém a rotina yyparse que chama a rotina yylex para obter tokens. Como o Lex, o Yacc não gera programas completos. A yyparse deve ser chamada a partir de uma rotina main. Um programa completo também requer uma rotina de erro chamada yyerror. Ambas, main e yyerror, podem ser supridas pelo programador, por meio da biblioteca liby.a, que pode ser linkada com a opção -ly, na compilação.

Escrevendo uma Especificação Yacc Uma especificação yacc descreve uma gramática livre do contexto que pode ser usada para gerar um parser. Ela possui elementos membros de 4 classes: Tokens, que é o conjunto de símbolos terminais; Elementos sintáticos, que são símbolos não terminais. Regras de produção, que definem símbolos não terminais em termos de seqüência de terminais e não terminais; Uma regra start, que reduz todos os elementos da gramática para uma regra.

Símbolos A cada regra está associado um símbolo não terminal (lado esquerdo). As definições (lado direito) consistem de zero ou mais símbolos terminais (tokens ou caracteres literais) ou não terminais. Tokens são símbolos terminais reconhecidos pelo analisador léxico, e só aparecem no lado direito das regras. A cada regra pode ser associada uma ação em C. Estas ações ficam entre chaves ( { } ).

Símbolos (continuação) Os nomes de símbolos podem ter qualquer tamanho, consistindo de letras, ponto, sublinhado e números (exceto na primeira posição). Caracteres maiúsculos e minúsculos são distintos. Os nomes de não terminais são usualmente especificados em minúsculos. Tokens, em maiúsculos.

Formato da especificação Uma especificação mínima em yacc consiste de uma seção de regras, precedida de uma seção de declaração de tokens reconhecidos pela gramática. O formato é similar ao formato do Lex. declarações %% regras de produção rotinas em C do usuário

Yacc: Declarações Códigos em C entre %{ %} (como no Lex) Definição de tokens: %token T1 T2 T3 ... TN Definição de regras auxiliares para solução de ambigüidades: Exemplos: %left MAIS MENOS %left VEZES DIVIDIDO %left MENOS_UNARIO

Yacc: Regras de Produção As regras de produção tem a forma: /* uma gramática definida assim: */ <lado esquerdo> := <alt1>|<alt2>|...|<altN> /* transforma-se na seguinte especificação yacc */ <lado esquerdo>: <alt1> {/*ação 1*/} | <alt2> {/*ação 2*/} ... | <alt3> {/*ação N*/} ;

Yacc: Regras de Produção Cada símbolo (terminal ou não) tem associado a ele uma pseudo variável; O símbolo do lado esquerdo tem associada a ele a pseudo variável $$; Cada símbolo i da direita tem associada a ele a variável $i; $i contém o valor do token (retornado por yylex()) se o símbolo i for terminal, caso contrário contém o valor do $$ do não terminal; Ações podem ser executadas sobre estas variáveis.

Yacc: Rotinas em C do Usuário São funções em C que são copiadas para o parser gerado. São semelhantes às subrotinas auxiliares do Lex. Se o Lex não for usado para especificação do analisador léxico, a função yylex() deve ser implementada como uma rotina em C do usuário.

Exemplo (cat parser.y) %{ #include <stdio.h> #include <stdlib.h> %} %start calc %token END_OF_LINE ADD SUB OPEN_PARENTHESIS CLOSE_PARENTHESIS NUMBER %left ADD SUB %% calc : expr END_OF_LINE { printf("r: %d\n", $1); exit(0); } ; expr : expr ADD expr $$ = $1 + $3; | expr SUB expr $$ = $1 - $3; | OPEN_PARENTHESIS expr CLOSE_PARENTHESIS $$ = $2; | NUMBER /* código do usuário */

Exemplo (restante de cat parser.y) int yyerror (char *mens) { fprintf(stderr, "%s\n", mens); return (1); } main (int argc, char **argv) return (yyparse());

Exemplo (cat analisador_lexico.l) %{ #include <stdio.h> #include "y.tab.h" extern int yylval; %} %% add return (ADD); sub return (SUB); [0-9]+ {yylval = atoi(yytext); return NUMBER;}; 0x[0-9a-fA-F]+ {sscanf(yytext, "%x", &yylval); return NUMBER;}; \( return (OPEN_PARENTHESIS); \) return (CLOSE_PARENTHESIS); \n return (END_OF_LINE); . ;

Compilando o Exemplo yacc -d parser.y lex analisador_lexico.l gcc -o calc lex.yy.c y.tab.c -ll

Exemplo2 (cat parser2.y) %{ #include <stdio.h> #include <stdlib.h> %} %union { float float_val; } %start calc %token END_OF_LINE ADD SUB OPEN_PARENTHESIS CLOSE_PARENTHESIS %token <float_val> NUMBER %type <float_val> expr %left ADD SUB %% calc : expr END_OF_LINE printf("r: %f\n", $1); exit(0); ; expr : expr ADD expr ...

Exemplo2 (cat analisador_lexico2.l) %{ #include <stdio.h> #include "y.tab.h" //extern int yylval; int int_val; %} %% add return (ADD); sub return (SUB); [0-9]+ {yylval.float_val = atoi(yytext); return NUMBER;}; 0x[0-9a-fA-F]+ {sscanf(yytext, "%x", &int_val); yylval.float_val = int_val; return NUMBER;}; \( return (OPEN_PARENTHESIS); \) return (CLOSE_PARENTHESIS); \n return (END_OF_LINE); . ;

Trabalho 2 (enviar para sp1@lcad.inf.ufes.br) Faça uma calculadora de ponto flutuante usando o lex e o yacc que: Realize as operações de +, -, * e / sobre expressões; Compute as funções seno, cosseno e raiz quadrada sobre expressões.