【问题标题】:Boost Qi Composing rules using Functions使用函数提升 Qi 编写规则
【发布时间】:2015-01-07 05:04:17
【问题描述】:

我正在尝试为一种语言的多个子集定义一些 Boost::spirit::qi 解析器,并且代码重复最少。为此,我创建了一些基本的规则构建函数。原始解析器工作正常,但一旦我开始使用组合函数,我的解析器似乎不再工作。

一般语言的形式是:

A B: C

有些语言的子集,其中ABC 必须是特定类型,例如A 是int 而BC 是浮点数。这是我用于该子语言的解析器:

using entry = boost::tuple<int, float, float>;

template <typename Iterator>
struct sublang : grammar<Iterator, entry(), ascii::space_type>
{
   sublang() : sublang::base_type(start)
   {
       start = int_ >> float_ >> ':' >> float_;
   }
   rule<Iterator, entry(), ascii::space_type> start;
};

但由于子集很多,我尝试创建一个函数来构建我的解析器规则:

template<typename AttrName, typename Value>
auto attribute(AttrName attrName, Value value)
{
    return attrName >> ':' >> value;
}

这样我就可以更轻松地为每个子集构建解析器,而无需重复信息:

// in sublang
start = int_ >> attribute(float_, float_);

但是这失败了,我不知道为什么。在我的 clang 测试中,解析失败了。在 g++ 中,程序似乎崩溃了。

这是完整的示例代码:http://coliru.stacked-crooked.com/a/8636f19b2e9bff8d

当前代码有什么问题,解决这个问题的正确方法是什么?我想避免在每个子语言解析器中指定属性和其他元素的语法。

【问题讨论】:

    标签: c++ boost boost-spirit boost-spirit-qi


    【解决方案1】:

    很简单:将auto 与 Spirit(或任何基于 Boost Proto 和 Boost Phoenix 的 EDSL)一起使用很可能是未定义行为¹

    现在,您通常可以使用

    来解决此问题
    • BOOST_SPIRIT_AUTO
    • boost::proto::deep_copy
    • 最新版 Boost 中的新功能(TODO 添加链接)

    在这种情况下,

    template<typename AttrName, typename Value>
    auto attribute(AttrName attrName, Value value) {
        return boost::proto::deep_copy(attrName >> ':' >> value);
    }
    

    修复它:Live On Coliru

    或者

    1. 您可以使用带有继承属性的qi::lazy[]

      我在Reading JSON file with C++ and BOOSTprop_key 规则中做了非常相似的事情。

    2. 您可以查看 Spirit Repository 中的 Keyword List Operator。它旨在允许更轻松地构建语法,例如:

      no_constraint_person_rule %=
          kwd("name")['=' > parse_string ]
        / kwd("age")   ['=' > int_]
        / kwd("size")   ['=' > double_ > 'm']
        ;
      
    3. 您可以将其与Nabialek Trick 结合使用。我会在 SO 上搜索答案以获取示例。 (一个是Grammar balancing issue


    ¹ 完全无状态的参与者 (Eric Niebler on this) 和表达式占位符除外。参见例如

    一些例子

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-28
      • 1970-01-01
      相关资源
      最近更新 更多