2 Ocak 2018 Salı

spirit x3 phrase_parse

Giriş
Şu satırı dahil ederiz.
#include <boost/spirit/home/x3.hpp>
Kolay kullanmak için şöyle yaparız.
namespace x3 = boost::spirit::x3;
phrase_parse metodu - iterator + grammar + fusion
Metoda iterator , grammar ve fusion nesnesi geçilir.

phrase_parse metodu - iterator + grammar + grammar + std::vector
Şöyle yaparız.  C++ include directivlerini bulmak için kullanılır.
Bu örnekte content tuhaf bir şekilde begin ve end iterator'lere çevriliyor. Ayrıca dördüncü parametre olarak x3::space yerine yeni bir grammer veriliyor.
using namespace boost::spirit::x3;

auto comment_ = space 
          | "//" >> *(char_ - eol) 
          | "/*" >> *(char_ - "*/")
          ;

auto name_ = rule<struct _, std::string> {} = lexeme[
          '<' >> *(char_ - '>' - eol) >> '>'
        | '"' >> *(char_ - '"' - eol) >> '"'
    ];

auto include_ = "#include" >> name_;

auto const content = [&]() -> std::string {
  std::ifstream file(fname);
  return { std::istreambuf_iterator<char>{file}, {} };//string to be parsed
}();

std::vector<std::string> headers;
/*bool ok = */phrase_parse(content.begin(), content.end(),
 *(omit[*(char_ - include_)] >> include_) , comment_, headers);

phrase_parse metodu - std::vector
Şöyle yaparız. fusion vector nesnesi iki defa double template alır.
#include <boost/fusion/container/vector.hpp>

boost::fusion::vector<double, double> p;
x3::phrase_parse(
        s.begin(), s.end(), 
        x3::double_ >> x3::double_, x3::space, 
        p
);
assert( boost::fusion::at_c<0>(p) == 1.2 );
assert( boost::fusion::at_c<1>(p) == 3.4 );
phrase_parse metodu - std::pair
Şu satırı dahil ederiz.
#include <boost/fusion/include/std_pair.hpp>
Örnek
Şöyle yaparız.
std::pair<double, double> p;
std::string input("1.0 2.0");
std::string::iterator input_pos = input.begin();
x3::phrase_parse(input_pos, input.end(),
  x3::double_ >> x3::double_,
  x3::space, p);
Örnek
Şöyle yaparız.
std::string test("1.1");
std::pair<int, int> d;

bool r = qi::phrase_parse(
        test.begin(),
        test.end(),
        qi::int_ >> '.' >> qi::int_,
        space,
        d
        );
Diğer
x3 phrase_parse metodu "variadic overload" yeteneği sunmuyor. Yani en fazla 5 parametre alabiliyor. Eski spirit gibi çalışması için şöyle yaparız.
auto myparse = [](auto& b, auto e, auto const& p, auto&... binds) {
  auto attr = std::tie(binds...);
  return x3::phrase_parse(b, e, p, x3::space, attr);
};

std::string const s = "3.2 4.5";

double d1, d2;
auto begin = s.begin(), end = s.end();

if (myparse(begin, end, x3::double_ >> x3::double_, d1, d2)) {
  std::cout << "Parsed: " << d1 << ", " << d2 << "\n";
} else {
  std::cout << "Parse failed\n";
}

Hiç yorum yok:

Yorum Gönder