160 likes | 333 Views
Parser generieren. Y et A nother C ompiler – C ompiler YACC. YACC. generiert die C-Programme, die den Eingabetext analysieren und bearbeiten; die Analyse betrifft die Zeichen, aus denen der Text besteht. YACC.
E N D
Parser generieren Yet Another Compiler – Compiler YACC
YACC • generiert die C-Programme, die den Eingabetext analysieren und bearbeiten; • die Analyse betrifft die Zeichen, aus denen der Text besteht.
Um einen Übersetzer für eine bestimmte Eingabe (Eingabesprache) zu konstruieren, müssen Sie u.a. Werkzeuge für folgende Aufgaben bereitstellen: • eine Funktion, die die Eingabe, Zeichen für Zeichen, einliest und in bestimmte Einheiten (Tokens) zerlegt (Scanner) • eine Funktion, die die Struktur der Eingabeeinheiten erkennt und entsprechende Aktionen ausführt, wenn eine bestimmte Struktur auftritt (Parser) • eine Funktion, die Fehler in der Eingabe behandelt
Programmaufruf:yacc [-schalter...] datei v zusätzlich zum C-Programm y.tab.c, gibt yacc in der Datei y.output eine Beschreibung der Übergangs-Tabellen des Parsers (Parsing- Tabellen) aus. d es wird eine Datei y.tab.h erstellt, die #define- Anweisungen enthält datei Name der Datei, in der das yacc-Quell- Programm steht
Wie arbeitet yacc?yacc erwartet als Eingabe ein yacc-Quell-Programm, das in einem bestimmten Format geschrieben sein muß. Der Benutzer legt im yacc-Quell-Programm fest: • die Struktur der Eingabe(-sprache), d.h. die Grammatik, die der Parser erkennen soll, • Aktionen, die ausgeführt werden, wenn der Parser eine entsprechende Struktur findet, • eine Funktion yylex, die die Eingabezeichen liest, nach Token vorgruppiert und die Strukturbestimmung vorbereitet. yylex führt also die lexikalische Analyse aus.
Wie arbeitet yacc ? (2)yacc erstellt aus diesen Angaben ein C-Programm, in dem ein Parser (yyparse) definiert wird. Genauer gesagt, erzeugt yacc die Übergangstabellen für einen Stackautomaten, der nach einem LR(1)-Parsing-Algorithmus arbeitet. Eingabe-einheiten werden solange in dem Stack abgespeichert, bis sie eine syntaktische Struktur bilden. Die Eingaben, die der Struktur angehören, werden aus dem Stack geholt und die Struktur wird abgespeichert.
Wie arbeitet yacc ? (3)Die Klasse der Grammatiken, die yacc bearbeiten kann, ist eine Teilmenge der Chomsky-Typ 2 Grammatiken (dieLALR(1)-Grammatiken). Die Grammatiken dürfen bestimmte Mehrdeutigkeiten enthalten; mit Präzedenzregelnkönnen sie Mehrdeutigkeiten auflösen.yacc schreibt das C-Programm, in dem die Funktion yyparse definiert wird, in die Datei y.tab.c . yyparse ist eine integer-Funktion, die die Funktion yylex jedes Mal aufruft, wenn die nächste Eingabeeinheit eingelesen werden muß.yyparse hat den return-Wert 0, wenn die Eingabe grammati-kalisch richtig beendet und vom Parser akzeptiert wird. Falls ein Fehler in der Eingabe auftritt und nicht erfolgreich behoben werden kann, dann hat yyparse den return-Wert 1.
Beispiel: $ yacc grammatik.y $ lex regeln.l $ cc y.tab.c -ly -lln $ a.out <eingabe $
Format eines yacc-Quell-Programms [Deklaration…] %% Regel… [%%] [Programm…] Deklarationen und Regeln müssen im entsprechenden Format geschrieben sein.
Im Programmteil können Sie C-Funktionen definieren, • die im yacc-Programm aufgerufen werden (z.B. Aktionen), • die Teilfunktionen eines Übersetzers sind (z.B. yylex), • die als Hauptfunktion fungieren sollen (z.B. main).
Deklarationen in yacc-Quell-Programmen: • %{ text %} • %token NAME [nummer] • %start symbol • %left TOKEN… • %right TOKEN… • %nonassoc TOKEN… • %type <value> symbol… • %union { unionkomponente }
Regeln in yacc-Quell-Programmen symbol : rumpf ; oder symbol : rumpf1 | rumpf2 . . . | rumpfn ;
Beispiel: %token JAHR %start datum %% datum : tag ‘.’ zmonat ‘.’ JAHR | tag ‘.’ wmonat JAHR ; tag : ‘1’ | ‘2’ . . . | ‘3’ ‘1’ ; zmonat : ‘1’ | ‘2’ . . . | ‘1’ ‘2’ ; wmonat : ‘J’ ‘a’ ‘n’ ‘u’ ‘a’ ‘r’ | ‘F’ ‘e’ ‘b’ ‘r’ ‘u’ ‘a’ ‘r’ | . . .
Aktionen in yacc-Quell-Programmen: • Werte zurückgeben, • von yylex Werte für Terminalsymbole entgegenentnehmen, • untereinander kommunizieren, • Ein- und Ausgabe ausführen, • andere Funktionen aufrufen, • externe Vektoren und Variablen ändern. Eine Aktion muß in { } geschrieben werden, also { C–Programmteil }
Wie arbeitet der Parser ? • Das Hauptprogramm ruft die Funktion yyparse ( ) auf, • die Funktion yyparse ruft die Funktion yylex auf.