6 Aralık 2017 Çarşamba

spirit qi Auxiliary Parser Sınıfları

qi::attr
Aslında gerçekte parse etmeden bir değer döndürmek için kullanılır.
Örnek
Şöyle yaparız.
struct Sample {
  int a;
  int b;
};
BOOST_FUSION_ADAPT_STRUCT(Sample, a , b)

namespace qi = boost::spirit::qi;

std::string const z("3");
Sample r;
qi::rule<std::string::const_iterator, Sample()> AnythingAndOne
  = qi::int_ >> qi::attr(1) >> qi::eoi;

if (parse(z.begin(), z.end(), AnythingAndOne, r))
  std::cout << "Parsed: " << boost::fusion::as_vector(r) << "\n";
else
  std::cout << "Parse failed\n";
Çıktı olarak şunu alırız.
Parsed: (3 1)
Örnek
Elimizde şu string olsun. null yerine 0 değerini yakalamak isteyelim.
"1.2,null,3.9"
Kullanım şekli şöyle
rule_def = parser_expression | qi::attr(default_value);
Şöyle yaparız.
reader_ = qi::double_ | qi::lit("null") >> qi::attr(0);
Tam örnek için şöyle yaparız.
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
struct DataStruct { double n1, n2, n3; };

BOOST_FUSION_ADAPT_STRUCT(DataStruct, n1, n2, n3)

using Iterator = typename std::string::const_iterator;

qi::rule<Iterator, double()> reader_   =
  qi::double_ | qi::lit("null") >> qi::attr(0);
qi::rule<Iterator, DataStruct()> data_ =
  reader_ >> ',' >> reader_ >> ',' >> reader_;

DataStruct res;
auto const str = std::string("1.2,null,3.9");
Iterator start = str.begin(), end = str.end();

if (qi::parse(start, end, data_ >> qi::eoi, res)) {
  std::cout << "parsed: " << boost::fusion::as_vector(res) << "\n";
}
Aynı şeyi şöyle de yaparız.
qi::rule<Iterator, double()> reader_ =
  (qi::double_[_val = _1] | (lexeme["null"])[_val = 0.]);
qi::eps
epsion parser. Derinlin 32'yi geçmesin istersek şöyle yaparız.
qi::rule<std::string::const_iterator, std::string(size_t depth)> term;
qi::_r1_type _depth;
term %= 
  qi::eps(_depth < 32) >>
  qi::string("(") >> *term(_depth + 1) >> qi::string(")");
qi::eol
Örnek
Şöyle yaparız.
token = '{' >> qi::eol;
Örnek
Şöyle yaparız.
cluster_start %= "=Cluster=" > qi::eol;
Örnek
Bir skipper tanımlamak için şöyle yaparız.
template <typename Iterator> structalo
verilog_skipper : qi::grammar<Iterator> {

  verilog_skipper() : verilog_skipper::base_type(skip) {
    skip = qi::ascii::space | line_comment;
    line_comment = "//" >> *(qi::char_ - qi::eol) >> (qi::eol|qi::eoi);
  }
private:
  qi::rule<Iterator> skip;
  qi::rule<Iterator> line_comment;
};

Hiç yorum yok:

Yorum Gönder