Die Boost C++ Bibliotheken

Attribute

Aktionen sind eine Möglichkeit, geparste Werte zu verarbeiten. Eine andere Möglichkeit ist es, Objekte an boost::spirit::qi::parse() oder boost::spirit::qi::phrase_parse() zu übergeben, in denen die geparsten Werte gespeichert werden. Diese Objekte werden Attribute genannt. Entscheidend ist, dass der Typ der Attribute zum Parser passt.

Genaugenommen sind Sie mit Attributen bereits im vorherigen Abschnitt in Berührung gekommen. Der Parameter, der an Aktionen übergeben wird, ist ein Attribut. Jeder Parser besitzt ein Attribut. So hat zum Beispiel das Attribut des Parsers boost::spirit::qi::int_ den Typ int. Im Folgenden werden Attribute jedoch nicht als Parameter an Funktionen übergeben. Geparste Daten werden in Attributen gespeichert und stehen nach einem Aufruf von boost::spirit::qi::parse() oder boost::spirit::qi::phrase_parse() zur Weiterverarbeitung zur Verfügung.

Beispiel 11.11. Einen int-Wert in einem Attribut speichern
#include <boost/spirit/include/qi.hpp>
#include <string>
#include <iostream>

using namespace boost::spirit;

int main()
{
  std::string s;
  std::getline(std::cin, s);
  auto it = s.begin();
  int i;
  if (qi::phrase_parse(it, s.end(), qi::int_, ascii::space, i))
    std::cout << i << '\n';
}

Im Beispiel 11.11 kommt ein Parser vom Typ boost::spirit::qi::int_ zum Einsatz. Der geparste int-Wert soll in der Variablen i gespeichert werden. Dies erfolgt nicht über eine Aktion. Stattdessen wird i als zusätzlicher Parameter an boost::spirit::qi::phrase_parse() übergeben. i wird dadurch zu einem Attribut des Parsers und automatisch auf den Wert gesetzt, der vom Parser gefunden wird.

Wenn Sie das obige Beispiel ausführen und eine Zahl eingeben, wird diese auf die Standardausgabe ausgegeben.

Beispiel 11.12. Mehrere int-Werte in einem Attribut speichern
#include <boost/spirit/include/qi.hpp>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
#include <iostream>

using namespace boost::spirit;

int main()
{
  std::string s;
  std::getline(std::cin, s);
  auto it = s.begin();
  std::vector<int> v;
  if (qi::phrase_parse(it, s.end(), qi::int_ % ',', ascii::space, v))
  {
    std::ostream_iterator<int> out{std::cout, ";"};
    std::copy(v.begin(), v.end(), out);
  }
}

Im Beispiel 11.12 wird ein Parser verwendet, der mit qi::int_ % ',' definiert ist. Dieser Parser erlaubt die Eingabe beliebig vieler Ganzzahlen, die durch Kommas getrennt werden müssen. Wie gewohnt spielt es keine Rolle, an welchen Stellen wie viele Leerzeichen angegeben werden – sie werden im obigen Beispiel ignoriert.

Weil der Parser mehrere int-Werte zurückgeben kann, muss das Attribut einen Typ besitzen, der mehrere int-Werte speichern kann. Im Beispiel wird ein Vektor übergeben. Wenn Sie das Beispiel ausführen und mehrere Ganzzahlen durch Kommas getrennt eingeben, werden sie durch Semikolons getrennt auf die Standardausgabe ausgegeben.

Sie können anstelle des Vektors auch einen anderen Container wie zum Beispiel std::list verwenden.

Die Dokumentation von Boost.Spirit enthält eine Übersicht, welcher Attribut-Typ für welchen Operator verwendet werden muss.