08.01.2013 Views

Winfried Bantel 25. Mai 2011 - Multimedia-Server Informatik

Winfried Bantel 25. Mai 2011 - Multimedia-Server Informatik

Winfried Bantel 25. Mai 2011 - Multimedia-Server Informatik

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

YACC<br />

<strong>Winfried</strong> <strong>Bantel</strong><br />

HTW Aalen<br />

<strong>25.</strong> <strong>Mai</strong> <strong>2011</strong><br />

W. <strong>Bantel</strong> (HTW Aalen) YACC <strong>25.</strong> <strong>Mai</strong> <strong>2011</strong> 1 / 26


Allgemeines zu YACC<br />

Entwickelt in den 1970ern von Johnson bei Bell<br />

Yet another COmpiler-Compiler<br />

Häufig Varianten im Einsatz, etwa GNU-Bison oder JYACC<br />

Yacc produziert einen LALR-Parser<br />

Yacc Setzt eine Scanner-Funktoin mit dem Prototypen int yylex(); voraus<br />

W. <strong>Bantel</strong> (HTW Aalen) YACC <strong>25.</strong> <strong>Mai</strong> <strong>2011</strong> 2 / 26


Black-Box der Mittelwert-Funktion<br />

Scanner✲<br />

✲<br />

Grammatik<br />

YACC<br />

Parser (*.c) ✲<br />

W. <strong>Bantel</strong> (HTW Aalen) YACC <strong>25.</strong> <strong>Mai</strong> <strong>2011</strong> 3 / 26


Verarbeitung von Yacc- und Lex-Datei<br />

Lex-<br />

Skript<br />

Yacc-<br />

Skript<br />

Lex<br />

Yacc<br />

✲<br />

✲<br />

C-<br />

Programm<br />

lex.yy.c<br />

✫✬<br />

C-<br />

Programm<br />

y.tab.c<br />

C-Compiler<br />

✲<br />

Ausführbares<br />

Programm<br />

W. <strong>Bantel</strong> (HTW Aalen) YACC <strong>25.</strong> <strong>Mai</strong> <strong>2011</strong> 4 / 26


Einführendes YACC-Beispiel<br />

Listing 1: Einführendes YACC-Beispiel (yacc/einfuehrung.y)<br />

%{ // D e f i n i t i o n e n und D e k l a r a t i o n e n<br />

#i n c l u d e <br />

i n t y y l e x ( ) ;<br />

v o i d y y e r r o r ( char ∗ ) ;<br />

%}<br />

%% // Regeln<br />

s t a r t : ’ a ’ | ’ ( ’ s t a r t ’ ) ’ ;<br />

%% // C−Code / Funtionen<br />

i n t main ( ) { r e t u r n y y p a r s e ( ) ; }<br />

i n t y y l e x ( ) {<br />

i n t c ;<br />

w h i l e ( c = g e t c h a r ( ) , c < 33 && c >−1);<br />

r e t u r n ( c < 0)? 0 : c ;<br />

}<br />

v o i d y y e r r o r ( char ∗ t x t ) { p r i n t f (” F e h l e r %s ” , t x t ) ; }<br />

W. <strong>Bantel</strong> (HTW Aalen) YACC <strong>25.</strong> <strong>Mai</strong> <strong>2011</strong> 5 / 26


Grundaufbau einer YACC-Datei (1)<br />

<br />

<br />

<br />

W. <strong>Bantel</strong> (HTW Aalen) YACC <strong>25.</strong> <strong>Mai</strong> <strong>2011</strong> 6 / 26


Grundaufbau einer YACC-Datei (2)<br />

Im ersten Teil werden vor allem Definitionen angegeben. Zusätzlich kann hier<br />

C-Code eingebracht werden, typischerweise Prototypen und Daten.<br />

Im zweiten Teil wird die Grammatik in einer YACC-spezifischen, der BNF<br />

ähnlichen Form eingegeben. Zusätzlich zur Grammatik kann Programmcode<br />

angegeben werden, der ausgeführt wird, wenn ein handle reduziert wird.<br />

Im dritten Teil werden C-Funktionen codiert. Manche Funktionen-wie etwa die<br />

<strong>Mai</strong>n-Funktion oder eine Funktion zur Fehlerausgabe-müssen hier codiert werden.<br />

Weitere Unterprogramme können hier ebenfalls codiert werden.<br />

W. <strong>Bantel</strong> (HTW Aalen) YACC <strong>25.</strong> <strong>Mai</strong> <strong>2011</strong> 7 / 26


YACC als Funktion<br />

YACC erzeugt Funktion<br />

i n t y y p a r s e ( ) ;<br />

YACC erwartet Scanner-Funktion<br />

i n t y y l e x ( ) ;<br />

W. <strong>Bantel</strong> (HTW Aalen) YACC <strong>25.</strong> <strong>Mai</strong> <strong>2011</strong> 8 / 26


YACC / LEX Zusammenspiel<br />

Scanner gibt Token zurück (Typ int)<br />

C-char-Konstanten sind gültige Token<br />

Weitere Token über %token-Direktive<br />

Zusätzliche Info über globale Variable yylval<br />

yylval -Typ über union-Deklaration<br />

Token können typisiert sein<br />

W. <strong>Bantel</strong> (HTW Aalen) YACC <strong>25.</strong> <strong>Mai</strong> <strong>2011</strong> 9 / 26


Term-Analyse in Ley / YACC (Scanner)<br />

Listing 2: Term-Analyse in Ley / YACC (Scanner) (yacc/term-parser.l)<br />

%{<br />

#i n c l u d e ”y . tab . h”<br />

%}<br />

%%<br />

”+” r e t u r n t p l u s ;<br />

”∗” r e t u r n t m a l ;<br />

”(” r e t u r n t k l a a u f ;<br />

”)” r e t u r n t k l a z u ;<br />

[0 −9]+(”.”[0 −9]+)? r e t u r n t z a h l ;<br />

[ \ t \n ] /∗ do n o t h i n g ∗ / ;<br />

. r e t u r n t f e h l e r ;<br />

%%<br />

W. <strong>Bantel</strong> (HTW Aalen) YACC <strong>25.</strong> <strong>Mai</strong> <strong>2011</strong> 10 / 26


Term-Analyse in Lex / YACC (Parser)<br />

Listing 3: Term-Analyse in Lex / YACC (Parser) (yacc/term-parser.y)<br />

%token t p l u s t m a l t k l a a u f t k l a z u t z a h l t f e h l e r<br />

%%<br />

e x p r e s s i o n : term<br />

| e x p r e s s i o n t p l u s term<br />

;<br />

term : f a c t o r<br />

| term t m a l f a c t o r<br />

;<br />

f a c t o r : t z a h l<br />

| t k l a a u f e x p r e s s i o n t k l a z u<br />

;<br />

%%<br />

W. <strong>Bantel</strong> (HTW Aalen) YACC <strong>25.</strong> <strong>Mai</strong> <strong>2011</strong> 11 / 26


Term-Analyse in Lex / YACC (Hautprogramm)<br />

Listing 4: Term-Analyse in Lex / YACC (Hautprogramm) (yacc/term-parser.c)<br />

#i n c l u d e <br />

i n t main ( ) {<br />

}<br />

p r i n t f (” Parse−E r g e b n i s : %d\n ” , y y p a r s e ( ) ) ;<br />

r e t u r n 0 ;<br />

i n t y y e r r o r ( char ∗ s ) {<br />

p r i n t f (”% s \n ” , s ) ;<br />

}<br />

W. <strong>Bantel</strong> (HTW Aalen) YACC <strong>25.</strong> <strong>Mai</strong> <strong>2011</strong> 12 / 26


Term-Analyse in Lex / YACC (Erzeugung)<br />

Listing 5: Term-Analyse in Lex / YACC (Erzeugung) (yacc/term-parser.sh)<br />

l e x term−p a r s e r . l<br />

yacc −d term−p a r s e r . y<br />

gcc term−p a r s e r . c y . tab . c l e x . yy . c − l f l<br />

W. <strong>Bantel</strong> (HTW Aalen) YACC <strong>25.</strong> <strong>Mai</strong> <strong>2011</strong> 13 / 26


Term-Compilierung in Lex / YACC (Scanner)<br />

Listing 6: Term-Compilierung in Lex / YACC (Scanner) (yacc/term-compiler.l)<br />

%{<br />

#i n c l u d e ”y . tab . h”<br />

#i n c l u d e < s t d l i b . h><br />

%}<br />

%%<br />

”+” r e t u r n t p l u s ;<br />

”∗” r e t u r n t m a l ;<br />

”(” r e t u r n t k l a a u f ;<br />

”)” r e t u r n t k l a z u ;<br />

[0 −9]+(”.”[0 −9]+)? { y y l v a l . d = a t o f ( y y t e x t ) ; r e t u r n t z a h l ; }<br />

[ \ t \n ] /∗ do n o t h i n g ∗ / ;<br />

. r e t u r n t f e h l e r ;<br />

%%<br />

W. <strong>Bantel</strong> (HTW Aalen) YACC <strong>25.</strong> <strong>Mai</strong> <strong>2011</strong> 14 / 26


Term-Compilierung in Lex / YACC (Parser)<br />

Listing 7: Term-Compilierung in Lex / YACC (Parser) (yacc/term-compiler.y)<br />

%{<br />

#i n c l u d e <br />

%}<br />

%union { double d ; }<br />

%token t p l u s t m a l t k l a a u f t k l a z u t f e h l e r<br />

%token< d> t z a h l<br />

%%<br />

e x p r e s s i o n : term<br />

| e x p r e s s i o n t p l u s term { p r i n t f (” add\n ” ) ; }<br />

;<br />

term : f a c t o r<br />

| term t m a l f a c t o r { p r i n t f (” mult \n ” ) ; }<br />

;<br />

f a c t o r : t z a h l { p r i n t f (” c o n s t %l f \n ” , $1 ) ; }<br />

| t k l a a u f e x p r e s s i o n t k l a z u<br />

;<br />

%% W. <strong>Bantel</strong> (HTW Aalen) YACC <strong>25.</strong> <strong>Mai</strong> <strong>2011</strong> 15 / 26


Term-Compilierung in Lex / YACC (Hautprogramm)<br />

Listing 8: Term-Compilierung in Lex / YACC (Hautprogramm) (yacc/term-compiler.c)<br />

#i n c l u d e <br />

i n t main ( ) {<br />

}<br />

p r i n t f (” Parse−E r g e b n i s : %d\n ” , y y p a r s e ( ) ) ;<br />

r e t u r n 0 ;<br />

i n t y y e r r o r ( char ∗ s ) {<br />

p r i n t f (”% s \n ” , s ) ;<br />

}<br />

W. <strong>Bantel</strong> (HTW Aalen) YACC <strong>25.</strong> <strong>Mai</strong> <strong>2011</strong> 16 / 26


Term-Compilierung in Lex / YACC (Erzeugung)<br />

Listing 9: Term-Compilierung in Lex / YACC (Erzeugung) (yacc/term-compiler.sh)<br />

l e x term−c o m p i l e r . l<br />

yacc −d term−c o m p i l e r . y<br />

gcc term−c o m p i l e r . c y . tab . c l e x . yy . c − l f l<br />

W. <strong>Bantel</strong> (HTW Aalen) YACC <strong>25.</strong> <strong>Mai</strong> <strong>2011</strong> 17 / 26


Term-Intertretierung in Lex / YACC (Parser)<br />

Listing 10: Term-Intertretierung in Lex / YACC (Parser) (yacc/term-interpreter.y)<br />

%{<br />

#i n c l u d e <br />

%}<br />

%union { double d ; }<br />

%token t p l u s t m a l t k l a a u f t k l a z u t f e h l e r<br />

%token< d> t z a h l<br />

%type< d> e x p r e s s i o n term f a c t o r<br />

%%<br />

c a l c : e x p r e s s i o n { p r i n t f (”% l f \n ” , $1 ) ; }<br />

e x p r e s s i o n : term {$$ = $1 ; }<br />

| e x p r e s s i o n t p l u s term {$$ = $1 + $3 ; }<br />

;<br />

term : f a c t o r {$$ = $1 ; }<br />

| term t m a l f a c t o r {$$ = $1 ∗ $3 ; }<br />

;<br />

f a c t o r : t z a h l {$$ = $1 ; }<br />

| t k l a a u f e x p r e s s i o n t k l a z u {$$ = $2 ; }<br />

W. <strong>Bantel</strong> (HTW Aalen) YACC <strong>25.</strong> <strong>Mai</strong> <strong>2011</strong> 18 / 26


Term-Intertretierung in Lex / YACC (Erzeugung)<br />

Listing 11: Term-Intertretierung in Lex / YACC (Erzeugung) (yacc/term-interpreter.sh)<br />

l e x term−c o m p i l e r . l<br />

yacc −d term−i n t e r p r e t e r . y<br />

gcc term−c o m p i l e r . c y . tab . c l e x . yy . c − l f l<br />

W. <strong>Bantel</strong> (HTW Aalen) YACC <strong>25.</strong> <strong>Mai</strong> <strong>2011</strong> 19 / 26


YACC-Analyse<br />

> yacc -v term-parser.y<br />

> less y.output<br />

Terminals which are not used<br />

t_fehler<br />

Grammar<br />

0 $accept: expression $end<br />

1 expression: term<br />

2 | expression t_plus term<br />

3 term: factor<br />

4 | term t_mal factor<br />

5 factor: t_zahl<br />

6 | t_kla_auf expression t_kla_zu<br />

W. <strong>Bantel</strong> (HTW Aalen) YACC <strong>25.</strong> <strong>Mai</strong> <strong>2011</strong> 20 / 26


Operatoren<br />

Priorität: 1 + 2 * 3<br />

Assoziativität: a = b = 1<br />

Priorität über Grammatik geregelt (Hierarchie)<br />

Assoziativität über Grammatik geregelt (Rekursion)<br />

Grammatik Γ1: Assoziativität in der Grammatik<br />

R1 → R1 ◦ id | id<br />

R2 → id ◦ R2 | id<br />

Einfach, da Grammatrik vorliegt<br />

Umfangreich bei vielen Operatoren (C: 44!)<br />

W. <strong>Bantel</strong> (HTW Aalen) YACC <strong>25.</strong> <strong>Mai</strong> <strong>2011</strong> 21 / 26


Operatoren in YACC<br />

Operator-Priorität und Assoziativität über %left- und %right-Direktiven<br />

%left: Linksassoziativ<br />

%right: Rechtsassoziativi<br />

Reihenfolge: Priorität aufsteigend<br />

Voraussetzung: Mehrdeutrige Grammatik (!!!!), typischerweise<br />

shift-reduce-Konflikte<br />

W. <strong>Bantel</strong> (HTW Aalen) YACC <strong>25.</strong> <strong>Mai</strong> <strong>2011</strong> 22 / 26


Operatoren in YACC<br />

Listing 12: YACC-Operatoren (yacc/term-operatoren.y)<br />

%token t p l u s t m a l t k l a a u f t k l a z u t z a h l t f e h l e r<br />

%l e f t t p l u s<br />

%l e f t t m a l<br />

%%<br />

e x p r e s s i o n : f a c t o r<br />

| e x p r e s s i o n t p l u s e x p r e s s i o n<br />

| e x p r e s s i o n t m a l e x p r e s s i o n<br />

;<br />

f a c t o r : t z a h l<br />

| t k l a a u f e x p r e s s i o n t k l a z u<br />

;<br />

%%<br />

W. <strong>Bantel</strong> (HTW Aalen) YACC <strong>25.</strong> <strong>Mai</strong> <strong>2011</strong> 23 / 26


Konflikte<br />

Schiebe-Reduziere-Konflikt<br />

Reduziere-Reduziere-Konflikt<br />

Warnungen (Schiebe-Reduziere) oder Fehler (Reduziere/Reduziere)<br />

YACC-Grammatiken sollen Konfliktfrei sein!!!!<br />

Große Probleme: Dangling-Else<br />

W. <strong>Bantel</strong> (HTW Aalen) YACC <strong>25.</strong> <strong>Mai</strong> <strong>2011</strong> 24 / 26


Operatoren in YACC<br />

Listing 13: Dangling-else (yacc/if-else-konflikt.y)<br />

%{<br />

#i n c l u d e <br />

#i n c l u d e <br />

%}<br />

%union { char t x t [ 2 0 0 ] ; }<br />

%type< t x t > stmt<br />

%%<br />

t x t : stmt { p r i n t f (” Loesung : %s \n ” , $1 ) ; }<br />

stmt : ’ i ’ ’ z ’ ’ t ’ stmt { s p r i n t f ( $$ , ” i z t (%s ) ” , $4 ) ; }<br />

| ’ i ’ ’ z ’ ’ t ’ stmt ’ e ’ stmt { s p r i n t f ( $$ , ” i z t (%s ) e (%s )<br />

| ’ c ’ { s t r c p y ( $$ , ” c ” ) ; }<br />

;<br />

%%<br />

i n t main ( ) { r e t u r n y y p a r s e ( ) ; }<br />

i n t y y l e x ( ) {<br />

i n t c ;<br />

w h i l e ( c = g e t c h a r ( ) , c < 33 && c >−1);<br />

r e t u r n ( c < 0)? 0 : c ;<br />

} W. <strong>Bantel</strong> (HTW Aalen) YACC <strong>25.</strong> <strong>Mai</strong> <strong>2011</strong> 25 / 26


Operatoren in YACC<br />

Bildschirmausgabe:<br />

> yacc -d if-else-konflikt.y<br />

conflicts: 1 shift/reduce<br />

> gcc y.tab.c -lfl<br />

> echo "i z t i z t c e c"|./a.out<br />

Loesung: i z t (i z t (c) e (c))<br />

W. <strong>Bantel</strong> (HTW Aalen) YACC <strong>25.</strong> <strong>Mai</strong> <strong>2011</strong> 26 / 26

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!