View
221
Download
0
Category
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
má
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