SORU
19 Mayıs 2011, PERŞEMBE


daha fazla ruh madness - çözümleyici-tip (kurallar vs int_parser<>) ve meta-programlama teknikleri

Soru alt kalın, sorun da sonuna doğru damıtma kod parçası tarafından özetlenmiştir.

Tek bir bileşen Lakos olarak yazın sistemimi (tür sistemi string türünden gelen ve yok) birleştirmeye çalışıyorum. boost::array, boost::variant, ve bunu başarmak için boost::mpl, kullanıyorum. Benim tipte bir değişken ile birleştirilmiş için ayrıştırıcı ve jeneratör kurallar olmasını istiyorum. tanımlanmamış bir türü, (aşağıya bakınız) int4 türü ve int8 bir tipi var. Varyant variant<undefined, int4,int8> olarak okur.

int4 özellikleri:

struct rbl_int4_parser_rule_definition
{
  typedef boost::spirit::qi::rule<std::string::iterator, rbl_int4()> rule_type;

  boost::spirit::qi::int_parser<rbl_int4> parser_int32_t;

  rule_type rule;

  rbl_int4_parser_rule_definition()
  {
    rule.name("rbl int4 rule");
    rule = parser_int32_t;  
  }
};

template<>
struct rbl_type_parser_rule<rbl_int4>
{
  typedef rbl_int4_parser_rule_definition string_parser;
};

varyant yukarıda tanımsız olarak başlar, ve sonra ben kuralları başlatılamadı. Yaşadığım bir sorun, neden 50 sayfa hataları, ve sonunda başardı izlemek aşağı, Değişken kullanır operator= sırasında atama ve boost::spirit::qi::int_parser<> olamaz atanmış bir operatör=).

Kontrast için, tanımsız tipim ile bir sorunum yok:

struct rbl_undefined_parser_rule_definition
{
  typedef boost::spirit::qi::rule<std::string::iterator, void()> rule_type;
  rule_type rule;

  rbl_undefined_parser_rule_definition()
  {
    rule.name("undefined parse rule");
    rule = boost::spirit::qi::eps;
  }
};

template<>
struct rbl_type_parser_rule<rbl_undefined>
{
  typedef rbl_undefined_parser_rule_definition string_parser;
};

Sorunun damıtma:

#include <string>
#include <boost/spirit/include/qi.hpp>
#include <boost/variant.hpp>
#include <boost/cstdint.hpp>

typedef boost::spirit::qi::rule<std::string::iterator,void()> r1;
typedef boost::spirit::qi::rule<std::string::iterator,int()> r2;

typedef boost::variant<r1,r2> v;

int main()
{
  /*
  problematic
  boost::spirit::qi::int_parser<int32_t> t2;
  boost::spirit::qi::int_parser<int32_t> t1;


  t1 = t2;
  */

  //unproblematic
  r1 r1_;
  r2 r2_;
  r1_ = r2_;

  v v_;
  // THIS is what I need to do.
  v_ = r2();
}

Beton ayrıştırıcıları ve kuralları arasında anlamsal bir boşluk var. Beynim pramatism düşünmek için gitmiyorum, şu anda sigara içiyorBenim sorum, bu sorunu nasıl çözerim ?Üç yaklaşım sorunu çözmek için düşünebilirim.

bir:Statik işlev üyeleri:

struct rbl_int4_parser_rule_definition
{
  typedef boost::spirit::qi::rule<std::string::iterator, rbl_int4()> rule_type;

  //boost::spirit::qi::int_parser<rbl_int4> parser_int32_t;

  rule_type rule;

  rbl_int4_parser_rule_definition()
  {
    static boost::spirit::qi::int_parser<rbl_int4> parser_int32_t;

    rule.name("rbl int4 rule");
    rule = parser_int32_t;  
  }
};

Yaklaşım sanırım bir kod parçacığı güvenli engeller ? ?

iki:İntegral çözümleyici bir shared_ptr sarılır. Yazarak sistemi için TMP ile rahatsız ediyorum iki nedeni vardır: bileşenler 1 etkinliği, 2 merkezileştirmek ilgilidir. işaretçi kullanarak ilk nedeni yendi.

üç:operatör= yok-op olarak tanımlanır. varyant lhs varsayılan atama önce inşa edilmiş olduğunu garanti eder.

Düzenleme: En mantıklısı (operatör= no-op) yapar 3 seçenek düşünüyorum. Kural konteyner oluşturulduktan sonra değişmez, sadece mahsup tür kuralı sürekli zorlamak için atıyorum.

CEVAP
2 ŞUBAT 2012, PERŞEMBE


Soruyu tam ölçüde, bu yüzden emin değilim, ama burada bir kaç ipucu

  • Hattı // THIS is what I need to do. derler bana uyar (sorun çözüldü mü? ile yorumladı Aslında bir çözümleyici, bir kural değil atama demek olduğunu tahmin ediyorum?)

  • Fonksiyon-yerel static başlatma, son standart (C 11) parçacığı güvenli olarak tanımlandı. Derleyici C 0 X desteği parçacığı kontrol edin. (Eğer başlatıcı atar, deyim yeniden başlatmayı deneyecek başlatma, arada bir pas.

  • kurallar alias()

    http://boost-spirit.com/home/articles/doc-addendum/faq/#aliases açıklandığı gibi

    Mantıklı bir kopya zorunda aslında değer-kopya proto ifadesi olmadan kurallar oluşturabilirsiniz SSS dediği gibi, bu temelde tembel bağlayıcı izin vermek için

  • Nabialek Trick tam da ihtiyacınız olan şey olabilir, temelde tembel sonraki ayrıştırma için bir ayrıştırıcı seçer

    one = id;
    two = id >> ',' >> id;
    
    keyword.add
        ("one", &one)
        ("two", &two)
        ;
    
    start = *(keyword[_a = _1] >> lazy(*_a));
    

    Sizin kapsamda, keyword tanımlanmış olarak görüyorum

    qi::symbols<char, qi::rule<Iterator>*> keyword;
    

    semantik eylemleri öznitelikleri ile bütün işi. Alternatif olarak,

    qi::symbols<char, qi::rule<Iterator, std::variant<std::string,int>() >*> keyword;
    
  • Aynı tür altında kuralları önceki satırda, temelde gösterildiği gibi () getirin

    Bu kafam karıştı kısım: tip sistem birleştirmek istediğini söylüyorsun. Strongtyped ayrıştırıcıları (farklı öznitelik imza) ihtiyaç olmayabilir.

    typedef boost::variant<std::string,int> unified_type;
    typedef qi::rule<std::string::iterator, unified_type() > unified_rule;
    
    unified_rule rstring =  (qi::char_ - '.');
    unified_rule rint    = qi::int_;
    
    unified_rule combine = rstring | rint;
    

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Maschine Tutorials

    Maschine Tut

    15 ŞUBAT 2011
  • SDSARG3

    SDSARG3

    14 Mart 2009
  • WOSU Public Media

    WOSU Public

    23 AĞUSTOS 2007