Winfried Bantel 25. Mai 2011 - Multimedia-Server Informatik
Winfried Bantel 25. Mai 2011 - Multimedia-Server Informatik
Winfried Bantel 25. Mai 2011 - Multimedia-Server Informatik
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