A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

5.6 – Complementos de Yacc 5.6.1 – Usando Yacc com gramáticas ambíguas Gramáticas ambíguas causam conflitos durante a construção de um analisador sintático.

Apresentações semelhantes


Apresentação em tema: "5.6 – Complementos de Yacc 5.6.1 – Usando Yacc com gramáticas ambíguas Gramáticas ambíguas causam conflitos durante a construção de um analisador sintático."— Transcrição da apresentação:

1 5.6 – Complementos de Yacc – Usando Yacc com gramáticas ambíguas Gramáticas ambíguas causam conflitos durante a construção de um analisador sintático pelo Yacc Gramáticas ambíguas causam conflitos durante a construção de um analisador sintático pelo Yacc Os tipos de conflitos são: Os tipos de conflitos são: Deslocamento-redução: o analisador tanto pode deslocar um átomo para a pilha, como pode reduzir o topo da pilha por uma produção Deslocamento-redução: o analisador tanto pode deslocar um átomo para a pilha, como pode reduzir o topo da pilha por uma produção Redução-redução: o analisador pode usar mais de uma produção para reduzir o topo da pilha Redução-redução: o analisador pode usar mais de uma produção para reduzir o topo da pilha

2 Há regras para a solução de ambiguidades Há regras para a solução de ambiguidades Yacc gera analisadores mais eficientes para gramáticas ambíguas do que para gramáticas não ambíguas Yacc gera analisadores mais eficientes para gramáticas ambíguas do que para gramáticas não ambíguas

3 Exemplo 5.34: Programa para análise da seguinte gramática ambígua para cálculo de expressões: Exemplo 5.34: Programa para análise da seguinte gramática ambígua para cálculo de expressões: E E + E | E - E | E * E | E / E | ( E ) | - E | num Com a seguinte precedência de operadores: * e / tem precedência sobre + e - * e / tem precedência sobre + e - Menos-unário tem precedência sobre * e / Menos-unário tem precedência sobre * e / O programa deve calcular expressões de valor real

4 E E + E | E - E | E * E | E / E | ( E ) | - E | num A gramática é ambígua pois para a sentença * 3 tem duas árvores sintáticas A gramática é ambígua pois para a sentença * 3 tem duas árvores sintáticas E E+E 5E*E 83 E E*E E+E3 58

5 Programa com regras para eliminação de ambiguidades e comandos de escrita para mostrar as reduções feitas: %{ #include #include #define YYSTYPE double %} %token NUM %left'+' '-' %left '*' '/' %rightMENUN % Declarações para solução de ambiguidades

6 line:expr '$' {printf ( "Valor: %g\n", $1); return 0;} ; expr:expr '+' expr {$$ = $1 + $3; printf ("Regra1: %g = %g + %g\n", $$, $1, $3);} |expr '-' expr {$$ = $1 - $3; printf ("Regra2: %g = %g - %g\n", $$, $1, $3);} |expr '*' expr {$$ = $1 * $3; printf ("Regra3: %g = %g * %g\n", $$, $1, $3);}

7 |expr '/' expr {$$ = $1 / $3; printf ("Regra4: %g = %g / %g\n", $$, $1, $3);} |'(' expr ')' {$$ = $2; printf ("Regra5: %g = ( %g )\n", $$, $2);} | '-' expr%prec MENUN {$$ = -$2; printf ("Regra6: %g = - %g \n", $$, $2);} |NUM {$$ = $1; printf ("Regra7: %g = %g\n", $$, $1);} ;% Dispositivo para solução de ambiguidades

8 yylex () { int c; do c = getchar (); while (c == ' '); if (c == '.' || isdigit (c)) { ungetc (c, stdin); scanf ("%lf", &yylval) ; return (NUM); } return c; }

9 A seguir, são descritas regras e dispositivos de programação do Yacc para solucionar ambiguidades A seguir, são descritas regras e dispositivos de programação do Yacc para solucionar ambiguidades Por default, o conflito redução-redução é resolvido em favor da produção que aparece primeiro na lista de produções Por default, o conflito redução-redução é resolvido em favor da produção que aparece primeiro na lista de produções Por default, o conflito deslocamento-redução é resolvido em favor do deslocamento Por default, o conflito deslocamento-redução é resolvido em favor do deslocamento

10 No exemplo anterior, não fosse pelas regras de precedência a serem comentadas logo a seguir, a forma sentencial: No exemplo anterior, não fosse pelas regras de precedência a serem comentadas logo a seguir, a forma sentencial: provocaria o deslocamento do + para o topo da pilha A soma seria realizada antes da multiplicação A soma seria realizada antes da multiplicaçãoPilhaEntrada expr * expr + 3

11 Nas declarações do programa Yacc, pode-se atribuir precedências e associatividades aos terminais da gramática; sejam as declarações: Nas declarações do programa Yacc, pode-se atribuir precedências e associatividades aos terminais da gramática; sejam as declarações: %left'+' '-' %left '*' '/' %right '~' (menos unário) '+' e '-' têm mesma precedência '+' e '-' têm mesma precedência '*' e '/' têm mesma precedência '*' e '/' têm mesma precedência A precedência cresce de cima para baixo A precedência cresce de cima para baixo No programa aparece: %right MENUN No programa aparece: %right MENUN provocaria o deslocamento do + para o topo da pilha A soma seria realizada antes da multiplicação Diferentes

12 Cada produção em Yacc também tem associada a si uma precedência e uma associatividade: Cada produção em Yacc também tem associada a si uma precedência e uma associatividade: Por default, é a precedência e associatividade de seu terminal mais a direita Por default, é a precedência e associatividade de seu terminal mais a direita Exemplo: a precedência e associatividade da produção A a B c D e F G será a de e Exemplo: a precedência e associatividade da produção A a B c D e F G será a de e Na decisão (deslocar a) ou (reduzir por A ) haverá deslocamento se a tiver maior precedência que A, e vice-versa Na decisão (deslocar a) ou (reduzir por A ) haverá deslocamento se a tiver maior precedência que A, e vice-versa

13 Na forma sentencial: Na forma sentencial: haverá redução, pois a produção expr * expr tem a precedência de * que é maior que a de + PilhaEntrada expr * expr + 3

14 Na declaração %left -, o operador - é associativo à esquerda; a seguinte forma sentencial causa redução: Na declaração %left -, o operador - é associativo à esquerda; a seguinte forma sentencial causa redução: A expressão = 2-1 = 1 A expressão = 2-1 = 1 Se fosse %right -, causaria deslocamento Se fosse %right -, causaria deslocamento O cálculo de seria = 5-2 = 3 O cálculo de seria = 5-2 = 3PilhaEntrada expr - expr - 3

15 Pode-se também forçar uma produção a ter uma determinada precedência Pode-se também forçar uma produção a ter uma determinada precedência O programa visto apresenta: O programa visto apresenta: %left'+' '-' %left '*' '/' %rightMENUN expr | '-' expr %prec MENUN Esta produção é forçada a ter precedência maior que +, -, *, / Esta produção é forçada a ter precedência maior que +, -, *, /

16 Exemplo: o programa visto produziu os seguintes resultados experimentais: Exemplo: o programa visto produziu os seguintes resultados experimentais: 1) Entrada: 5-2-2$ Regra7: 5 = 5 Regra7: 2 = 2 Regra2: 3 = Regra7: 2 = 2 Regra2: 1 = Valor: 1 2) Trocando %left '+' '-' por %right '+' '-': Entrada: 5-2-2$ Regra7: 5 = 5 Regra7: 2 = 2 Regra2: 0 = Regra2: 5 = Valor: 5

17 Exemplo: o programa visto produziu os seguintes resultados experimentais: Exemplo: o programa visto produziu os seguintes resultados experimentais: 3) Destrocando: Entrada: 5*-(3+2)$ Regra7: 5 = 5 Regra7: 3 = 3 Regra7: 2 = 2 Regra1: 5 = Regra5: 5 = ( 5 ) Regra6: -5 = - 5 Regra3: -25 = 5 * -5 Valor: -25 4) Entrada: -3+8$ Regra7: 3 = 3 Regra6: -3 = - 3 Regra7: 8 = 8 Regra1: 5 = Valor: 5 5) Trocando%rightMENUN %left '+' '-' %left '*' '/' Entrada: -3+8$ Regra7: 3 = 3 Regra7: 8 = 8 Regra1: 11 = Regra6: -11 = - 11 Valor: -11

18 5.6.2 – Notificação e tratamento de erros no Yacc Em Yacc, o tratamento de erros pode ser feito usando produções de erros entre as produções da gramática Em Yacc, o tratamento de erros pode ser feito usando produções de erros entre as produções da gramática Primeiramente deve-se decidir quais não-terminais da gramática terão essas produções Primeiramente deve-se decidir quais não-terminais da gramática terão essas produções Esses podem ser não-terminais que possuam átomos em suas produções normais, para que mensagens notificando a falta deles possam ser emitidas Esses podem ser não-terminais que possuam átomos em suas produções normais, para que mensagens notificando a falta deles possam ser emitidas Ou então outros estratégicos geradores de expressões, comandos, sub-programas, etc. Ou então outros estratégicos geradores de expressões, comandos, sub-programas, etc.

19 Seja A um não-terminal escolhido; introduz-se, na gramática, produções da forma A error Seja A um não-terminal escolhido; introduz-se, na gramática, produções da forma A error e são cadeias de terminais e ou não-terminais, vazias ou não e são cadeias de terminais e ou não-terminais, vazias ou não error é uma palavra reservada do Yacc (um token especial) error é uma palavra reservada do Yacc (um token especial) Na montagem do analisador, as produções de erros são tratadas como produções normais da gramática Na montagem do analisador, as produções de erros são tratadas como produções normais da gramática No entanto, quando o analisador produzido encontra um erro, a manipulação dos estados e da pilha é diferente do normal No entanto, quando o analisador produzido encontra um erro, a manipulação dos estados e da pilha é diferente do normal

20 Encontrando um erro, desempilha-se símbolos e estados, até encontrar um estado no topo da pilha, cujo conjunto de itens contenha um item do tipo A. error Encontrando um erro, desempilha-se símbolos e estados, até encontrar um estado no topo da pilha, cujo conjunto de itens contenha um item do tipo A. error Programa analisador LR Entrada 0 Pilha Saída Tabelas LR erro Estado com item do tipo A. error

21 Encontrando um erro, desempilha-se símbolos e estados, até encontrar um estado no topo da pilha, cujo conjunto de itens contenha um item do tipo A. error Encontrando um erro, desempilha-se símbolos e estados, até encontrar um estado no topo da pilha, cujo conjunto de itens contenha um item do tipo A. error Programa analisador LR Entrada 0 Pilha Saída Tabelas LR erro Estado com item do tipo A. error

22 Desloca-se o átomo fictício error para o topo da pilha, como se tivesse visto um erro na entrada Programa analisador LR Entrada 0 Pilha Saída Tabelas LR erro Estado com item do tipo A. error err or Estado com item do tipo A error.

23 Se for vazia, reduz-se imediatamente para A e uma eventual ação semântica pode ocorrer (notificação e tratamento de erros programado) Programa analisador LR Entrada 0 Pilha Saída Tabelas LR erro Estado com item do tipo A. error err or Estado com item do tipo A error.

24 Se for vazia, reduz-se imediatamente para A e uma eventual ação semântica pode ocorrer (notificação e tratamento de erros programado) Programa analisador LR Entrada 0 Pilha Saída A Tabelas LR erro

25 Se não for vazia: Programa analisador LR Entrada 0 Pilha Saída A Tabelas LR erro

26 Se não for vazia: o analisador observa os próximos símbolos de entrada, até encontrar uma sub-cadeia redutível para o analisador observa os próximos símbolos de entrada, até encontrar uma sub-cadeia redutível para Programa analisador LR Entrada 0 Pilha Saída Tabelas LR erro Estado com item do tipo A. error err or Estado com item do tipo A error. redutível para

27 Essa sub-cadeia é deslocada para a pilha provocando a redução para A Programa analisador LR Entrada 0 Pilha Saída Tabelas LR erro Estado com item do tipo A. error err or Estado com item do tipo A error. redutível para

28 Essa sub-cadeia é deslocada para a pilha provocando a redução para A Programa analisador LR Entrada 0 Pilha Saída A Tabelas LR erro redutível para O caso mais comum é o de ser uma sequência de terminais

29 Também uma eventual ação semântica pode ocorrer (notificação e tratamento de erros programado) Programa analisador LR Entrada 0 Pilha Saída A Tabelas LR erro redutível para O caso mais comum é o de ser uma sequência de terminais

30 O analisador deixa o estado de erro e volta ao normal, através da execução de uma macro: yyerrok O analisador deixa o estado de erro e volta ao normal, através da execução de uma macro: yyerrok O exemplo a seguir é experimental e relativamente simples: O exemplo a seguir é experimental e relativamente simples: Mostra os casos de e serem vazios e compostos de um e dois terminais Mostra os casos de e serem vazios e compostos de um e dois terminais Mostra também o uso da macro yyerrok Mostra também o uso da macro yyerrok A literatura (livros, Internet, etc.) apresenta outros dispositivos para recuperação de erros no Yacc A literatura (livros, Internet, etc.) apresenta outros dispositivos para recuperação de erros no Yacc

31 Exemplo: programa para a seguinte gramática: Exemplo: programa para a seguinte gramática: Função : Cabeçalho Declarações Cabeçalho : ID ( ) Declarações : { ListDecl } ListDecl : ε | ListDecl Declaração Declaração : Tipo ListElemDecl ; Tipo : INT | FLOAT | CHAR | BOOL ListElemDecl : ElemDecl | ListElemDecl, ElemDecl ElemDecl : ID

32 Analisador léxico: delim[ \t\n\r] ws{delim}+ letra[A-Za-z] digito[0-9] id{letra}({letra}|{digito})* % {ws}{ ;} bool{return BOOL;} char{return CHAR;} float{return FLOAT;} int{return INT;} {id}{strcpy (yylval.cadeia, yytext); return ID;} "("{return ABPAR;} ")"{return FPAR;} "{"{return ABCHAV;} "}"{return FCHAV;} ";"{return PVIRG;} ","{return VIRG;}.{yylval.carac = yytext[0]; return INVAL;} %

33 Analisador sintático: %{ #include #include void Esperado (char *); %} %union { char cadeia[50]; char carac; }

34 %tokenBOOL %tokenCHAR %tokenFLOAT %tokenINT %token ID %tokenABPAR %tokenFPAR %tokenABCHAV %tokenFCHAV %tokenPVIRG %tokenVIRG %token INVAL %

35 Funcao: Cabecalho Declaracoes ; Cabecalho : ID ABPAR {printf ("%s \( ", $1);} FPAR {printf (")\n");} | ID error {printf ("%s ", $1); Esperado ("(");} Esperado ("(");} FPAR {yyerrok; printf (")\n");} FPAR {yyerrok; printf (")\n");} | ID error {printf ("%s\n", $1); Esperado ("( )"); yyerrok;} Esperado ("( )"); yyerrok;} | error {Esperado ("Identificador");} ABPAR FPAR {yyerrok; printf ("() ");} ABPAR FPAR {yyerrok; printf ("() ");} | ID ABPAR error {printf ("%s (\n", $1); Esperado (")"); yyerrok;} ;

36 Declaracoes : ABCHAV {printf ("\{\n");} ListDecl FCHAV {printf ("}\n");} FCHAV {printf ("}\n");}; ListDecl: | ListDecl Declaracao ; Declaracao: Tipo ListElemDecl PVIRG {printf ("; \n");} {printf ("; \n");} | Tipo ListElemDecl error PVIRG {Esperado("';' "); yyerrok;} ;

37 Tipo : INT {printf ("int ");} | FLOAT {printf ("float ");} | CHAR {printf ("char ");} | BOOL {printf ("bool ");} ; ListElemDecl : ElemDecl | ListElemDecl VIRG {printf (", ");} ElemDecl ; ElemDecl : ID {printf ("%s ", $1);} | error ID {Esperado("Identificador"); yyerrok;} {Esperado("Identificador"); yyerrok;};

38 % #include "lex.yy.c" void Esperado (char *s) { printf ("\n***** Esperado: %s \n", s); } A seguir alguns testes e seus resultados A seguir alguns testes e seus resultados

39 1) Programa para teste: (sem erros) main ( ) { int i, j, k, fat; bool m, n; float x; char a; } Resultado: main ( ) { int i, j, k, fat ; bool m, n ; float x ; char a ; }

40 2) Programa para teste: ( ) ( ){ int i, j, k, fat; bool m, n; float x; char a; } Resultado: syntax error ***** Esperado: Identificador () { int i, j, k, fat ; bool m, n ; float x ; char a ; }

41 3) Programa para teste: abc ) { int i, j, k, fat; bool m, n; float x; char a; } Resultado: syntax error abc ***** Esperado: ( ) { int i, j, k, fat ; bool m, n ; float x ; char a ; }

42 4) Programa para teste: abc ( { int i, j, k, fat; bool m, n; float x; char a; } Resultado: syntax error abc ( ***** Esperado: ) { int i, j, k, fat ; bool m, n ; float x ; char a ; }

43 5) Programa para teste: abc{ int i, j, k, fat; bool m, n; float x; char a; } Resultado: syntax error abc ***** Esperado: ( ) { int i, j, k, fat ; bool m, n ; float x ; char a ; }

44 6) Programa para teste: abc ( ) { int bool i, j, k, fat; bool m, n float x; char a; } Resultado: abc ( ) { int syntax error ***** Esperado: Identificador, j, k, fat ; bool m, n syntax error ***** Esperado: ';' char a ; }


Carregar ppt "5.6 – Complementos de Yacc 5.6.1 – Usando Yacc com gramáticas ambíguas Gramáticas ambíguas causam conflitos durante a construção de um analisador sintático."

Apresentações semelhantes


Anúncios Google