13
11/17/2016 4 . yacc = Yet Another Compiler Compiler bison = “ GNU Project parser generator (yacc replacement)” “general-purpose parser generator that converts a context-free grammar … into a C program to parse that grammar “ http://dinosaur.compilertools.net/bison/index.html http://www.gnu.org/software/bison/manual/bison.html

bison - cs.ubbcluj.rodana/2016-2017/LFTC/ResurseCurs/7-bison.pdf · Folosirea bison + flex • ?? constantele asociate atomilor lexicali • $ bison –d fisier.y => fisier.tab.h

  • Upload
    others

  • View
    8

  • Download
    0

Embed Size (px)

Citation preview

Page 1: bison - cs.ubbcluj.rodana/2016-2017/LFTC/ResurseCurs/7-bison.pdf · Folosirea bison + flex • ?? constantele asociate atomilor lexicali • $ bison –d fisier.y => fisier.tab.h

11/17/2016 4

.

• yacc = Yet Another Compiler Compiler

• bison =

“ GNU Project parser generator (yacc replacement)”

“general-purpose parser generator

that converts a context-free grammar …

into a C program to parse that grammar “ http://dinosaur.compilertools.net/bison/index.html

http://www.gnu.org/software/bison/manual/bison.html

Page 2: bison - cs.ubbcluj.rodana/2016-2017/LFTC/ResurseCurs/7-bison.pdf · Folosirea bison + flex • ?? constantele asociate atomilor lexicali • $ bison –d fisier.y => fisier.tab.h

11/17/2016 6

.

• yacc = Yet Another Compiler Compiler

• bison =

“ GNU Project parser generator (yacc replacement)”

gramatică bazata pe LR(1) cod C

sub UNIX

$ info bison

$ bison -V bison (GNU Bison) 2.5 2.4.1

Written by Robert Corbett and Richard Stallman

~ 1988 - 1990

Page 3: bison - cs.ubbcluj.rodana/2016-2017/LFTC/ResurseCurs/7-bison.pdf · Folosirea bison + flex • ?? constantele asociate atomilor lexicali • $ bison –d fisier.y => fisier.tab.h

11/17/2016 7

Structura fişierului de intrare

%{

declaraţii C

%}

declaraţii

%%

reguli ale gramaticii

%%

Cod C

Page 4: bison - cs.ubbcluj.rodana/2016-2017/LFTC/ResurseCurs/7-bison.pdf · Folosirea bison + flex • ?? constantele asociate atomilor lexicali • $ bison –d fisier.y => fisier.tab.h

11/17/2016 8

Secţiunea reguli ale gramaticii:

• regulile multiple pt. acelaşi rezultat pot fi scrise separat

sau pot fi unificate prin “|” :

rezultat: regula1-componente...

| regula2-componente...

...

;

De exemplu: exp: exp exp '+'

| exp exp '*'

;

Page 5: bison - cs.ubbcluj.rodana/2016-2017/LFTC/ResurseCurs/7-bison.pdf · Folosirea bison + flex • ?? constantele asociate atomilor lexicali • $ bison –d fisier.y => fisier.tab.h

11/17/2016 9

Secţiunea reguli ale gramaticii:

• pentru fiecare componenta pot fi specificate acţiuni

(semantica regulii):

{instrucţiuni C}

rezultat: regula1-componente... {instr. C 1}

| regula2-componente... {instr. C 2}

...

;

• actiunea poate fi vida.

Page 6: bison - cs.ubbcluj.rodana/2016-2017/LFTC/ResurseCurs/7-bison.pdf · Folosirea bison + flex • ?? constantele asociate atomilor lexicali • $ bison –d fisier.y => fisier.tab.h

11/17/2016 10

Observatii (1)

• presupune ca exista functiile:

int yylex()

– returneaza codul unui atom

( <= %token DIGIT )

yyerror

– apelata atunci cand se detecteaza o eroare de sintaxa

• genereaza functia

– int yyparse(void)

• nu genereaza functia main

Page 7: bison - cs.ubbcluj.rodana/2016-2017/LFTC/ResurseCurs/7-bison.pdf · Folosirea bison + flex • ?? constantele asociate atomilor lexicali • $ bison –d fisier.y => fisier.tab.h

11/17/2016 11

Restul fisierului

• yacc generează o funcţie

yyparse()

• erorile sintactice sunt

raportate apelând

yyerror()

%%

yylex()

{

...

}

main()

{

yyparse();

}

yyerror()

{

printf("syntax error\n");

exit(1);

}

Page 8: bison - cs.ubbcluj.rodana/2016-2017/LFTC/ResurseCurs/7-bison.pdf · Folosirea bison + flex • ?? constantele asociate atomilor lexicali • $ bison –d fisier.y => fisier.tab.h

11/17/2016 13

Folosire bison

• $ bison fisier.y

=> fisier.tab.c

… gcc …

Page 9: bison - cs.ubbcluj.rodana/2016-2017/LFTC/ResurseCurs/7-bison.pdf · Folosirea bison + flex • ?? constantele asociate atomilor lexicali • $ bison –d fisier.y => fisier.tab.h

11/17/2016 14

Folosirea bison + flex

• ?? constantele asociate atomilor lexicali

• $ bison –d fisier.y

=> fisier.tab.h

=> fisier.tab.c

• fisierul *.lxi (ce urmeaza sa fie compilat cu flex)

#include “fisier.tab.h”

Page 10: bison - cs.ubbcluj.rodana/2016-2017/LFTC/ResurseCurs/7-bison.pdf · Folosirea bison + flex • ?? constantele asociate atomilor lexicali • $ bison –d fisier.y => fisier.tab.h

11/17/2016 15

Valori semantice ale neterminalelor

• permite ca actiunea semantica asociata unei reguli de productie sa fie descrisa in functie de valorile semantice ale neterminalelor

• exemplu:

expr: expr '+' expr { $$ = $1 + $3; }

• $$ - valoarea semantica asociata net. din m.s.

• $i - valoarea semantica asociata

celui de-al i-lea net. din m.d.

• yylval - valoarea semantica a unui atom

<= yylex !!

Page 11: bison - cs.ubbcluj.rodana/2016-2017/LFTC/ResurseCurs/7-bison.pdf · Folosirea bison + flex • ?? constantele asociate atomilor lexicali • $ bison –d fisier.y => fisier.tab.h

11/17/2016 16

Legatura cu yylex

• yacc apelează yylex() pt.

a obţine următorul atom

• “valoarea” unui atom se

memoreaza în var.

globală yylval

• tipul implicit este int

%%

yylex()

{

int c;

c = getchar();

if (isdigit(c)) {

yylval = c - '0';

return DIGIT;

}

return c;

}

Page 12: bison - cs.ubbcluj.rodana/2016-2017/LFTC/ResurseCurs/7-bison.pdf · Folosirea bison + flex • ?? constantele asociate atomilor lexicali • $ bison –d fisier.y => fisier.tab.h

11/17/2016 17

Interpretor expresii

Gramatica ambigua !

• atunci cand construieste arborele de derivare – care alegere se face?

• eroare: “conflict shift/reduce”

%%

line : expr '\n' { printf("%d\n", $1);}

;

expr : expr '+' expr { $$ = $1 + $3;}

| expr '*' expr { $$ = $1 * $3;}

| '(' expr ')' { $$ = $2; }

| DIGIT { $$ = $1; }

;

%%

Page 13: bison - cs.ubbcluj.rodana/2016-2017/LFTC/ResurseCurs/7-bison.pdf · Folosirea bison + flex • ?? constantele asociate atomilor lexicali • $ bison –d fisier.y => fisier.tab.h

11/17/2016 18

Precedenţa operatorilor

prioritate

de sus

(mică)

în jos

(mare)

%token DIGIT

%left '+' declaratie de atom !!

%left '*'

%%

line : expr '\n' { printf("%d\n", $1);}

;

expr : expr '+' expr { $$ = $1 + $3;}

| expr '*' expr { $$ = $1 * $3;}

| '(' expr ')' { $$ = $2;}

| DIGIT { $$ = $1; }

;

%%