2 Kasım 2017 Perşembe

spirit x3 char_parser

Giriş
Şu satırı dahil ederiz.
#include <boost/spirit/home/x3.hpp>
Tanımlama
Şöyle yaparız.
namespace test {
  struct any_char: x3::char_parser<any_char> {
    static bool const has_attribute = false;
    template <typename Char, typename Context>
    bool test(Char /*ch_*/, Context const&) const {
      return true;
    }
  };

  auto const char_ = any_char{};
}
Örnek
C++ header örüntüsünü parse eden parser için şöyle yaparız.
auto header_name_brackets = '<' >> *(~char_('>')) >> '>';
Şunu parse edebilir.
"<my/file.hpp>"
Örnek
Elimizde şöyle bir config dosyası olsun
VALUE "foo"
ANOTHERVALUE "bar"
YETANOTHERVALUE "barbar"
Şöyle yaparız. Gramer'deki -(...) ile başlayan kısma dikkat.
std::istream& stream = ..
std::map<std::string, std::string> settings;

boost::spirit::istream_iterator f(stream >> std::noskipws), l;
using namespace boost::spirit::x3;

auto key_ = lexeme [ +upper ];
auto value_ = lexeme [ '"' >> *~char_('"') >> '"' ];

if (!phrase_parse(f, l, -(key_ >> value_) % eol >> eoi, blank, settings))
  throw std::invalid_argument("cannot parse config map");
Örnek
horse kelimesine kadar olan kısmı parse etmek için şöyle yaparız.
template <typename Sub>
auto negate(Sub p) {
    return +(x3::char_ - x3::as_parser(p));
};


std::string input("all the king's men and all the king's horses"), parsed;
if (parse(input.begin(), input.end(), negate("horse"), parsed))
  std::cout << "'" << input << "' -> '" << parsed << "'\n";
Örnek
lambda'ya gelen ctx boost::variant<char,?> tipindendir. Şöyle yaparız.
std::string s("#");
namespace x3 = boost::spirit::x3;
auto f = [](auto & ctx) {
  auto & attr = x3::_attr(ctx);
  char c = boost::get<char>(attr);
};
auto mapChar = x3::char_('#') | x3::char_('.');

auto p = mapChar[f];
auto b = s.begin();
bool success = x3::parse(b, s.end(), p);
std::cout << "Success: " << success << ' ' << (b == s.end()) << '\n';
Ya da şöyle yaparız.
auto const& attr = x3::_attr(ctx);
char c;
x3::traits::move_to(attr, c);

Hiç yorum yok:

Yorum Gönder