1 / 116

CES-41 COMPILADORES Aulas Práticas - 2014

CES-41 COMPILADORES Aulas Práticas - 2014. Capítulo II A Ferramenta Yacc. Yacc é um gerador de analisadores sintáticos:

felix
Télécharger la présentation

CES-41 COMPILADORES Aulas Práticas - 2014

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. CES-41 COMPILADORESAulas Práticas - 2014 Capítulo II A Ferramenta Yacc

  2. Yacc é um gerador de analisadores sintáticos: • Têm como entrada a gramática livre de contexto da linguagem-fonte do compilador e implementa uma função de nome yyparse, que responde se o programa analisado tem ou não erros sintáticos • Yacc (YetAnotherCompiler-Compiler) do sistema UNIX também possui diversas versões para o sistema DOS (o Yacc do Mingw é uma delas) • O analisador gerado é um programa em Linguagem C

  3. Programa 2.1: Saída de dados • Criar na pasta MinGW/bin um arquivo extensão .y (saida.y, por exemplo) com o seguinte programa: %% prod: {printf ("hello friends!\n");} ; %% yylex () { return 0; } • Executar os seguintes comandos: yaccsaida.y gccy.tab.c main.c yyerror.c -o saida -lfl saida Colocar pelo menos uma produção Não pode haver função main Tem de haver função yylex

  4. %% prod: {printf ("hello friends!\n");} ; %% yylex () { return 0; } • Executar: saida > ppp • Abrir o arquivo ppp (No DOS: more ppp) • Abrir o arquivo main.c (só executa yyparse e retorna) • yyparse é o analisador sintático produzido pelo Yacc • Abrir o arquivo y.tab.c e localizar yylex, prod e o printf acima

  5. Estrutura de um programa em Yacc: • Tal como em Lex,um programa em Yacc é dividido em três partes, a saber: Declarações % % Produções da gramática % % Rotinas auxiliares

  6. Produções da gramática: • É a parte principal de um programa em Yacc • O programa deve conter pelo menos uma produção • As produções podem vir acompanhadas de ações escritas na Linguagem C, inseridas em qualquer posição de seu lado direito

  7. Produções da gramática: • Exemplo: Sejam as produções: ExprExprOPAD Termo | Termo Termo ID | CTE • Em Yacc, com ações opcionais: expr : expr OPAD {comandos em C} termo | {comandos em C} termo ; termo : ID {comandos em C} | CTE {comandos em C} ;

  8. Produções da gramática: • Ações podem aparecer no lado direito de uma produção vazia • Exemplo: yyy : {comandos em C} | xxx {comandos em C} zzz ; A primeira produção de yyy é vazia

  9. Declarações: Nelas estão inclusas: • Em C, delimitadas por %{ e %}: • Declarações de variáveis, tipos, protótipos, etc. • Definições de constantes e macros (define’s) • Inclusão de arquivos sem definição de funções • Declarações do Yacc (fora de %{ e %}) usadas para definir terminais, não-terminais, precedência de operadores, tipos dos atributos, etc.

  10. Declarações: • Exemplo: para as produções anteriores expr : expr OPAD {comandos em C} termo | {comandos em C} termo ; termo : ID {comandos em C} | CTE {comandos em C} ; os átomos são assim declarados: %token OPAD %token ID %token CTE

  11. Rotinas auxiliares: • São definições de funções em C, referenciadas nas ações das produções da gramática • Podem trazer a inclusão de arquivos com extensão .c; por exemplo, o arquivo lex.yy.c, do Flex • Não devem conter a função main, pois essa já vem inclusa no ambiente da ferramenta • Devem incluir a função yylex; quando usado com Flex, essa função já vem contida no arquivo lex.yy.c

  12. prod : {printf ("hello friends!\n"); return;} %% prod : {printf ("hello friends!\n");} ; %% yylex () { return 0; } • Fazer yylex retornar algo diferente de zero • Colocar um return dentro da ação depois do printf return 50; Retomando o programa saida.y

  13. Explicando os fatos %% prod : {printf ("hello friends!\n");} ; %% yylex () { return 0; } • O analisador gerado pelo Yacc é bottom-up • Vai detectando lados direitos de produções e reduzindo-os para seus lados esquerdos • Tudo acaba bem quando se consegue chegar ao símbolo inicial

  14. Explicando os fatos %% prod : {printf ("hello friends!\n");} ; %% yylex () { return 0; } • A única produção desta gramática (prod) é vazia • Antes de yyparse pedir um átomo para yylex, ele casa a falta de átomo em suas mãos com seu lado direito • yyparse faz a redução para o lado esquerdo e executa a ação no final da produção • Chegou ao símbolo inicial

  15. Explicando os fatos %% prod : {printf ("hello friends!\n");} ; %% yylex () { return 0; } • Em seguida, chama yylex que lhe retorna zero • Recebendo zero, ele aceita e retorna • main então se encerra

  16. prod : {printf ("hello friends!\n"); return;} Explicando os fatos %% prod : {printf ("hello friends!\n");} ; %% yylex () { return 50; } • Depois de chegar ao símbolo inicial, yyparsesó aceita o átomo zero • Se yylex lhe retornar algo diferente de zero, ele rejeitará • Com o return dentro da ação, yyparse retorna para main antes de chamar yylex

  17. Programa 2.2: Entrada de dados • Criar um arquivo extensão .y (entra.y, por exemplo) com o seguinte programa: %% ppp: {int i, n; printf ("Digite o numero de repeticoes: "); scanf ("%d", &n); for (i = 1; i <= n; i++) printf ("\nhello friends!"); } ; %% yylex () {return 0;}

  18. Executar os seguintes comandos: yacc entra.y gccy.tab.c yyerror.c main.c -o entra -lfl entra • Criar um arquivo entra.dat, colocando nele o número 10 • Executar os comandos: entra < entra.dat entra < entra.dat > ppp • Abrir o arquivo ppp

  19. Esquema de produção de um programa executável usando Yacc, sem auxilio do Flex:

  20. Programa 2.3: Reconhecimento de frase • Rodar yacc e gcc para um arquivo recfrase.y com o seguinte programa: %% prod : 'C' 'O' 'M' 'P' ' ' '1' '5' {printf ("Reconheco!\n"); return;} ; %% yylex () { returngetchar (); } O lado direito das produções tem apenas terminais (tokens) Um caractere entre apóstrofos é considerado um token Executar recfrase com: COMP 14 COMP 15 COMP 16 COMP 153

  21. Programa 2.3: Reconhecimento de frase • Rodar yacc e gcc para um arquivo recfrase.y com o seguinte programa: %% prod : 'C' 'O' 'M' 'P' ' ' '1' '5' {printf ("Reconheco!\n"); return;} ; %% yylex () { returngetchar (); } Executar com arquivo de dados (recfrase.dat, por exemplo): uma frase de cada vez Executar: recfrase < recfrase.dat > ppp Executar recfrase com: COMP 14 COMP 15 COMP 16 COMP 153

  22. Experimente tirar o return; sem e com arquivo de dados Tokens são convertidos em defines pelo Yacc Programa 2.4: Gramática S → ε | a S b %token a %token b %tokendolar %token erro %% SS : S dolar {printf ("Fim da analise\n"); return;} ; S : | a S b ; %% yylex () { char x; x = getchar (); while (x == ' ' || x == '\n' || x == '\t' || x == '\r') x = getchar (); printf ("Caractere lido: %c\n", x); if (x == 'a') return a; if (x == 'b') return b; if (x == '$') returndolar; return erro; } Rodar para várias cadeias, uma por vez: aabb$ $ aaabbb$ a$b$aaabb$ aabbb$ aba$ ba$ Rodar com arquivo de dados contendo: aabb$

  23. Experimente tirar o return; sem e com arquivo de dados Programa 2.4: Gramática S → ε | a S b %token a %token b %tokendolar %token erro %% SS : S dolar {printf ("Fim da analise\n"); return;} ; S : | a S b ; %% yylex () { char x; x = getchar (); while (x == ' ' || x == '\n' || x == '\t' || x == '\r') x = getchar (); printf ("Caractere lido: %c\n", x); if (x == 'a') return a; if (x == 'b') return b; if (x == '$') returndolar; return erro; } Chegando ao símbolo inicial, yyparse sempre chama yylex, esperando zero yylexsó retorna quando um caractere é digitado e nunca retorna zero Com fim de arquivo, yylex retorna erro

  24. Exercício 2.1: Escrever em Yacc, um analisador sintático para a seguinte gramática geradora da linguagem L abaixo: L = { (a b)ncn (d d)* | n  1} Gramática: S  a b A c D A  a b A c | ε D  d dD | ε

  25. Exercício 2.2: Escrever em Yacc, um analisador sintático para a seguinte gramática geradora da linguagem L abaixo: L = { aibj | j  i  0 } Gramática: S  A B A  a A b | ε B  b B | ε

  26. Exercício 2.3: Escrever em Yacc, um analisador sintático para a seguinte gramática geradora de expressões contendo só pares de parêntesis balanceados e nenhum outro caractere Exemplos: ( ), ( ( ) ), ( ) ( ), ( ) ( ( ) ( ( ) ) ) ( ( ) ) Gramática: S  ( A ) | S ( A ) A ε | S

  27. Programa 2.5: Yacc auxiliado por Lex • Programa em Flex no arquivo expr01.l delim [ \t\n\r] ws {delim}+ digit [0-9] num {digit}+ %% {ws} { ;} {num} {return CTE;} "+" {return OPAD;} "-" {return OPAD;} "*" {return OPMULT;} "/" {return OPMULT;} "(" {return ABPAR;} ")" {return FPAR;} "$" {return DOLAR;} . {return INVAL;} %% yylex retorna tokens declarados no programa em Yacc

  28. Programa em Yacc no arquivo expr01.y %{ #include <stdio.h> #include <stdlib.h> %} %token DOLAR %token CTE %token OPAD %token OPMULT %token ABPAR %token FPAR %token INVAL %% Tokens a serem retornados por yylex

  29. Tokens aparecem do lado direito das produções line : expr DOLAR {printf("Fim da analise\n"); return;} ; expr : expr OPAD term | term ; term : term OPMULT fat | fat ; fat : CTE | ABPAR expr FPAR ; %% #include "lex.yy.c" yylex está em lex.yy.c

  30. Executar os seguintes comandos: flex expr01.l yacc expr01.y gccy.tab.cmain.cyyerror.c -o expr01 -lfl expr01 (digitar uma expressão correta terminada por ‘$’) expr01 (digitar uma expressão incorreta terminada por ‘$’) • Usando arquivo de dados de entrada, yylex retorna zero ao ler fim de arquivo, quando criado pelo Flex • Então, dispensa-se o return da produção line

  31. Esquema de produção de um programa executável usando Yacc, com auxilio do Flex:

  32. Programa 2.6: Uso de atributos (calculadora simples) • Programa em Flex no arquivo calc01.l delim [ \t\n\r] ws {delim}+ digit [0-9] num {digit}+ %% {ws} { ;} {num} {yylval = atoi(yytext); return CTE;} "+" {yylval = MAIS; return OPAD;} "-" {yylval = MENOS; return OPAD;} "*" {yylval = VEZES; return OPMULT;} "/" {yylval = DIV; return OPMULT;} "(" {return ABPAR;} ")" {return FPAR;} "$" {return DOLAR;} . {yylval = yytext[0]; return INVAL;} %% yylval guarda o atributo de um token yylval é declarado pelo Yacc

  33. Programa em Yacc no arquivo calc01.y %{ #include <stdio.h> #include <stdlib.h> #define MAIS 1 #define MENOS 2 #define VEZES 3 #define DIV 4 %} %token DOLAR %token CTE %token OPAD %token OPMULT %token ABPAR %token FPAR %token INVAL %% Atributos para os tokens OPAD e OPMULT Por default,yylval é inteiro

  34. Não-terminais também têm atributos line : expr DOLAR { printf("valor: %d\n", $1); } ; expr : expr OPAD term { switch ($2) { case MAIS : $$ = $1 + $3; break; case MENOS : $$ = $1 - $3; break; } } | term ; Numa produção qualquer: $$ é o atributo do não-terminal do lado esquerdo $1, $2, $3 ... são atributos dos 1o, 2o, 3o ... símbolos do lado direito

  35. Rodar o executável para um arquivo com a expressão 10 * (5 + 3)$ term : term OPMULT fat { switch ($2) { case VEZES: $$ = $1 * $3; break; case DIV: $$ = $1 / $3; break; } } | fat ; fat : CTE | ABPAR expr FPAR {$$ = $2;} ; %% #include "lex.yy.c" O atributo de um terminal é fornecido por yylex, em yylval Os atributos dos não-terminais devem ser calculados nas ações Por default,a ação tomada no final de uma produção é: $$ = $1;

  36. No Yacc, a análise é bottom-up (por deslocamento e redução) • Os átomos são obtidos e deslocados para uma pilha (deslocamento) • Quando no topo da pilha se formar o lado-direito de uma produção, tem-se uma ocasião para reduzir • O analisador verifica se a redução é válida • Isso será estudado no tópico sobre Análise Bottom-Up do capítulo sobre Análise Sintática • Em caso positivo, substitui, na pilha, o lado-direito pelo lado-esquerdo da produção (redução) • Então, a ação no final da produção é executada

  37. Análise e cálculo da expressão 10 * (5 + 3)$ line : expr DOLAR expr : expr OPAD term | term term : term OPMULT fat | fat fat : CTE | ABPAR expr FPAR

  38. Análise e cálculo da expressão 10 * (5 + 3)$ line : expr DOLAR expr : expr OPAD term | term term : term OPMULT fat | fat fat : CTE | ABPAR expr FPAR

  39. Análise e cálculo da expressão 10 * (5 + 3)$ line : expr DOLAR expr : expr OPAD term | term term : term OPMULT fat | fat fat : CTE | ABPAR expr FPAR

  40. Análise e cálculo da expressão 10 * (5 + 3)$ line : expr DOLAR expr : expr OPAD term | term term : term OPMULT fat | fat fat : CTE | ABPAR expr FPAR

  41. Análise e cálculo da expressão 10 * (5 + 3)$ line : expr DOLAR expr : expr OPAD term | term term : term OPMULT fat | fat fat : CTE | ABPAR expr FPAR

  42. Análise e cálculo da expressão 10 * (5 + 3)$ line : expr DOLAR expr : expr OPAD term | term term : term OPMULT fat | fat fat : CTE | ABPAR expr FPAR

  43. Análise e cálculo da expressão 10 * (5 + 3)$ line : expr DOLAR expr : expr OPAD term | term term : term OPMULT fat | fat fat : CTE | ABPAR expr FPAR

  44. Análise e cálculo da expressão 10 * (5 + 3)$ line : expr DOLAR expr : expr OPAD term | term term : term OPMULT fat | fat fat : CTE | ABPAR expr FPAR Por que não reduz segundo E → T ? A resposta virá no estudo de Análise Bottom-Up

  45. Análise e cálculo da expressão 10 * (5 + 3)$ line : expr DOLAR expr : expr OPAD term | term term : term OPMULT fat | fat fat : CTE | ABPAR expr FPAR

  46. Análise e cálculo da expressão 10 * (5 + 3)$ line : expr DOLAR expr : expr OPAD term | term term : term OPMULT fat | fat fat : CTE | ABPAR expr FPAR

  47. Análise e cálculo da expressão 10 * (5 + 3)$ line : expr DOLAR expr : expr OPAD term | term term : term OPMULT fat | fat fat : CTE | ABPAR expr FPAR

  48. Análise e cálculo da expressão 10 * (5 + 3)$ line : expr DOLAR expr : expr OPAD term | term term : term OPMULT fat | fat fat : CTE | ABPAR expr FPAR

  49. Análise e cálculo da expressão 10 * (5 + 3)$ line : expr DOLAR expr : expr OPAD term | term term : term OPMULT fat | fat fat : CTE | ABPAR expr FPAR

  50. Análise e cálculo da expressão 10 * (5 + 3)$ line : expr DOLAR expr : expr OPAD term | term term : term OPMULT fat | fat fat : CTE | ABPAR expr FPAR

More Related