Linguagens e Programação BISON - dei.isep.ipp.ptproenca/dump/LPROG/pptFlexBison.pdf ·...

Preview:

Citation preview

Linguagens e Programação

BISONPaulo Proença – prp@isep.ipp.pt

LPROG

BISON

Gerador de analisadores sintáticos.

Converte uma gramática independente de contexto LARL(1)1 num programa C capaz de processar frases da linguagem.

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

1 LARL : Look-Ahead Left to right Rightmost derivation

Gramática LARL(1) independente de contexto.

Especificação do processo de análise apenas com um token de avanço.

LPROG

BISON & FLEX

O BISON integra-se com o FLEX para o reconhecimento dos tokens da linguagem

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

Excerto de programa

int square ( int x ){return x * x ;}

Análise léxica (FLEX)

Gramática BISON para a Análise sintática

funcao: tipo ID '(' listaParametros ')'blocoInstrucoes;

blocoInstrucoes: '{' instrucoes '}';instrucoes: /*vazio*/ | instrucoes instrucao;tipo: TIPO_INT | TIPO_FLOAT | TIPO_CHAR ;(…)

TIPO_INT

'{'

RETURN ID '*' ID ';'

'}'

ID '(' TIPO_INT ')'ID

LPROG

Resultado

3Resultado

2

Ficheiro texto

3Ficheiro texto

2

Ciclo de vida do programa BISON

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

ficheiro fonte bison

.y BISON

Erros de BISON

ficheiro fonte C

.tab.c

Compilador(gcc)

programa executável

Ficheiro texto

1

Resultado

1

ficheiro fonte flex

.flex FLEX

Erros de FLEX

yylex()

ficheiro fonte C

.c

ficheiro de cabeçalho C

.tab.hopção -d

include

LPROG

Passos para a compilação

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

>> bison –d ficheiro.y

>> flex ficheiro.flex

Produz: ficheiro.tab.cA opção "–d" implica a criação do ficheiro.tab.h

>> gcc ficheiro.tab.c lex.yy.c -lfl Produz: lex.yy.c

Produz: a.out

LPROG

Ficheiro BISON

Formato de um ficheiro BISON

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

%{#include <stdio.h>int numArgs=0, numErros=0;

%}

%token ID INT REAL%start inicio

(…)

Dec

lara

çõ

es

Instruções CInstruções que serão incluídas no ficheiro C gerado pelo BISON. Os exemplos mais comuns são:- inclusão ficheiros .h- declaração de variáveis e constantes

Declarações BISONDefinições BISON que incluem:- declaração de tokens e dos seus tipos- precedência de operadores- axioma da gramática

LPROG

Ficheiro BISON

Formato de um ficheiro BISON

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

(…)

%%inicio: /*vazio*/

| lista_args;

lista_args: arg| lista_args ',' arg;

arg: ID {numArgs++;}| INT {numArgs++;}| REAL {numArgs++;} ;

%%

(…)

Gra

tic

a

Gramática- Notação BNF

Regras definidas em minúsculas O símbolo “definido como” é : Tokens com mais de um

caracter definidos em maiúsculas e com um só caracter especificados entre plicas

Regra inicial- Definida com %start

Alternativa vazia- Definida sem conteúdo- Por questão de legibilidade utiliza-

se o comentário /*vazio*/

Final da regra- As regras terminam com ;

LPROG

Ficheiro BISON

Formato de um ficheiro BISON

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

(…)

int main() {yyparse();if (numErros == 0)

printf("Frase válida\n");else

printf("Frase inválida\nNº de erros: %d\n", numErros);printf("Nº de argumentos: %d\n",numArgs);return 0;

}

int yyerror(char *s) {numErros++;printf("Erro sintático ou semântico: %s\n", s);

}

Ro

tin

as

em

C

Evoca o analisador sintático

LPROG

Propostas de Exercícios

1. Crie o programa “Hello World” com BISON e FLEX. Os tokens existentes são HELLO e WORLD. Sempre

que o texto a analisar tiver os dois tokens pela ordem certa, deve imprimir a frase “HelloWorld!!!”.

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

LPROG

Propostas de Exercícios

1.

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

pl5ex1.flex

%{#include "pl5ex1.tab.h" /* header file criado pelo BISON */extern int nErr; /* variável declarada no BISON */

%}

%%[ \t] return ' ';Hello return HELLO;World return WORLD;. {printf("Erro léxico: simbolo desconhecido %s\n",

yytext);nErr++;}\n return 0;<<EOF>> return 0;%%

LPROG

Propostas de Exercícios

1.

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

pl5ex1.y

%{#include <stdio.h>int existe=0;int nErr=0;

%}

%token HELLO WORLD%start inicio

%%inicio: HELLO

' 'WORLD {existe=1;};

%%

(…)

LPROG

Propostas de Exercícios

1.

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

pl5ex1.y

(…)

int main(){yyparse();if(existe)

printf("\nHello World!!!\n");else

printf("Frase inválida\nNumero de erros: %d\n",nErr);return 0;

}

int yyerror(char *s){nErr++;printf("erro semantico: %s\n",s);

}

LPROG

Valores semânticos

A variável yylval permite guardar os valores

semânticos (lexemas) identificados pelo analisador léxico.

Por omissão yylval é definida como um

inteiro

É possível redefinir o tipo de yylval

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

Armazenamento do lexema no FLEX

[0-9]+ { yylval=atoi(yytext); return INT; }

Redefinição do tipo de yylval

#define YYSTYPE double

LPROG

Valores semânticos

Para definição de tipos mais complexos utiliza-se a diretiva BISON %union.

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

Diretiva %union no ficheiro BISON

%union {char *palavra;int numInteiro;float numReal;

}

Armazenamento do lexema no FLEX

[0-9]+ { yylval.numInteiro=atoi(yytext); return INT; }[a-zA-Z]+ { yylval.palavra=strdup(yytext); return STRING; }

LPROG

Ações Semânticas

O BISON pode ter ações semânticas ao longo das regras;

Cada ação semântica ocupa um $ da regra

dependendo da posição ocupada;

O lado esquerdo (regra) é referenciado sempre por $$.

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

expressao: INT { printf("Inteiro = %d\n",$1); } '+' { printf("Operador = %d\n",$2); } INT { printf("Inteiro = %d\n",$3); $$=$1+$3; } ;

LPROG

Propostas de Exercícios

2. Crie um analisador usando o FLEX e o BISON, que reconheça frases constituídas por dois inteiros separados por um operador relacional (=, <, >, <=,>=, <>). O analisador deve indicar se a frase esta

de acordo com a sintaxe, e se a comparação é verdadeira ou falsa.

10 <= 20 '\n' - verdadeiro

5 = 10 '\n' -falso

120 <> 130 '\n' - verdadeiro

> 10 '\n' - erro de sintaxe

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

LPROG

Propostas de Exercícios

2.

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

pl5ex2.flex

%{#include "pl5ex2.tab.h"extern int nErr;

%}%%[ \t] return 0;[0-9]+ {yylval=atoi(yytext);return INT;}= return IGUAL;\<= return MENOR_IGUAL;\>= return MAIOR_IGUAL;\<\> return DIFERENTE; \< return MENOR;\> return MAIOR;. {printf("Erro léxico: %s\n", yytext);nErr++;}\n return 0;<<EOF>> return 0;%%

LPROG

Propostas de Exercícios

2.

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

Pl5ex2.y

%{#include <stdio.h>int vlogico;int nErr=0;

%}

%token INT IGUAL MAIOR MENOR MAIOR_IGUAL MENOR_IGUAL DIFERENTE%start inicio

(…)

LPROG

Propostas de Exercícios

2.

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

Pl5ex2.y

(…)%%inicio:expIgual | expMaior | expMenor | expMaiorIgual |

expMenorIgual | diferente;

expIgual: INT IGUALINT {vlogico=($1==$3);};

expMaior: INT MAIORINT {vlogico=($1>$3);};

expMenor: INT MENORINT {vlogico=($1<$3);};

(…)

LPROG

Propostas de Exercícios

2.

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

Pl5ex2.y

(…)expMaiorIgual: INT

MAIOR_IGUALINT {vlogico=($1>=$3);};

expMenorIgual: INT MENOR_IGUALINT {vlogico=($1<=$3);};

diferente: INT DIFERENTEINT {vlogico=($1!=$3);};

%%(…)

LPROG

Propostas de Exercícios

2.

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

Pl5ex2.y

(…)

int main(){

yyparse();printf("%s\n",(vlogico==0)?"Falso":"Verdadeiro");return 0;

}

int yyerror(char *s){

nErr++;printf("erro semantico: %s\n",s);

}

LPROG

Propostas de Exercícios

3. Reescreva a gramática do exercício 2, de modo a:

i. aceitar inteiros e letras (a-z e A-Z);

ii. aceitar várias comparações na mesma linha;

iii. testar a incompatibilidade de tipos entre inteiros e letras;

iv. fazer a recuperação dos erros ocorridos.

10 <= 20 = 20 '\n' – verdadeiro verdadeiro

5 < 10 >= 5 < 2 '\n' – verdadeiro verdadeiro falso

120 <> A'\n' – incompatível

z <> A'\n' – verdadeiro

> 10 '\n' - erro de sintaxe

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

LPROG

Propostas de Exercícios

3.

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

pl5ex3.flex

%{#include <stdlib.h>#include "PL5Ex3Defs.h"#include "PL5Ex3.tab.h"

%}%%[ \t] return 0;[0-9]+ {yylval.valor.numero=atoi(yytext);

yylval.valor.tipo=INTEGER;return INT;}[a-zA-Z]+ {yylval.valor.palavra=strdup(yytext);

yylval.valor.tipo=STRING;return PALAVRA;}= return IGUAL;\<= return MENOR_IGUAL;\>= return MAIOR_IGUAL;\<\> return DIFERENTE; \< return MENOR;\> return MAIOR;. /*ignorado*/\n return yytext[0];<<EOF>> return 0;%%

LPROG

Propostas de Exercícios

3.

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

pl5Ex3Defs.h

typedef enum {INTEGER, STRING} ETipo;

typedef struct{int numero;char *palavra;ETipo tipo;

}SValor;

LPROG

Propostas de Exercícios

3.

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

pl5Ex3.y

%{#include <stdio.h>#include "PL5Ex3Defs.h"

int vlogico; int nErr=0;

void compara(SValor, int, SValor);%}

%union{SValor valor;

}

%token <valor> INT PALAVRA IGUAL MAIOR MENOR MAIOR_IGUAL MENOR_IGUAL DIFERENTE %type <valor> exprs

%start exprs_linha

%%(...)

LPROG

Propostas de Exercícios

3.

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

pl5Ex3.y

(...)%%exprs_linha: /*vazio*/

| exprs_linha exprs '\n';

exprs: INT {$$.numero = $1.numero; $$.tipo = $1.tipo;} | PALAVRA {$$.palavra = $1.palavra; $$.tipo = $1.tipo;}| exprs IGUAL INT { compara($1, IGUAL, $3); $$ = $3; }| exprs IGUAL PALAVRA { compara($1, IGUAL, $3); $$ = $3; }| exprs MAIOR INT { compara($1, MAIOR, $3); $$ = $3; }| exprs MAIOR PALAVRA { compara($1, MAIOR, $3); $$ = $3; }| exprs MENOR INT { compara($1, MENOR, $3); $$ = $3; }| exprs MENOR PALAVRA { compara($1, MENOR, $3); $$ = $3; }| exprs MAIOR_IGUAL INT { compara($1, MAIOR_IGUAL, $3); $$ = $3; }| exprs MAIOR_IGUAL PALAVRA { compara($1, MAIOR_IGUAL, $3); $$ = $3; }| exprs MENOR_IGUAL INT { compara($1, MENOR_IGUAL, $3); $$ = $3; }| exprs MENOR_IGUAL PALAVRA { compara($1, MENOR_IGUAL, $3); $$ = $3; }| exprs DIFERENTE INT { compara($1, DIFERENTE, $3); $$ = $3; }| exprs DIFERENTE PALAVRA { compara($1, DIFERENTE, $3); $$ = $3; }| error { yyerror("Erro de sintaxe");};

%%(...)

LPROG

Propostas de Exercícios

3.

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

pl5Ex3.y

(...)void compara (SValor v1, int op, SValor v2){

if(v1.tipo != v2.tipo){ puts("incompativel"); return; }switch(op){

case IGUAL: vlogico=(v1.tipo==INTEGER)?(v1.numero==v2.numero):(strcmp(v1.palavra,v2.palavra)==0);

break;case MAIOR: vlogico=(v1.tipo==INTEGER)?

(v1.numero>v2.numero):(strcmp(v1.palavra,v2.palavra)>0);break;

case MENOR: vlogico=(v1.tipo==INTEGER)?(v1.numero<v2.numero):(strcmp(v1.palavra,v2.palavra)<0);

break;case MAIOR_IGUAL: vlogico=(v1.tipo==INTEGER)?

(v1.numero>=v2.numero):(strcmp(v1.palavra,v2.palavra)>=0);break;

case MENOR_IGUAL: vlogico=(v1.tipo==INTEGER)?(v1.numero<=v2.numero):(strcmp(v1.palavra,v2.palavra)<=0);

break;case DIFERENTE: vlogico=(v1.tipo==INTEGER)?

(v1.numero!=v2.numero):(strcmp(v1.palavra,v2.palavra)!=0);}puts((vlogico==1)?"verdadeiro":"falso");}(...)

LPROG

Propostas de Exercícios

3.

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

pl5Ex3.y

(...)

int main(){

yyparse();return 0;

}

int yyerror(char *s){

nErr++;printf("erro sintatico/semantico: %s\n",s);

}

LPROG

Precedência de operadores

A precedência de operadores no BISON permite estabelecer a ordem pela qual as regras alternativas são processadas.

Diretivas BISON

%left - Declara um operador binário com associação à esquerda, isto é, o

agrupamento é realizado primeiro à esquerda. Assim a frase “x OPL y OPL z” seria realizada primeiro a operação “x OPL y” e depois o resultado desta operação com “OPL z”;

%right - Declara um operador binário com associação a direita, isto e, o

agrupamento e realizado primeiro a direita. Assim na frase “x OPR y OPR z” seria realizada primeiro a operação “y OPR z” e depois realizada o operação “x OPR” com

o resultado obtido anteriormente;

%nonassoc - Declara um operador não associativo, ou seja, um operador

que não pode aparecer mais que uma vez de seguida. Assim, a frase “x OPNA y OPNA z” gera um erro.

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

LPROG

Precedência de operadores

A precedência relativa de diferentes operadores é controlada pela ordem das suas declarações.

%left OP1 precedência mais baixa

%left OP2

%right OP3

%left OP4 precedência mais alta

Operadores definidos na mesma declaração têm igual nível de precedência.

%left OP5 OP6 OP7

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

LPROG

Precedência de operadores

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

Exemplo ficheiro BISON

(…)%left '<' '>' '=' DIF MEN_IG MAI_IG %left '+' '-' %left '*' '/' %left '^' %nonassoc MENOS_UNARIO%%expressao: expressao '+' expressao

| expressao '-' expressao| expressao '*' expressao| expressao '/' expressao| '-' expressao %prec MENOS_UNARIO | operando ;

operando: INTEIRO | REAL | ID;%%(…)

LPROG

Propostas de Exercícios

5. Implemente, utilizando o BISON e o FLEX, um analisador sintático para reconhecimento duma expressão aritmética. A gramática é a seguinte:

S →ID '=' E|E

E → E '+' E|E '-' E|E '*' E|E '/' E| '-'E| '(' E ')' | ID | INT |REAL

Em que ID é um identificador (letra de 'a' a 'z'), INT um numero inteiro e REAL um numero real. O parser deve analisar múltiplas

expressões e apresentar os resultados. Sempre que haja uma atribuição esse valor deve ser guardado, para ser utilizado com o identificador respectivo em outras expressões. Como tabela de símbolos, utilize um vector com uma posição para cada letra.

i. Implemente este analisador sem usar precedências de operadores;

ii. Implemente este analisador usando precedências de operadores.

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

LPROG

Propostas de Exercícios

5.

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

pl5Ex5.flex

%{#include "PL5Ex5Defs.h"#include "PL5Ex5.tab.h"extern int nErr;

%}%%[ \t] return 0;[a-z] {yylval.valor.id=yytext[0]; yylval.valor.tipo=VARIAVEL; return ID;} [0-9]+\.[0-9]+ {yylval.valor.val=atof(yytext); yylval.valor.tipo=NREAL;

return REAL;}[0-9]+ {yylval.valor.val=atof(yytext);yylval.valor.tipo=NINT; return INT;}\+ return ADD;- return SUB;\* return PROD;\/ return DIV;\( return OPENBR;\) return CLOSEBR;= return IGUAL;. {printf("erro léxico! simbolo não permitido: %s\n",yytext);nErr++;}\n return 0;<<EOF>> return 0;%%

LPROG

Propostas de Exercícios

5.

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

pl5Ex5Defs.h

typedef enum {NINT, NREAL, VARIAVEL} ETipo;

typedef struct{char id;float val;ETipo tipo;

}SValor;

LPROG

Propostas de Exercícios

5.

ii.

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

Pl5Ex5.y

%{#include <stdio.h>#include "PL5Ex5Defs.h"int nErr;float resultado;float memoria[26]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};float calcula(SValor, int, SValor);void setValor(SValor, SValor);float getValor(SValor);

%}

%union{SValor valor;

};

%token <valor> INT REAL ADD SUB PROD DIV ID OPENBR CLOSEBR IGUAL%type <valor> e %left ADD SUB%left PROD DIV

%start s(...)

LPROG

Propostas de Exercícios

5.

ii.

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

Pl5Ex5.y

(...)

%%

s: ID IGUAL e { setValor($1,$3); }| e;

e: e ADD e { $$.val=calcula($1, ADD, $3); }| e SUB e { $$.val=calcula($1, SUB, $3); }| e PROD e { $$.val=calcula($1, PROD, $3); }| e DIV e { $$.val=calcula($1, DIV, $3); }| SUB e { $$.val=-$2.val; }| OPENBR e CLOSEBR { $$.val=$2.val; }| ID { $$.val=getValor($1); }| INT | REAL;

%%

(...)

LPROG

Propostas de Exercícios

5.

ii.

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

Pl5Ex5.y

(...)

int main(){

while(1){int nErr=0;printf(" | %-8f | :: ",resultado);yyparse();

}return 0;

}

int yyerror(char *s){

nErr++;printf("ERRO SEMANTICO: %s\n",s);

}

(...)

LPROG

Propostas de Exercícios

5.

ii.

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

Pl5ex5.y

(...)

void setValor(SValor x, SValor y) {

int indice=x.id - 'a';memoria[indice]=y.val;

}

float getValor(SValor x){

int indice=x.id - 'a';resultado=memoria[indice];return(resultado);

}

(...)

LPROG

Propostas de Exercícios

5.

ii.

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

Pl5Ex5.y

(...)

float calcula (SValor v1, int op, SValor v2){

switch(op){case ADD:

resultado=v1.val+v2.val;break;

case SUB:resultado=v1.val-v2.val;break;

case PROD:resultado=v1.val*v2.val;break;

case DIV:resultado=v1.val/v2.val;

}

return resultado;}

LPROG

Exercício de aula

Desenvolver um analisador sintático, recorrendo ao flex e ao bison, que permita validar informação de datas segundo a seguinte gramática:

data: NUM '-' NUM '-' YEAR

| NUM '.' MONTH '.' NUM| NUM '/' NUM '/' NUM

;

Onde NUM é um numero de dois dígitos, YEAR num número de quatro dígitos e MONTH é uma palavra.

O analisador sintático deverá verificar a validade da data também no sentido da existência real da mesma.

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

LPROG

Algoritmo de análise do BISON

O funcionamento do BISON baseia-se numa pilha, onde são inseridos os tokense os lexemas.

Sempre que uma sequencia de tokens faz match com a regra atual, estes tokens são substituídos pela regra.

A inserção de tokens na pilha é chamada de shift e a substituição dos tokens por regras é chamada de reduce.

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

LPROG

Algoritmo de análise do BISON

Gramática (recursiva à ESQUERDA):

lista: INT

|lista ',' INT

Frase:

12,20,30

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

PILHA

LPROG

INT

Algoritmo de análise do BISON

Gramática (recursiva à esquerda):

lista: INT

|lista ',' INT

Frase:

12,20,30

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

PILHA

shiftlista

PILHA

reduce

LPROG

lista

,

Algoritmo de análise do BISON

Gramática (recursiva à esquerda):

lista: INT

|lista ',' INT

Frase:

12,20,30

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

PILHA

shift

LPROG

,

lista

INT

Algoritmo de análise do BISON

Gramática (recursiva à esquerda):

lista: INT

|lista ',' INT

Frase:

12,20,30

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

PILHA

shift

lista

PILHA

reduce

LPROG

lista

,

Algoritmo de análise do BISON

Gramática (recursiva à esquerda):

lista: INT

|lista ',' INT

Frase:

12,20,30

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

PILHA

shift

LPROG

,

lista

INT

Algoritmo de análise do BISON

Gramática (recursiva à esquerda):

lista: INT

|lista ',' INT

Frase:

12,20,30

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

PILHA

shift

lista

PILHA

reduce

LPROG

Algoritmo de análise do BISON

Gramática (recursiva à DIREITA):

lista: INT

|INT ',' lista

Frase:

12,20,30

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

PILHA

LPROG

INT

Algoritmo de análise do BISON

Gramática (recursiva à direita):

lista: INT

|INT ',' lista

Frase:

12,20,30

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

PILHA

shift

LPROG

INT

,

Algoritmo de análise do BISON

Gramática (recursiva à direita):

lista: INT

|INT ',' lista

Frase:

12,20,30

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

PILHA

shift

LPROG

,

INT

INT

Algoritmo de análise do BISON

Gramática (recursiva à direita):

lista: INT

|INT ',' lista

Frase:

12,20,30

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

PILHA

shift

LPROG

INT

,

INT

,

Algoritmo de análise do BISON

Gramática (recursiva à direita):

lista: INT

|INT ',' lista

Frase:

12,20,30

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

PILHA

shift

LPROG

,

INT

,

INT

INT

Algoritmo de análise do BISON

Gramática (recursiva à direita):

lista: INT

|INT ',' lista

Frase:

12,20,30

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

PILHA

shift lista

,

INT

,

INT

PILHA

reduce

LPROG

lista

,

INT

,

INT

Algoritmo de análise do BISON

Gramática (recursiva à direita):

lista: INT

|INT ',' lista

Frase:

12,20,30

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

PILHA

lista

,

INT

PILHA

reduce

LPROG

lista

,

INT

Algoritmo de análise do BISON

Gramática (recursiva à direita):

lista: INT

|INT ',' lista

Frase:

12,20,30

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

PILHA

lista

PILHA

reduce

LPROG

Algoritmo de análise do BISON

O funcionamento do analisador sintático pode ser acompanhado com detalhe utilizando a opção –v (--verbose) no comado bison ou incluindo a diretiva %verbose no ficheiro ".y"

Estes mecanismos produzem a criação de um ficheiro de extensão ".output", contendo

informação sobre o funcionamento do analisador sintático (gramática, conflitos, símbolos terminais e não terminais e os estados do autómato gerado pelo BISON)

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

LPROG

Algoritmo de análise do BISON

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

calc.y

%token NUM STR

%left '+' '-'%left '*'%start exp

%%

exp: exp '+' exp| exp '-' exp| exp '*' exp| exp '/' exp| NUM;

useless: STR;%%

LPROG

calc.output

1ª secção

refere os símbolos e as regras que não são utilizadas na

gramática

as regras (e os símbolos não terminais) inúteis são

removidas para produzir um parser mais reduzido

os tokens não utilizados na gramática são preservados

uma vez que podem ser reconhecidos pelo analisador

léxicoNonterminals useless in grammar

useless

Terminals unused in grammar

STR

Rules useless in grammar

6 useless: STR

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

LPROG

calc.output

2ª secção

são listados os estados que têm conflitos

State 8 conflicts: 1 shift/reduce

State 9 conflicts: 1 shift/reduce

State 10 conflicts: 1 shift/reduce

State 11 conflicts: 4 shift/reduce

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

LPROG

calc.output

3ª secção

o BISON apresenta a gramática que é de facto utilizadaGrammar

0 $accept: exp $end

1 exp: exp '+' exp

2 | exp '-' exp

3 | exp '*' exp

4 | exp '/' exp

5 | NUM

e descreve a utilização dos símbolosTerminals, with rules where they appear

(…)

Nonterminals, with rules where they appear

(…)

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

LPROG

calc.output

4ª secção

especificação do autómato, com a descrição de cada

estado e das respetivas transições (pointed rules)

cada transição é uma regra de produção onde o .representa a localização atual do cursor de entrada

State 0

0 $accept: . exp $end

NUM shift, and go to state 1

exp go to state 2

State 1

5 exp: NUM .

$default reduce using rule 5 (exp)

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

LPROG

Algoritmo de análise do BISON

O BISON pode produzir outras visualizações desta informação:

Ficheiro DOT - opção –g (--graph)

• Formato Graphviz

• Visualizador online em:

http://graphviz-dev.appspot.com/

Ficheiro XML - opção -x (--xml ) [=FILE]

• Este ficheiro pode ser transformado para HTML recorrendo a

uma transformação XSLT

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

LPROG

Conflitos BISON

reduce/reduce

Ocorre quando o BISON pode realizar “reduce” a duas

regras simultaneamente

Este erro deve-se normalmente a questões de

ambiguidade da gramática

DEVE SER SEMPRE CORRIGIDO

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

LPROG

Conflitos BISON

reduce/reduce

Ocorre quando o BISON pode realizar “reduce” a duas

regras simultaneamente

<sequencia> ⇒ <sequencia><palavra> ⇒ /*vazio*/<palavra> ⇒ TOKEN

<sequencia> ⇒ <talvez> ⇒ <palavra> ⇒ TOKEN

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

sequencia: /* vazio */ | talvez| sequencia palavra;

talvez: /* vazio */ | palavra ;

palavra: TOKEN ;

LPROG

Frase: TOKEN

Conflitos BISON - reduce/reduce

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

reduce

sequencia: /* vazio */ | talvez| sequencia palavra;

talvez: /* vazio */ | palavra ;

palavra: TOKEN ;

palavra talvezreduce

/*vazio*/

palavra

sequencia

palavra

reduce

TOKENshift

LPROG

Conflitos BISON

shift/reduce

Ocorre quando o BISON pode realizar “shift” de um

token ou “reduce” a uma regra simultaneamente

Este erro deve-se normalmente a questões de

ambiguidade da gramática

O BISON resolve sempre este conflito usando o “shift”

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

LPROG

Conflitos BISON

shift/reduce

Ocorre quando o BISON pode realizar “shift” de um

token ou “reduce” a uma regra simultaneamente

<if_stmt> ⇒ IF <expr> THEN <stmt> ⇒

IF <expr> THEN IF <expr> THEN <stmt> ELSE <stmt>

<if_stmt> ⇒ IF <expr> THEN <stmt> ELSE <stmt> ⇒

IF <expr> THEN IF <expr> THEN <stmt> ELSE <stmt> 19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

if_stmt: IF expr THEN stmt| IF expr THEN stmt ELSE stmt;

stmt: TOKEN| if_stmt;

expr: TRUE | FALSE ;

LPROG

Frase:

IF <expr> THEN IF <expr>

THEN <stmt> ELSE <stmt>

stmt

THEN

expr

IF

THEN

expr

IF

Conflitos BISON - shift/reduce

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

shift

reduce

if_stmt: IF expr THEN stmt| IF expr THEN stmt ELSE stmt;

stmt: TOKEN| if_stmt;

expr: TRUE | FALSE ;

if_stmt

THEN

expr

IF

ELSE

stmt

THEN

expr

IF

THEN

expr

IF

LPROG

Propostas de Exercícios

6. Considere um simulador de uma máquina de venda automática que dispõe de um conjunto de produtos e aceita moedas em euros (€0.01, €0.02, €0.05, €0.10, €0.20, €0.50, €1.00, €2.00). O objetivo é selecionar um produto, introduzir o respetivo valor, receber o troco (se existir) e receber o produto.

Considere os seguintes produtos: café (€0.35), pingo (€0.35), chá (€0.35), chocolate (€0.40), copo (€0.05) e leite (€0.30).

O formato de entrada de dados deve obedecer à seguinte regra:

<produto>,<moeda_1>, . . .<moeda_n>

O formato de saída deve obedecer à seguinte regra:

<produto>, <moeda_1>, . . .<moeda_n> | "dinheiro insuficiente"

Defina a gramática para que a máquina funcione sem interrupções e implemente-a utilizando o FLEX e o BISON.

19 de abril de 2016Paulo Proença – prp@isep.ipp.pt

Linguagens e Programação

BISONPaulo Proença – prp@isep.ipp.pt

Recommended