5.6 – Complementos de Yacc 5.6.1 – Usando Yacc com gramáticas ambíguas Gramáticas ambíguas...

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

Transcript of 5.6 – Complementos de Yacc 5.6.1 – Usando Yacc com gramáticas ambíguas Gramáticas ambíguas...

Page 1: 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.

5.6 – Complementos de 5.6 – Complementos de YaccYacc

5.6.1 – Usando Yacc com gramáticas 5.6.1 – Usando Yacc com gramáticas ambíguasambíguas

Gramáticas ambíguasGramáticas ambíguas causam causam conflitosconflitos durante a durante a construção de um analisador sintático pelo construção de um analisador sintático pelo YaccYacc

Os Os tipostipos de conflitos são: de conflitos são:

Deslocamento-redução: Deslocamento-redução: o analisador tanto o analisador tanto pode pode deslocardeslocar um átomo para a pilha, como um átomo para a pilha, como pode pode reduzirreduzir o topo da pilha por uma o topo da pilha por uma produçãoprodução

Redução-redução: Redução-redução: o analisador pode usar o analisador pode usar mais mais de uma produçãode uma produção para para reduzirreduzir o topo da pilha o topo da pilha

Page 2: 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.

Há Há regrasregras para a solução de para a solução de ambiguidades ambiguidades

Yacc Yacc gera analisadores mais gera analisadores mais eficientes eficientes para para gramáticas ambíguasgramáticas ambíguas do que para do que para gramáticas gramáticas não ambíguasnão ambíguas

Page 3: 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.

Exemplo 5.34:Exemplo 5.34: Programa para análise da Programa para análise da seguinte seguinte gramática ambígua gramática ambígua para cálculo de para cálculo de expressões:expressões:

E E E + E | E - E | E * E | E / E | ( E ) | - E E + E | E - E | E * E | E / E | ( E ) | - E

| num| num

Com a seguinte Com a seguinte precedência de operadoresprecedência de operadores::

‘‘*’*’ e e ‘/’‘/’ tem precedência sobre tem precedência sobre ‘+’‘+’ e e ‘-’‘-’ Menos-unárioMenos-unário tem precedência sobre tem precedência sobre ‘*’‘*’ e e ‘/’‘/’

O programa deve calcular expressões de valor realO programa deve calcular expressões de valor real

Page 4: 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.

E E E + E | E - E | E * E | E / E | ( E ) | - E + E | E - E | E * E | E / E | ( E ) | - E E

| num| num

A gramática é A gramática é ambíguaambígua pois para a sentença pois para a sentença 5 5 + 8 * 3+ 8 * 3 tem duas árvores sintáticas tem duas árvores sintáticas

E

E + E

5 E * E

8 3

E

E * E

E + E 3

5 8

Page 5: 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.

Programa com regras para Programa com regras para eliminação de eliminação de ambiguidadesambiguidades e e comandos de escritacomandos de escrita para para mostrar as mostrar as reduçõesreduções feitas: feitas:

%{%{

#include#include <stdio.h><stdio.h>

#include#include <ctype.h><ctype.h>

#define #define YYSTYPEYYSTYPE double double

%}%}

%token%token NUMNUM

%left%left '+' '-''+' '-'

%left%left '*' '/''*' '/'

%right%right MENUNMENUN

%%%%

Declarações para solução de ambiguidades

Page 6: 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.

lineline :: expr expr '$''$'

{printf ( "Valor: %g\n", {printf ( "Valor: %g\n", $1$1););

returnreturn 0;} 0;}

;;

exprexpr :: expr '+' exprexpr '+' expr

{{$$$$ = = $1$1 + + $3$3;;

printf ("Regra1: %g = %g + %g\n", printf ("Regra1: %g = %g + %g\n", $$$$, , $1$1, , $3$3);});}

|| expr '-' exprexpr '-' expr

{{$$$$ = = $1$1 - - $3$3;;

printf ("Regra2: %g = %g - %g\n", printf ("Regra2: %g = %g - %g\n", $$$$, , $1$1, , $3$3);});}

|| expr '*' exprexpr '*' expr

{{$$$$ = = $1$1 * * $3$3;;

printf ("Regra3: %g = %g * %g\n", printf ("Regra3: %g = %g * %g\n", $$$$, , $1$1, , $3$3);});}

Page 7: 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.

|| expr '/' exprexpr '/' expr

{{$$$$ = = $1$1 / / $3$3;;

printf ("Regra4: %g = %g / %g\n", printf ("Regra4: %g = %g / %g\n", $$$$, , $1$1, , $3$3);});}

|| '(' expr ')''(' expr ')'

{{$$ $$ = = $2$2; ;

printf ("Regra5: %g = ( %g )\n", printf ("Regra5: %g = ( %g )\n", $$$$, , $2$2);});}

| | '-' expr'-' expr %prec MENUN%prec MENUN

{{$$$$ = - = -$2$2;;

printf ("Regra6: %g = - %g \n", printf ("Regra6: %g = - %g \n", $$$$, , $2$2);});}

|| NUMNUM

{{$$$$ = = $1$1; printf ("Regra7: %g = %g\n", ; printf ("Regra7: %g = %g\n", $$$$, , $1$1);});}

;;

%%%%

Dispositivo para solução de ambiguidades

Page 8: 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.

yylex () {yylex () {

int c;int c;

dodo

c = getchar ();c = getchar ();

while (c == ' ');while (c == ' ');

if (c == '.' || isdigit (c)) {if (c == '.' || isdigit (c)) {

ungetc (c, stdin);ungetc (c, stdin);

scanf ("%lf", &yylval) ;scanf ("%lf", &yylval) ;

return (NUM);return (NUM);

}}

return c;return c;

}}

Page 9: 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.

A seguir, são descritas A seguir, são descritas regras e dispositivosregras e dispositivos de programação do de programação do YaccYacc para solucionar para solucionar ambiguidadesambiguidades

Por Por defaultdefault, o conflito , o conflito redução-reduçãoredução-redução é é resolvido em favor da resolvido em favor da produção que aparece produção que aparece primeiroprimeiro na lista de produções na lista de produções

Por Por defaultdefault, o conflito , o conflito deslocamento-deslocamento-reduçãoredução é resolvido em favor do é resolvido em favor do deslocamentodeslocamento

Page 10: 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.

No exemplo anterior, não fosse pelas No exemplo anterior, não fosse pelas regras regras de precedênciade precedência a serem comentadas logo a a serem comentadas logo a seguir, a forma sentencial:seguir, a forma sentencial:

provocaria o deslocamento do ‘+’ para o topo provocaria o deslocamento do ‘+’ para o topo da pilhada pilha

A soma seria realizada antes da multiplicaçãoA soma seria realizada antes da multiplicação

PilhaPilha EntradaEntrada

expr ‘*’ expr ‘*’ exprexpr

‘‘+’ 3+’ 3

Page 11: 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.

Nas declarações do programa Nas declarações do programa YaccYacc, pode-se atribuir , pode-se atribuir precedênciasprecedências e e associatividadesassociatividades aos terminais da gramática; sejam as aos terminais da gramática; sejam as declarações:declarações:

%left%left '+' '-''+' '-'

%left%left '*' '/''*' '/'

%right%right '~' '~' (menos unário) (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 baixoA precedência cresce de cima para baixo

No programa aparece: No programa aparece: %right%right MENUN MENUN

provocaria o deslocamento do ‘+’ para o topo da pilhaprovocaria o deslocamento do ‘+’ para o topo da pilha

A soma seria realizada antes da multiplicaçãoA soma seria realizada antes da multiplicação

Diferentes

Page 12: 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.

Cada produção em Cada produção em YaccYacc também tem também tem associada a si uma associada a si uma precedênciaprecedência e uma e uma associatividadeassociatividade::

Por default, é a precedência e Por default, é a precedência e associatividade de associatividade de seu terminal mais a seu terminal mais a direitadireita

Exemplo: a precedência e associatividade Exemplo: a precedência e associatividade da produção da produção A A a B c D e F G a B c D e F G será a será a de de ‘e’‘e’

Na decisão (deslocar Na decisão (deslocar ‘a’‘a’) ou (reduzir por ) ou (reduzir por AA) haverá deslocamento se ) haverá deslocamento se ‘a’‘a’ tiver tiver maior precedência que maior precedência que AA, e vice-versa, e vice-versa

Page 13: 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.

Na forma sentencial:Na forma sentencial:

haverá redução, pois a produção haverá redução, pois a produção

expr ‘*’ expr expr ‘*’ expr tem a precedência tem a precedência de de ‘*’‘*’

que é maior que a de que é maior que a de ‘+’‘+’

PilhaPilha EntradaEntrada

expr ‘*’ exprexpr ‘*’ expr ‘‘+’ 3+’ 3

Page 14: 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.

Na declaração Na declaração %left ‘-’%left ‘-’, o operador , o operador ‘-’‘-’ é é associativo à esquerdaassociativo à esquerda; a seguinte forma ; a seguinte forma sentencial causa redução:sentencial causa redução:

A expressão A expressão 5-3-1 = 2-1 = 15-3-1 = 2-1 = 1

Se fosse Se fosse %right ‘-’%right ‘-’, causaria deslocamento, causaria deslocamento

O cálculo de O cálculo de 5-3-15-3-1 seria seria 5-3-1 = 5-2 = 35-3-1 = 5-2 = 3

PilhaPilha EntradaEntrada

expr ‘-’ exprexpr ‘-’ expr ‘‘-’ 3-’ 3

Page 15: 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.

Pode-se também Pode-se também forçar uma produçãoforçar uma produção a ter a ter uma determinada uma determinada precedênciaprecedência

O programa visto apresenta:O programa visto apresenta:

%left%left '+' '-''+' '-'

%left%left '*' '/''*' '/'

%right%right MENUNMENUN

- - - - - - - - - - - - - - - -

expr expr | '-' expr | '-' expr %prec MENUN%prec MENUN

Esta produção é forçada a ter precedência Esta produção é forçada a ter precedência maior que maior que ‘+’‘+’, , ‘-’‘-’, , ‘*’‘*’, , ‘/’‘/’

Page 16: 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.

Exemplo: Exemplo: o programa visto produziu os o programa visto produziu os seguintes resultados experimentais:seguintes resultados experimentais:

1) Entrada: 5-2-2$Regra7: 5 = 5Regra7: 2 = 2Regra2: 3 = 5 - 2Regra7: 2 = 2Regra2: 1 = 3 - 2Valor: 1

2) Trocando %left '+' '-' por %right '+' '-': Entrada: 5-2-2$Regra7: 5 = 5Regra7: 2 = 2Regra7: 2 = 2Regra2: 0 = 2 - 2Regra2: 5 = 5 - 0Valor: 5

Page 17: 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.

Exemplo: Exemplo: o programa visto produziu os o programa visto produziu os seguintes resultados experimentais:seguintes resultados experimentais:

3) Destrocando:

Entrada: 5*-(3+2)$Regra7: 5 = 5Regra7: 3 = 3Regra7: 2 = 2Regra1: 5 = 3 + 2Regra5: 5 = ( 5 )Regra6: -5 = - 5Regra3: -25 = 5 * -5Valor: -25

4) Entrada: -3+8$Regra7: 3 = 3Regra6: -3 = - 3Regra7: 8 = 8Regra1: 5 = -3 + 8Valor: 5

5) Trocando %rightMENUN

%left '+' '-'

%left '*' '/'

Entrada: -3+8$Regra7: 3 = 3Regra7: 8 = 8Regra1: 11 = 3 + 8Regra6: -11 = - 11Valor: -11

Page 18: 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.

5.6.2 – Notificação e tratamento de erros 5.6.2 – Notificação e tratamento de erros no Yaccno Yacc

Em Em YaccYacc, o tratamento de , o tratamento de erroserros pode ser feito pode ser feito usando usando produçõesproduções de errosde erros entre as produções entre as produções da gramáticada gramática

Primeiramente deve-se decidir Primeiramente deve-se decidir quais não-quais não-terminaisterminais da gramática da gramática terão essas produçõesterão essas produções

Esses podem ser Esses podem ser não-terminaisnão-terminais que possuam que possuam átomosátomos em suas produções normais, para que em suas produções normais, para que mensagensmensagens notificando a notificando a faltafalta deles possam ser deles possam ser emitidasemitidas

Ou então outros Ou então outros estratégicosestratégicos geradores de geradores de expressões, comandos, sub-programas, etc.expressões, comandos, sub-programas, etc.

Page 19: 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.

Seja Seja AA um não-terminal um não-terminal escolhidoescolhido; introduz-se, na ; introduz-se, na gramática, produções da forma gramática, produções da forma A A error error

e e são são cadeiascadeias de terminais e ou não-terminais, de terminais e ou não-terminais, vaziasvazias ou não ou não

errorerror é uma palavra é uma palavra reservadareservada do do YaccYacc (um (um token token especial)especial)

Na Na montagemmontagem do analisador, as produções de do analisador, as produções de erroserros são tratadas como são tratadas como produções normaisproduções normais da da gramáticagramática

No entanto, quando o analisador produzido No entanto, quando o analisador produzido encontra um erroencontra um erro, a manipulação dos , a manipulação dos estadosestados e e da da pilhapilha é é diferentediferente do normal do normal

Page 20: 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.

Encontrando um erroEncontrando um erro, , desempilha-sedesempilha-se símbolos e estados, até encontrar um símbolos e estados, até encontrar um estadoestado no topo da pilha, cujo no topo da pilha, cujo conjunto de itensconjunto de itens contenha um item do tipo contenha um item do tipo A A . error . error

Programa

analisador LR

Entrada

0Pilha

Saída

Tabelas LR

erro

Estado com item do tipo A . error

Page 21: 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.

Encontrando um erroEncontrando um erro, , desempilha-sedesempilha-se símbolos e estados, até encontrar um símbolos e estados, até encontrar um estadoestado no topo da pilha, cujo no topo da pilha, cujo conjunto de itensconjunto de itens contenha um item do tipo contenha um item do tipo A A . error . error

Programa

analisador LR

Entrada

0Pilha

Saída

Tabelas LR

erro

Estado com item do tipo A . error

Page 22: 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.

Desloca-seDesloca-se o átomo fictício o átomo fictício error error para o para o topo topo da pilha, como se tivesse visto um da pilha, como se tivesse visto um erroerro na na entradaentrada

Programa

analisador LR

Entrada

0Pilha

Saída

Tabelas LR

erro

Estado com item do tipo A . error

error

Estado com item do tipo A error .

Page 23: 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.

Se Se for for vaziavazia, , reduz-sereduz-se imediatamente para imediatamente para AA e e uma eventual uma eventual ação semânticaação semântica pode ocorrer pode ocorrer (notificação e tratamento de erros (notificação e tratamento de erros programadoprogramado))

Programa

analisador LR

Entrada

0Pilha

Saída

Tabelas LR

erro

Estado com item do tipo A . error

error

Estado com item do tipo A error .

Page 24: 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.

Se Se for for vaziavazia, , reduz-sereduz-se imediatamente para imediatamente para AA e e uma eventual uma eventual ação semânticaação semântica pode ocorrer pode ocorrer (notificação e tratamento de erros (notificação e tratamento de erros programadoprogramado))

Programa

analisador LR

Entrada

0Pilha

Saída

A

Tabelas LR

erro

Page 25: 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.

Se Se não for não for vaziavazia::

Programa

analisador LR

Entrada

0Pilha

Saída

A

Tabelas LR

erro

Page 26: 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.

Se Se não for não for vaziavazia::

o analisador observa os o analisador observa os próximos símbolospróximos símbolos de entrada, até encontrar uma de entrada, até encontrar uma sub-cadeiasub-cadeia redutívelredutível para para

Programa

analisador LR

Entrada

0Pilha

Saída

Tabelas LR

erro

Estado com item do tipo A . error

error

Estado com item do tipo A error .

redutível

para

Page 27: 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.

Essa sub-cadeia é deslocada para a pilha Essa sub-cadeia é deslocada para a pilha provocando a redução para provocando a redução para AA

Programa

analisador LR

Entrada

0Pilha

Saída

Tabelas LR

erro

Estado com item do tipo A . error

error

Estado com item do tipo A error .

redutível

para

Page 28: 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.

Essa sub-cadeia é deslocada para a pilha Essa sub-cadeia é deslocada para a pilha provocando a redução para provocando a redução para AA

Programa

analisador LR

Entrada

0Pilha

Saída

A

Tabelas LR

erro

redutível

para O caso mais comum é o de ser uma sequência de terminais

Page 29: 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.

Também uma eventual Também uma eventual ação semânticaação semântica pode pode ocorrer (notificação e tratamento de erros ocorrer (notificação e tratamento de erros programadoprogramado))

Programa

analisador LR

Entrada

0Pilha

Saída

A

Tabelas LR

erro

redutível

para O caso mais comum é o de ser uma sequência de terminais

Page 30: 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.

O analisador deixa o estado de erro e O analisador deixa o estado de erro e volta ao volta ao normalnormal, através da execução de uma macro: , através da execução de uma macro: yyerrokyyerrok

O exemplo a seguir é O exemplo a seguir é experimentalexperimental e e relativamente relativamente simplessimples::

Mostra os casos de Mostra os casos de e e serem vazios e serem vazios e compostos de um e dois terminaiscompostos de um e dois terminais

Mostra também o uso da macro Mostra também o uso da macro yyerrokyyerrok

A literatura (livros, Internet, etc.) apresenta A literatura (livros, Internet, etc.) apresenta outros dispositivos para recuperação de erros no outros dispositivos para recuperação de erros no YaccYacc

Page 31: 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.

Exemplo:Exemplo: programa para a seguinte programa para a seguinte gramática:gramática:

Função : Cabeçalho DeclaraçõesFunção : Cabeçalho Declarações

Cabeçalho : ID ( ) Cabeçalho : ID ( )

Declarações : { ListDecl }Declarações : { ListDecl }

ListDecl : ListDecl : εε | ListDecl Declaração | ListDecl Declaração

Declaração : Tipo ListElemDecl ;Declaração : Tipo ListElemDecl ;

Tipo : INT | FLOAT | CHAR | BOOLTipo : INT | FLOAT | CHAR | BOOL

ListElemDecl : ElemDecl ListElemDecl : ElemDecl

| ListElemDecl , ElemDecl| ListElemDecl , ElemDecl

ElemDecl : IDElemDecl : ID

Page 32: 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.

Analisador léxico:Analisador léxico:delimdelim [ \t\n\r][ \t\n\r]wsws {delim}+{delim}+letraletra [A-Za-z][A-Za-z]digitodigito [0-9][0-9]idid {letra}({letra}|{digito})*{letra}({letra}|{digito})*%%%%{ws}{ws} { ;}{ ;}boolbool {return BOOL;}{return BOOL;}charchar {return CHAR;}{return CHAR;}floatfloat {return FLOAT;}{return FLOAT;}intint {return INT;}{return INT;}{id}{id} {strcpy (yylval.cadeia, yytext); return ID;}{strcpy (yylval.cadeia, yytext); return ID;}"(""(" {return ABPAR;}{return ABPAR;}")"")" {return FPAR;}{return FPAR;}"{""{" {return ABCHAV;}{return ABCHAV;}"}""}" {return FCHAV;}{return FCHAV;}";"";" {return PVIRG;}{return PVIRG;}",""," {return VIRG;}{return VIRG;}.. {yylval.carac = yytext[0]; return INVAL;}{yylval.carac = yytext[0]; return INVAL;}%%%%

Page 33: 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.

Analisador sintático:Analisador sintático:

%{%{

#include <string.h>#include <string.h>

#include <stdio.h>#include <stdio.h>

#include <stdlib.h>#include <stdlib.h>

void Esperado (char *);void Esperado (char *);

%}%}

%union {%union {

char cadeia[50];char cadeia[50];

char carac;char carac;

}}

Page 34: 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.

%token%token BOOLBOOL

%token%token CHARCHAR

%token%token FLOATFLOAT

%token%token INTINT

%token%token <cadeia><cadeia> IDID

%token%token ABPARABPAR

%token%token FPARFPAR

%token%token ABCHAVABCHAV

%token%token FCHAVFCHAV

%token%token PVIRGPVIRG

%token%token VIRG VIRG

%token%token <carac><carac> INVALINVAL

%%%%

Page 35: 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.

FuncaoFuncao : Cabecalho Declaracoes: Cabecalho Declaracoes;;

Cabecalho Cabecalho : ID ABPAR {printf ("%s \( ", : ID ABPAR {printf ("%s \( ", $1);} FPAR $1);} FPAR {printf (")\n");}{printf (")\n");}

| ID error {printf ("%s ", $1); | ID error {printf ("%s ", $1); Esperado ("(");} Esperado ("(");} FPAR {yyerrok; printf (")\n");}FPAR {yyerrok; printf (")\n");}| ID error {printf ("%s\n", $1); | ID error {printf ("%s\n", $1); Esperado ("( )"); yyerrok;}Esperado ("( )"); yyerrok;}| error {Esperado | error {Esperado

("Identificador");} ("Identificador");} ABPAR FPAR {yyerrok; printf ABPAR FPAR {yyerrok; printf

("() ");}("() ");}| ID ABPAR error {printf ("%s (\n", | ID ABPAR error {printf ("%s (\n",

$1); $1); Esperado (")"); yyerrok;} Esperado (")"); yyerrok;};;

Page 36: 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.

Declaracoes : ABCHAV {printf ("\{\n");} Declaracoes : ABCHAV {printf ("\{\n");} ListDecl ListDecl

FCHAV {printf ("}\n");}FCHAV {printf ("}\n");};;

ListDeclListDecl ::| ListDecl Declaracao| ListDecl Declaracao;;

DeclaracaoDeclaracao : Tipo ListElemDecl : Tipo ListElemDecl PVIRG PVIRG

{printf ("; \n");}{printf ("; \n");}| Tipo ListElemDecl error | Tipo ListElemDecl error

PVIRG PVIRG {Esperado("';' "); {Esperado("';' "); yyerrok;}yyerrok;}

;;

Page 37: 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.

Tipo Tipo : INT : INT {printf ("int ");} {printf ("int ");}| FLOAT {printf ("float ");}| FLOAT {printf ("float ");}| CHAR| CHAR {printf ("char ");} {printf ("char ");}| BOOL| BOOL {printf ("bool ");} {printf ("bool ");};;

ListElemDecl : ElemDeclListElemDecl : ElemDecl| ListElemDecl VIRG {printf (", | ListElemDecl VIRG {printf (",

");} ");} ElemDecl ElemDecl;;

ElemDecl : ID {printf ("%s ", $1);}ElemDecl : ID {printf ("%s ", $1);}| error ID | error ID {Esperado("Identificador"); {Esperado("Identificador");

yyerrok;}yyerrok;}; ;

Page 38: 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.

%%%%#include "lex.yy.c"#include "lex.yy.c"

void Esperado (char *s) {void Esperado (char *s) {printf ("\n***** Esperado: %s \n", s);printf ("\n***** Esperado: %s \n", s);

}}

A seguir alguns testesA seguir alguns testes e seus resultadose seus resultados

Page 39: 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.

1) Programa para teste: (sem erros)1) Programa para teste: (sem erros)

main ( )main ( ){{

int i, j, k, fat;int i, j, k, fat;bool m, n;bool m, n;float x;float x;char a;char a;

}}

Resultado:

main ( ){int i , j , k , fat ;bool m , n ;float x ;char a ;}

Page 40: 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.

2) Programa para teste: 2) Programa para teste:

( )( ){{

int i, j, k, fat;int i, j, k, fat;bool m, n;bool m, n;float x;float x;char a;char a;

}}

Resultado:

syntax error

***** Esperado: Identificador() {int i , j , k , fat ;bool m , n ;float x ;char a ;}

Page 41: 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.

3) Programa para teste: 3) Programa para teste:

abc )abc ){{

int i, j, k, fat;int i, j, k, fat;bool m, n;bool m, n;float x;float x;char a;char a;

}}

Resultado:

syntax errorabc***** Esperado: (){int i , j , k , fat ;bool m , n ;float x ;char a ;}

Page 42: 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.

4) Programa para teste: 4) Programa para teste:

abc (abc ({{

int i, j, k, fat;int i, j, k, fat;bool m, n;bool m, n;float x;float x;char a;char a;

}}

Resultado:

syntax errorabc (

***** Esperado: ){int i , j , k , fat ;bool m , n ;float x ;char a ;}

Page 43: 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.

5) Programa para teste: 5) Programa para teste:

abc abc {{

int i, j, k, fat;int i, j, k, fat;bool m, n;bool m, n;float x;float x;char a;char a;

}}

Resultado:

syntax errorabc

***** Esperado: ( ){int i , j , k , fat ;bool m , n ;float x ;char a ;}

Page 44: 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.

6) Programa para teste: 6) Programa para teste:

abc ( )abc ( ){{

int bool i, j, k, fat;int bool i, j, k, fat;bool m, nbool m, nfloat x;float x;char a;char a;

}}

Resultado:

abc ( ){int syntax error

***** Esperado: Identificador, j , k , fat ;bool m , n syntax error

***** Esperado: ';'char a ;}