Jewiki unterstützen. Jewiki, die größte Online-Enzy­klo­pädie zum Judentum.

Helfen Sie Jewiki mit einer kleinen oder auch größeren Spende. Einmalig oder regelmäßig, damit die Zukunft von Jewiki gesichert bleibt ...

Vielen Dank für Ihr Engagement! (→ Spendenkonten)

How to read Jewiki in your desired language · Comment lire Jewiki dans votre langue préférée · Cómo leer Jewiki en su idioma preferido · בשפה הרצויה Jewiki כיצד לקרוא · Как читать Jewiki на предпочитаемом вами языке · كيف تقرأ Jewiki باللغة التي تريدها · Como ler o Jewiki na sua língua preferida

Backus-Naur-Form

Aus Jewiki
Zur Navigation springen Zur Suche springen

Die Backus-Naur-Form oder Backus-Normalform (kurz BNF) ist eine kompakte formale Metasprache zur Darstellung kontextfreier Grammatiken (Typ-2-Grammatiken in der Chomsky-Hierarchie). Hierzu zählt die Syntax gängiger höherer Programmiersprachen. Sie wird auch für die Notation von Befehlssätzen und Kommunikationsprotokollen verwendet.

Ursprünglich war sie nach John W. Backus benannt, später wurde sie (auf Anregung von Donald E. Knuth) auch nach Peter Naur benannt. Beide waren Pioniere der Informatik, die sich mit der Erstellung der Algol-60-Regeln und insbesondere mit der Kunst des Compilerbaus beschäftigten. Durch die Backus-Naur-Form im Algol 60 Report wurde es erstmals möglich, die Syntax einer Programmiersprache formal exakt, also ohne die Ungenauigkeiten natürlicher Sprachen, darzustellen.

Es gibt viele Varianten der Backus-Naur-Form. Die erweiterte Backus-Naur-Form (EBNF) ist eine gebräuchliche Variante, die unter anderem eine kompakte Notation von sich wiederholenden Elementen erlaubt. Für Syntaxdefinitionen in Internetnormen wird überwiegend die angereicherte Backus-Naur-Form (ABNF) verwendet.

Grundlagen

Ein Programm besteht zunächst aus – auf Bildschirm oder Papier – sichtbaren Zeichen. Daneben treten noch Leerzeichen und Zeilentrenner auf. Die sichtbaren Zeichen werden zu den Terminalsymbolen (englisch terminal symbols / terminals) gerechnet.

Die BNF verwendet so genannte Ableitungsregeln (Produktionen), in denen Nichtterminalsymbole (englisch nonterminal symbols / nonterminals) definiert werden. Dabei dient das Zeichen | (vertikaler Strich) als Alternative, die Zeichenfolge ::= wird zur Definition verwendet und die Nichtterminalsymbole (auch syntaktische Variablen genannt) werden mit spitzen Klammern <…> umschlossen.

Alternative:

<Ziffer ausser Null> ::= 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

Eine Ziffer außer Null ist also entweder eine 1, oder eine 2, oder eine 3 usw. Es lassen sich auch Terminalfolgen definieren, also eine Sequenz. Als Elemente dürfen Terminalsymbole und Nichtterminalsymbole auftreten.

Sequenz:

<Ziffer>              ::= 0 | <Ziffer ausser Null>
<Zweistellige Zahl>   ::= <Ziffer ausser Null> <Ziffer>
<Zehn bis Neunzehn>   ::= 1 <Ziffer>
<Zweiundvierzig>      ::= 42

Eine Ziffer ist also eine 0 oder eine Ziffer außer Null. Eine zweistellige Zahl ist eine Ziffer außer Null gefolgt von einer Ziffer. Zweiundvierzig ist eine 4 gefolgt von einer 2.

Wiederholungen müssen in BNF über Rekursionen definiert werden. Eine Ableitungsregel kann dazu auf der rechten Seite das Symbol auf der linken Seite enthalten, etwa:

<Ziffernfolge> ::= <Ziffer> | <Ziffer> <Ziffernfolge>

Lies: Eine Ziffernfolge ist eine Ziffer oder eine Ziffer gefolgt von einer Ziffernfolge.

Eine Ziffernfolge passt also zu den Symbolfolgen 0, 1, 2, 10, 9870, 8970635 usw., jedoch auch zu 00, 000, … Eine positive Zahl darf nicht mit 0 beginnen. Dies leistet die folgende Regel:

<Positive Zahl> ::= <Ziffer ausser Null> | <Ziffer ausser Null> <Ziffernfolge>

BNF und kontextfreie Sprachen

Die Produktionsregeln der BNF (nach Backus) sind genau die in kontextfreien Grammatiken (nach Chomsky) erlaubten Regeln; es ist also klar, dass beide Formalismen dieselben Sprachen erzeugen. Sie entstanden auch zu derselben Zeit, nämlich am Ende der 1950er Jahre. Es gibt aber erst seit 1961 einen Hinweis auf den Zusammenhang, nämlich in einem Überblicksartikel über Metasprachen von Saul Gorn,[1] dort noch als Zusammenhang von BNF mit allgemeinen Phrasenstrukturgrammatiken dargestellt und erst später – genauer – auf kontextfreie Grammatiken beschränkt. Im Folgejahr gab es einen Briefwechsel zwischen Gorn und Knuth über dieses Thema in den Leserbriefen (letters to the editor) von Comm. ACM. Es ist plausibel anzunehmen, dass Chomsky und Backus ihre Formalismen unabhängig voneinander entwickelten und Gorn der erste war, der beide Ansätze kannte und so die Verbindung herstellen konnte.[2]

BNF und Programmiersprachen

Um die Syntax von Programmiersprachen wie ALGOL, Pascal oder Java in BNF darzustellen, müssen auch die Schlüsselwörter (IF, SWITCH) zu den Terminalsymbolen gerechnet werden. In einem Compiler werden sie in einer Vorphase, der lexikalischen Analyse, erkannt und als besondere Zeichen weitergegeben. Kommentare werden von der lexikalischen Analyse erkannt (und oft entfernt), manchmal auch weitere Elemente wie Gleitkommazahlen, Bezeichner und Zeichenketten.

Damit lässt sich die gesamte Syntax z. B. eines PASCAL-Programms in BNF darstellen (teilweise gekürzt):

 <Programm>               ::= 'PROGRAM' <Bezeichner> 'BEGIN' <Satzfolge> 'END' '.'
 <Bezeichner>             ::= <Buchstabe> <Restbezeichner>
 <Restbezeichner>         ::= | <Buchstabe oder Ziffer> <Restbezeichner>
 <Buchstabe oder Ziffer>  ::= <Buchstabe> | <Ziffer>
 <Buchstabe>              ::= A | B | C | D | … | Z | a | b | … | z
 <Ziffer>                 ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
 <Satzfolge>              ::= …
 …

Eine Syntaxanalyse besteht aus der Rückführung eines Programmtexts auf das Nichtterminalsymbol <Programm>. Ein Programm muss also mit dem Wort PROGRAM beginnen, auf das ein Bezeichner folgt. Bezeichner beginnen mit einem Buchstaben, gefolgt von beliebig vielen Buchstaben oder Ziffern.

Die Rückführung auf <Programm> gelingt bei

  PROGRAM Ggt BEGIN … END .

  PROGRAM DiesisteinlangerBezeichnermit123 BEGIN … END .

nicht jedoch bei

  Ggt BEGIN … END .         (beginnt nicht mit PROGRAM)

  PROGRAM 123 BEGIN … END . (123 ist kein Bezeichner, Bezeichner müssen mit einem Buchstaben beginnen)

Beispiel

Hier eine BNF für eine deutsche Postanschrift:

  <Post-Anschrift>  ::= <Personenteil> <Straße> <Stadt>
  <Personenteil>    ::= <Titelteil> <Namensteil> <EOL>
  <Titelteil>       ::= <Titel> |
  <Namensteil>      ::= <Vornamenteil> <Nachname> | <Vornamenteil> <Namensteil>
  <Vornamenteil>    ::= <Vorname> | <Initial> .
  <Straße>          ::= <Straßenname> <Hausnummer> <EOL>
  <Stadt>           ::= <Postleitzahl> <Stadtname> <EOL>

Die Ausformulierung lautet:

  • Eine Postanschrift besteht aus einem Personenteil, gefolgt von einer Straße, gefolgt von der Stadt.
  • Der Personenteil besteht aus einem Titelteil und einem Namensteil, gefolgt von einem Zeilenende.
  • Der Titelteil besteht aus einem Titel oder ist leer.
  • Der Namensteil besteht aus einem Vornamensteil, einem Nachnamen oder aus einem Vornamensteil und wiederum aus einem Namensteil. (Diese Regel zeigt die Benutzung von Rekursion in BNFs und stellt den Fall dar, dass eine Person mehrere Vornamen und/oder Initialen besitzt.)
  • Der Vornamenteil besteht aus einem Vornamen oder einem Initial, auf den ein Punkt folgt.
  • Eine Straße besteht aus einem Straßenname, gefolgt von einer Hausnummer, gefolgt von einem Zeilenende.
  • Eine Stadt besteht aus einer Postleitzahl, gefolgt von einem Stadtname, gefolgt von einem Zeilenende.

Man beachte, dass einiges (wie die Postleitzahl oder Hausnummer) nicht weiter spezifiziert ist. Es wird angenommen, dass diese lexikalischen Details vom Kontext abhängen oder anderweitig spezifiziert sind.

Oft wird der Titel in eckige Klammern gestellt, der Titelteil entfällt. Dies bedeutet, dass der Titel leer sein darf:

Option:

 <Personenteil>    ::= [ <Titel> ] <Namensteil> <EOL>

Dieses Beispiel ist keine reine Form aus dem Algol 60 Report. Die eckigen Klammern […] stellen eine Option dar. Sie wurden einige Jahre später in der Definition von IBMs PL/I eingeführt, sind aber allgemein nur in EBNF anerkannt.

Option:

 <Zahl> ::= [ - ] <Positive Zahl>

Das Minuszeichen ist optional. Die Definition ist äquivalent zu

 <Zahl> ::=  <Positive Zahl> | - <Positive Zahl>

Eine Zahl ist eine positive Zahl, oder ein Minuszeichen, gefolgt von einer positiven Zahl.

Modifikationen der BNF

Syntaxdiagramme der modifizierten BNF

Die Alternative und die Sequenz sind zur Darstellung der BNF grundsätzlich geeignet. Allerdings lassen sich die Zeichen |, [, ] nicht von den BNF-Zeichen unterscheiden. Oft können auch Zeichen wie Punkt oder Minus nur schwer erkannt werden.

Die BNF wird daher in der Regel etwas modifiziert und ergänzt:

  • Keine spitzen Klammern <…> für Nichtterminale.
  • Zeichen als Terminalsymbole werden in Anführungszeichen gesetzt ("0" | "1" …)
  • Nichtterminalsymbole in Kleinbuchstaben.
  • Schlüsselwörter in Großbuchstaben.
  • Nur = statt ::=.
  • Ein Punkt am Ende einer Regel. Mehrzeilige Regeln sind möglich.
  ziffer            = "0" | "1" | "2" | "3" | … | "9" .
  zifferaussernull  = "1" | "2" | "3" | … | "9" .
  ziffernfolge      = ziffer | ziffer ziffernfolge .
  zahl              = [ "-" ] zifferaussernull [ ziffernfolge ] | "0" .
  programm          = PROGRAM bezeichner
                      BEGIN satzfolge END "." .

Die Option wird manchmal nicht mit eckigen Klammern, sondern durch ein angefügtes Fragezeichen dargestellt. Die Wiederholung durch Rekursion ist oft umständlich:

  • Optionen werden durch ein angefügtes Fragezeichen dargestellt.
  • Wiederholungen (ein- oder mehrfach) werden durch ein angefügtes Pluszeichen dargestellt.
  • Optionale Wiederholungen (keinmal, ein- oder mehrfach) werden durch einen angefügten Stern dargestellt.
  • Klammern dienen zur Gruppierung
  ziffernfolge ::= ziffer+ .
  zahl         ::= ( "-" )? zifferaussernull ( ziffernfolge )? | "0" .
  bezeichner   ::= buchstabe ( buchstabe | ziffer )* .

Die erweiterte Backus-Naur-Form geht andere Wege. Sie verwendet eckige Klammern […] für die Option, jedoch geschweifte Klammern {…} für die optionale Wiederholung. Terminale und Nichtterminale werden nicht streng unterschieden. Hier würde das obenstehende Beispiel so dargestellt:

  Ziffernfolge = Ziffer { Ziffer } ;
  Zahl         = [ "-" ] ZifferAusserNull [ Ziffernfolge ] | "0" ;
  Bezeichner   = Buchstabe { Buchstabe | Ziffer } ;

Selbstdefinition einer (modifizierten) BNF

Eine modifizierte BNF kann sich selbst definieren:

  Modifiziertebnf   ::= | Satz Modifiziertebnf .
  Satz              ::= Nichtterminal ":" ":" "=" Elementliste "." .
  Elementliste      ::= | Element Elementliste .
  Element           ::= Terminal | Nichtterminal .
  Nichtterminal     ::= Kleinbuchstabe | Kleinbuchstabe Nichtterminal .
  Terminal          ::= Schluesselwort | Anf Sichtbareszeichen Anf .
  Schluesselwort    ::= Grossbuchstabe | Grossbuchstabe Schluesselwort 
  Grossbuchstabe    ::= "A" | "B" | … | "Z" .
  Kleinbuchstabe    ::= "a" | "b" | … | "z" .
  Sichtbareszeichen ::= "!" | "$" | "%" | … (''alle sichtbaren Zeichen'') .
  Anf               ::= '"' .

Bei dieser Version werden Schlüsselwörter als Großbuchstaben dargestellt, Nichtterminale als Kleinbuchstaben. Wiederholungen müssen über Rekursionen definiert werden. Davon wird in der eigenen Definition auch Gebrauch gemacht (modifiziertebnf, elementliste, nichtterminal, schlüsselwort).

BNF und Parser-Generatoren

Manche Parsergeneratoren verwenden eine eigene Form der BNF als Eingabe und generieren hieraus einen Parser für die zugrundeliegende Programmiersprache.

Das dem Betriebssystem Unix beigegebene yacc ist so ein Programm. Es generiert einen tabellengesteuerten Parser aus einer BNF-Definition, wobei nur Produktionen (: statt ::=) und Alternativen (|) zulässig sind. Dies ist notwendig, da yacc eine S-Attribution ermöglicht, einem optionalen Teil jedoch kein sinnvoller semantischer Typ des Attributs zugeordnet werden kann. Als Ausgabe erhält man ein Unterprogramm in der Programmiersprache C. Die zugrundeliegende Grammatik muss dabei die LALR-Eigenschaft erfüllen.

Siehe auch

Literatur

Weblinks

Einzelnachweise

  1. Saul Gorn: Specification languages for mechanical languages and their processors – a baker’s dozen. In: Communications of the ACM 4, 1961, S. 336–371.
  2. Anton Nijholt: Computers and Languages. North-Holland, Amsterdam 1988, ISBN 0-444-70463-9, S. 207–210.
Dies ist ein als lesenswert ausgezeichneter Artikel.
Dieser Artikel wurde am 3. März 2006 in dieser Version in die Liste der lesenswerten Artikel aufgenommen.
Dieser Artikel basiert ursprünglich auf dem Artikel Backus-Naur-Form aus der freien Enzyklopädie Wikipedia und steht unter der Doppellizenz GNU-Lizenz für freie Dokumentation und Creative Commons CC-BY-SA 3.0 Unported. In der Wikipedia ist eine Liste der ursprünglichen Wikipedia-Autoren verfügbar.