Giriş
Şu satırı dahil ederiz.
Birinci parametre parse edilecek iterator tipidir.
İkinci parametre doldurulması beklenen tipi belirtir, yani return type diyelim.
Üçüncü parametre token'ları ayırmak için kullanılacak parser'dır. Genelde qi::space_type kullanılır.
Iterator
Şöyle yaparız
Skipper olarak şöyle yapılır.
fusion
Şu satırı dahil ederiz.
Şöyle yaparız. Template parametresi olarak sadece iterator veririr. Diğer parametreler kodlanır.
Şöyle yaparız. Template parametresi olarak sadece iterator ve skipper verilir. Return type kodlanır.
Default parametreler verebiliriz. Şöyle yaparız.
Şöyle yaparız. Her kural = veya kural %= ile belirtilir. Farkını bilmiyorum.
Ayrıca her kural sınıfın private alanında tanımlanmalıdır.
% karakteri ile şöyle yaparız.
Şöyle yaparız.
Elimizde iki gramer olsun. İlk gramer büyük harfle başlayan stringler, ikincisi ise double'ları okur.
Şöyle yaparız.
Şu satırı dahil ederiz.
#include <boost/spirit/include/qi.hpp>namespace qi = boost::spirit::qi;
namespace bs = boost::spirit;namespace ascii = boost::spirit::ascii;Birinci parametre parse edilecek iterator tipidir.
İkinci parametre doldurulması beklenen tipi belirtir, yani return type diyelim.
Üçüncü parametre token'ları ayırmak için kullanılacak parser'dır. Genelde qi::space_type kullanılır.
Iterator
Şöyle yaparız
std::string input = "...";
typedef std::string::const_iterator Iter;
MyGrammar<Iter,...> g;std::string input = "...";
auto it = input.begin();
MyGrammar<decltype(it),...>  g;Skipper olarak şöyle yapılır.
ascii::blank_typeascii::space_typefusion
Şu satırı dahil ederiz.
#include <boost/fusion/include/adapt_struct.hpp>using namespace boost::fusion;struct Foo
{
  std::string field1;
  std::string field2;  std::string field3;};BOOST_FUSION_ADAPT_STRUCT(
  MyNameSpace::Foo,
  (std::string, field1)
  (std::string, field2)
  (std::string, field3)
)Şöyle yaparız. Template parametresi olarak sadece iterator veririr. Diğer parametreler kodlanır.
template <typename It>
struct MyGrammar : qi::grammar<It, Attribute()> {
  MyGrammar() : MyGrammar::base_type(start) {
    start = qi::skip(qi::space) [ mainRule ];
    mainRule = /*....*/;
  }
private:
  qi::rule<It, Attribute()> start;
  qi::rule<It, Attribute(), qi::space_type> mainRule;
};Şöyle yaparız. Template parametresi olarak sadece iterator ve skipper verilir. Return type kodlanır.
template <typename Iterator, typename Skipper>
struct MyGrammar : qi::grammar<Iterator, Foo(), Skipper> {
  ...
};Default parametreler verebiliriz. Şöyle yaparız.
template <typename Iterator, typename Result = std::vector<std::string> > 
struct MyGrammar : public qi::grammar<Iterator, Result(), bs::ascii::space_type> {
};std::string input = "...";
auto it = input.begin();
my_grammar<decltype(it)> g;Şöyle yaparız. Her kural = veya kural %= ile belirtilir. Farkını bilmiyorum.
Ayrıca her kural sınıfın private alanında tanımlanmalıdır.
MyGrammar() : MyGrammar::base_type(start) {
    start = ...;
}
private:
qi::rule<Iterator, Foo(), Skipper> start;token = ...;
start = ...;
private:
qi::rule<Iterator, Foo(), ascii::blank_type> start;
qi::rule<Iterator, std::string()> token;% karakteri ile şöyle yaparız.
start = token % ',';
token = ...;token = ...;
start = "VARIABLE" >> text >> qi::eol;Şöyle yaparız.
template <typename It = std::string::const_iterator>
struct parser : qi::grammar<It, AST::Record()> {
  parser() : parser::base_type(start) {
    using namespace qi;
    start     = skip(blank) [record_];
    record_   = prefix_ >> fqdn_ >> int_ >> int_ >> int_ >> int_ >> sample_
                >> '[' >> sample_ >> ']' >> tolerance_;
    prefix_   = string("^+"); // or whatever you need to match here
    fqdn_     = +graph; // or whatever additional constraints you have
    sample_   = direction_ >> duration_;
    duration_ = (long_ >> units_) [ _val = _1 * _2 ];
    tolerance_= "+/-" >> duration_;
    BOOST_SPIRIT_DEBUG_NODES(
      (start)(record_)
      (prefix_)(fqdn_)(sample_)(duration_)(tolerance_)
    )
  }
  private:
    struct directions : qi::symbols<char, AST::TimeSample::Direction> {
     ...
    } direction_;
    struct units : qi::symbols<char, AST::clock::duration> {
        ...
    } units_;
    using Skipper = qi::blank_type;
    qi::rule<It, AST::Record()> start;
    qi::rule<It, AST::Record(), Skipper> record_;
    qi::rule<It, AST::TimeSample(), Skipper> sample_;
    qi::rule<It, AST::clock::duration(), Skipper> duration_, tolerance_;
    // lexemes:
    qi::rule<It, std::string()> prefix_;
    qi::rule<It, std::string()> fqdn_;
};Elimizde iki gramer olsun. İlk gramer büyük harfle başlayan stringler, ikincisi ise double'ları okur.
struct attr_1 {
    std::string a;
};
BOOST_FUSION_ADAPT_STRUCT(attr_1, (std::string, a))
struct attr_2 {
    double a;
};
BOOST_FUSION_ADAPT_STRUCT(attr_2, (double, a))
template <typename It = const char *>
struct grammar_1 : qi::grammar<It, attr_1()> {
  grammar_1() : grammar_1::base_type{ rule_ } { rule_ = qi::eps >> +ascii::upper; }
  private:
    qi::rule<It, attr_1()> rule_;
};
template <typename It = std::string::const_iterator>
struct grammar_2 : qi::grammar<It, attr_2()> {
  grammar_2() : grammar_2::base_type{ rule_ } { rule_ = qi::double_; }
  private:
    qi::rule<It, attr_2()> rule_;
};typedef boost::variant<attr_1, attr_2> attr_comp;
template <typename It = std::string::const_iterator>
struct grammar_comp : qi::grammar<It, attr_comp()> {
  grammar_comp() : grammar_comp::base_type{ rule_ } { rule_ = (g1_ | g2_); }
private:
  grammar_1<It> g1_;
  grammar_2<It> g2_;
   qi::rule<It, attr_comp()> rule_;
};Şöyle yaparız.
MyGrammar() : MyGrammar::base_type(start, "MY") {  start = ...;
  token = ...;
} 
Hiç yorum yok:
Yorum Gönder