29 Ocak 2018 Pazartesi

spirit x3 rule Sınıfı

Constructor - isim + gramer
Şöyle yaparız.
auto const identifier = x3::rule<struct _, char> { "identifier" } =
        x3::char_("0-9");
Constructor - isim + ayrık gramer
Örnek
Şöyle yaparız.
rule<struct idBlock1> const block {"Block"};
auto const block_def =
  '{' >> *( block  | (char_ - '}')) >> '}'
  | '[' >> *( block  | (char_ - ']')) >> ']';

BOOST_SPIRIT_DEFINE(block)
Örnek
rule değişken ismi ile BOOST_SPIRIT_DEFINE macrosuna verilen ismi aynı olmalı. Şu örnek hatalı
using namespace boost::spirit::x3;

class myrule_tag;
rule<myrule_tag, foo> version_number = "version_number";
auto const version_number_def = eps
        >> int_
        >> "."
        >> int_
        ;
BOOST_SPIRIT_DEFINE(rtsp_request_line)
Örnek
Şöyle yaparız.
namespace Header {

  using Type = std::tuple<unsigned int, unsigned int>;

  namespace x3 = boost::spirit::x3;

  x3::uint_parser<unsigned int, 10, 1, 3> uint_;

  x3::rule<class parser, Type> const parser = "parser";
  auto const parser_def  = '<' >> uint_ >> '>' >> uint_;

  BOOST_SPIRIT_DEFINE(parser)

}
Çağırmak için şöyle yaparız.
const std::string d1 = "<1>2";

Header::Type header;

auto iter = d1.begin();
auto end = d1.end();

bool r = boost::spirit::x3::parse(iter, end, Header::parser, header);
if (!r || iter != end) {
  std::cerr << "Parsing failed at " << std::string{iter,end} << "\n";
} else {
  std::cout << std::get<0>(header) << " " << std::get<1>(header) << "\n";
}
Constructor - gramer + lambda
Örnek
Elimizde şöyle bir ifade olsun. inner product yani her bir elemanın karşıdaki dizi ile çarpılı toplamlarını bulmak isteyelim. 1 * 4 + 2 * 5 + 3 * 6 = 32
"SUM({1, 2, 3} .* {4, 5, 6})"
Şöyle yaparız. Gramerde (parser + % + ayraç ) >> bitiş karakteri kullanımına dikkat.
auto ruleSum = x3::rule<struct _, int> {} =
        (
            x3::lit("SUM") >> '(' >>
            '{' >> (x3::int_ % ',') >> '}' >> ".*" >>
            '{' >> (x3::int_ % ',') >> '}' >>
            ')'
        )
[( [](auto& ctx) {
  using boost::fusion::at_c;
  // dissect context
  auto& pass = x3::_pass(ctx);
  auto& result = x3::_val(ctx);
  std::vector<int> const& vec1 = at_c<0>(x3::_attr(ctx));
  std::vector<int> const& vec2 = at_c<1>(x3::_attr(ctx));

  // do the work
  pass = (vec1.size() == vec2.size());
  if (pass)
    result = std::inner_product(boost::begin(vec1), boost::end(vec1),
      boost::begin(vec2), 0);
   })
];
Şöyle yaparız.
int attr = 0;
if( x3::phrase_parse(boost::begin(input), boost::end(input),
  ruleSum >> x3::eoi, x3::ascii::space, attr) ) {
  std::cout<<"Match! result = "<<attr<<std::endl;
} else {
  std::cout<<"Not match!"<<std::endl;
}

Hiç yorum yok:

Yorum Gönder