更疯狂的精神 - 解析器类型(规则VS int_parser<>)和元编程技术 [英] more spirit madness - parser-types (rules vs int_parser<>) and meta-programming techniques

查看:169
本文介绍了更疯狂的精神 - 解析器类型(规则VS int_parser<>)和元编程技术的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题是在底部大胆,问题也接近尾声蒸馏code片段总结。

The question is in bold at the bottom, the problem is also summarized by the distillation code fragment towards the end.

我想我的类型的系统(类型系统确实给和从类型字符串)统一成一个单一的部件(由洛科什所定义)。我使用的boost ::阵列的boost ::变种的boost :: MPL 中,为了实现这一目标。我想为我的类型的一个变种统一解析器和发电机的规则。有一个未定义的类型,INT4(见下文)型和一个int8的类型。变体内容变体LT;不确定,INT4,INT8方式>

I am trying to unify my type system (the type system does to and from from type to string) into a single component(as defined by Lakos). I am using boost::array, boost::variant, and boost::mpl, in order to achieve this. I want to have the parser and generator rules for my types unified in a variant. there is a undefined type, a int4(see below) type and a int8 type. The variant reads as variant<undefined, int4,int8>.

INT4特点:

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;
};

上面的变种开始作为未定义的,然后我初始化规则。我有一个问题,这引起了50页的错误,而我也终于设法追查,变种使用运算符= 任务期间和提振::精神::齐:: int_parser&LT;&GT; 不能分配给另一个(运算符=)

the variant above starts out as undefined, and then I initialize the rules. I had a problem, which caused 50 pages of errors, and I have finally managed to track it down, Variant uses operator= during assignment and a boost::spirit::qi::int_parser<> cannot be assigned to another (operator=).

要相比之下,我没有问题,我不确定类型:

To contrast, I don't have a problem with my undefined type:

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;
};

问题的蒸馏:

#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();
}

有是具体的解析器和规则之间的语义鸿沟。我的脑子此刻吸烟,所以我不会去想pramatism,我的问题是,我该如何解决这个问题?我能想到的三种方法来解决这个问题。

There is a semantic gap between concrete parsers and rules. My brain is smoking at the moment so I am not going to think about pramatism, My question is, how do I solve this problem ? I can think of three approaches to solve the problem.

之一:静态函数成员:

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;  
  }
};

我猜方法的一个prevents线程安全的code? ?

I guess approach one prevents thread safe code ? ?

二:积分解析器包装在一个shared_ptr。有两个原因,我用TMP困扰的类型系统:1的效率,2集中化问题纳入组件。使用指针击败的第一个原因。

two: The integral parser is wrapped in a shared_ptr. There are two reasons I'm bothering with TMP for the typing system: 1 efficiency, 2 centralizing concerns into components. using pointers defeats the first reason.

三:运算符=定义为无操作。变种保证了 LHS 的默认分配之前建造的。

three: operator= is defined as a no-op. variant guarantees that the lhs is default constructed before assignment.

编辑:
我想选择3是最有意义的(运算符=是无操作)。一旦规则容器中创建它不会改变,我只分配给强制式的统治特点到它的偏移量。

I am thinking option 3 makes the most sense (operator= is a no-op). Once the rule container is created it will not change, and I am only assigning to force a type's rule trait into its offset.

推荐答案

我不太确定我得到这个问题的严重程度,但这里有一些提示

I'm not so sure I get the full extent of the question, but here are a few hints


  • 注释行//这是我需要做的。编译没问题(问题解决了?我猜你实际上意味着分配解析器,而不是一个规则?)

  • The line commented with // THIS is what I need to do. compiles fine with me (problem solved? I'm guessing you actually meant assigning a parser, not a rule?)

函数本地静态初始化已被定义为线程的最新标准(C ++ 11)的安全。检查的C ++ 0x线程编译器的支持。 (如果初始化两罚全中,初始化语句的过程将尝试重新初始化,顺便说一句)。

Initialization of function-local static has been defined to be thread safe in the latest standard (C++11). Check your compiler support for C++0x threading. (If the initializer throws, a pass of the initialization statement will try to initialize again, by the way).

规则别名()

如<一个描述href=\"http://boost-spirit.com/home/articles/doc-addendum/faq/#aliases\">http://boost-spirit.com/home/articles/doc-addendum/faq/#aliases

您可以创建规则逻辑副本,而无需实际价值的复制原前pression。作为FAQ说,这主要是为了让懒惰的结合

You can create 'logical copies' of rules without having to actually value-copy the proto expression. As the FAQ says, this is mainly to allow lazy-binding

href=\"http://boost-spirit.com/home/articles/qi-example/nabialek-trick/\"> Nabialek绝招可能是precisely你的

The Nabialek Trick might be precisely what you need, basically it lazily selects a parser for subsequent parsing

one = id;
two = id >> ',' >> id;

keyword.add
    ("one", &one)
    ("two", &two)
    ;

start = *(keyword[_a = _1] >> lazy(*_a));

在你的情况下,我可以看到关键字定义为

In your context, I could see keyword defined as

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

做所有的工作与语义动作的属性。另外,

doing all the work with attributes from semantic actions. Alternatively,

qi::symbols<char, qi::rule<Iterator, std::variant<std::string,int>() >*> keyword;


  • 带来同样类型下的规则(如显示在previous线,基本)

  • Bring the rules under the same type (like shown in the previous line, basically)

    这是在那里我感到困惑的部分:你说要统一的类型系统。有可能不是一个需要strongtyped解析器(不同属性的签名)。

    This is the part where I'm getting confused: You say you want to unify your type system. There might not be a need for strongtyped parsers (distinct attribute signatures).

    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;
    


  • 这篇关于更疯狂的精神 - 解析器类型(规则VS int_parser&LT;&GT;)和元编程技术的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆