Spirit (Parser)

aus Wikipedia, der freien Enzyklopädie
Wechseln zu: Navigation, Suche
Dieser Artikel oder Abschnitt bedarf einer Überarbeitung. Näheres ist auf der Diskussionsseite angegeben. Hilf mit, ihn zu verbessern, und entferne anschließend diese Markierung.

Spirit ist ein mittels Templatemetaprogrammierung implementierter rekursiv absteigender Parsergenerator. Die Benutzung der erweiterten Backus-Naur-Form in C++ wird mithilfe von Ausdrucks-Templates ermöglicht. Die Parser-Objekte werden durch Überladen von Operatoren erstellt und ergeben einen LL-Parser, der in der Lage ist, mehrdeutige Ausdrücke auszuwerten.

Spirit kann zusammen und getrennt für lexikalische Analyse sowie auch für einfaches Parsen benutzt werden.

Der Spirit-Parser ist Bestandteil der freien Boost-Bibliothek.

Operatoren[Bearbeiten]

Aufgrund von Beschränkungen seitens der Programmiersprache C++ wurde die Spirit-Syntax um die Operatoren-Rangfolge aufgebaut, wobei Ähnlichkeiten zu EBNF sowie regulären Ausdrücken erhalten bleiben.

Syntax Erläuterung
x >> y Entspricht x gefolgt von y.
*x Entspricht x null oder mindestens einmal. (Repräsentiert die kleenesche Hülle; C++ hat keinen unären Postfix Operator *)
x | y Entspricht x oder y.
+x Entspricht x mindestens einmal.
 !x Entspricht x null oder einmal.
x & y Entspricht x und y.
x - y Entspricht x aber nicht y.
x ^ y Entspricht x, y oder beiden zusammen (in beliebiger Reihenfolge).
x [ function_expression ] Ruft die Funktion (oder den Funktor) auf, die (oder der) function_expression zurückgibt, wenn x wahr ist.
( x ) Entspricht x (kann für Rangfolgen-Gruppierungen benutzt werden)
x % y Entspricht eine oder mehrere Wiederholungen von x, getrennt durch Vorkommnisse von y.
~x Entspricht alles außer x (nur mit Zeichenklassen wie ch_p oder alnum_p)

Beispiel[Bearbeiten]

#include <boost/spirit.hpp>
#include <boost/spirit/actor.hpp>
#include <string>
#include <iostream>
 
using namespace std;
using namespace boost::spirit;
 
int main()
{
    string input;
 
    cout << "Gib eine Zeile ein.\n";
    getline(cin, input);
 
    cout << "Eingabe: '" << input << "'.\n";
 
    unsigned count = 0;
 
 /*  
    Die nächste Zeile parst die Eingabe (input.c_str()),
    mittels folgender Semantik
        (Einrückung entspricht dem Quellcode zwecks Übersichtlichkeit):
 
     Null oder mehr Vorkommnisse von (
          Buchstabenfolge "Katze" ( wenn wahr, erhöhe Zählvariable "count" )
      oder jedes andere Zeichen (fortschreiten um nächstes Vorkommnis von "Katze" zu finden)
     )
 */
     parse(input.c_str(),
        *(  str_p("Katze") [ increment_a(count) ]
          | anychar_p
         ));
 /*
     Der Parser wird mithilfe von Operatorüberladungen und
     Template-Matching gebaut, d.h. dass die eigentliche
     Arbeit in spirit::parse() erledigt wird und der Ausdruck
     der mit * anfängt, lediglich das Regelwerk initialisiert
     welches die Parser-Funktion benutzt.
  */
 
    // Zeige schließlich das Ergebnis.
    cout << "Die Eingabe hatte " << count
              << " Vorkommnisse von 'Katze'\n";
}

Es gibt andere Algorithmen, die zum Durchsuchen von Zeichenketten besser geeignet sind. Dieses Beispiel ist nur zur Veranschaulichung des Konzepts gedacht, wie Regeln erstellt und diesen Aktionen zugewiesen werden.

Weblinks[Bearbeiten]