2012-05-09 4 views
6

Ich habe einen einfachen Konfigurationsdatei-Parser aus spirit :: lex und spirit :: qi. Wenn der Lexer das Muster include "path" erreicht, möchte ich den Text der Datei enthalten. Wie Sie vielleicht wissen, spirit :: Lexer :: begin() startet den Scanvorgang:Wie implementiere ich include-Anweisungen mit boost :: spirit :: lex?

// Read file contents into a std::string 
... 

// _first and _last are const char* 
_first = _contents.c_str(); 
_last = &_first[_input.size()]; 

// _token is a lexer::iterator_type for the current token 
_token = _lexer.begin(_first, _last); 

Meine Idee ist, einen Stapel zu haben, die Lexer Zustand speichert als eine Struktur dargestellt wird:

struct LexerState 
{ 
    const char* first; 
    const char* last; 
    std::string contents; 
}; 

Die lexer würde das Muster für include "path" erkennen und in einer semantischen Aktion den Pfad zur Include-Datei extrahieren. Dann wird der aktuelle Lexer-Status auf den Stapel geschoben, der Inhalt der Datei wird in eine Zeichenfolge geladen und der neue Status wird wie oben unter Verwendung von lexer :: begin() initialisiert.

Wenn der Lexer das EOF-Zeichen findet, wird der Stapel geöffnet und lexer :: begin() wird mit den vorherigen lexer-Statusvariablen aufgerufen.

Ist es in Ordnung, wiederholt lexer :: begin() so zu nennen? Wie bekomme ich lex :: lexer das Muster include "path" und das EOF-Zeichen zu erkennen, ohne ein Token zum Qi-Parser zurückzugeben?

Gibt es schließlich alternative oder bessere Möglichkeiten, dies zu erreichen?

Antwort

3

Werfen Sie einen Blick auf, wie Boost Wave Dinge tut:

Die Wave C++ Präprozessor-Bibliothek verwendet die Spirit Parser Bau Bibliothek eine C++ Lexer mit ISO/ANSI-Standards konformer Vorverarbeitung Funktionen zu implementieren. Es stellt eine Iteratorschnittstelle bereit, die das aktuelle vorverarbeitete Token aus dem Eingabestream zurückgibt. Dieses vorverarbeitete Token wird während des Iterierens über die Präprozessor-Iteratorsequenz im laufenden Betrieb erzeugt (in der Terminologie der STL sind diese Iteratoren Vorwärtsiteratoren).

Und in Bezug auf Merkmale:

Die C++ Präprozessor vier separate Einrichtungen bietet, die Sie, wie Sie sehen, passen können:

  • Aufnahme von Header-Dateien
  • Macro Expansion
  • Bedingte Kompilierung
  • Liniensteuerung

Ihre Quick Start Sample zeigt, wie Sie Wave Boost-Lexer-Schnittstelle verwenden würde.