c++ - 来自备选方案的部分匹配的综合属性

标签 c++ boost-spirit boost-spirit-x3

当我在下面的规则中删除 x3::eps 时,第一个部分匹配的字符串结果仍在第二个匹配中,导致字符串包含重复的内容。

如果我在两者之间添加另一个案例,我仍然只会得到 1 个重复项而不是两个。

  • 为什么我需要使用 x3::eps,或者,我在评估规则和合成属性时误解了什么?
  • 我应该改用前瞻吗?
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/include/qi_char_class.hpp>
#include <boost/fusion/include/adapt_struct.hpp>

#include <iostream>
#include <string>
#include <vector>

namespace x3 = boost::spirit::x3;
namespace ascii = x3::ascii;

struct AstChannel {
    std::string label;
    bool complement;
};

x3::rule<class AstLabel, std::string> const astLabel = "astLabel";
auto const astLabel_def = ascii::lower >> *(ascii::alnum);
BOOST_SPIRIT_DEFINE(astLabel)

x3::rule<class AstChannel, AstChannel> const astChannel = "astChannel";
auto const astChannel_def = astLabel >> '!' >> x3::attr(true)
                          | astLabel >> x3::eps >> x3::attr(false) ;
BOOST_SPIRIT_DEFINE(astChannel) 

BOOST_FUSION_ADAPT_STRUCT(
    AstChannel,
    (std::string, label)
    (bool, complement)
)

int main() {
    std::string str("hello");
    auto iter = str.begin();
    auto end = str.end();
    AstChannel channel;
    bool r = phrase_parse(iter, end, astChannel, ascii::space, channel);
    if (r) {
        std::cout << channel.label << ',' << channel.complement << std::endl;
    }
    return 0;
}

最佳答案

真正的答案是:强制容器属性的原子属性传播(例如使用 x3::hold 或语义操作)。

更好的答案是:使用x3::matches:

Live On Coliru

#include <boost/spirit/home/x3.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <iostream>
using namespace std::string_literals;

struct AstChannel {
    std::string label;
    bool complement;
};

BOOST_FUSION_ADAPT_STRUCT(AstChannel, label, complement)

namespace Grammar {
    namespace x3 = boost::spirit::x3;
    namespace ascii = x3::ascii;

    auto const label   = x3::rule<struct labelRule, std::string> {"label" }
                       = x3::lexeme[ascii::lower >> *(ascii::alnum)];

    auto const channel = label >> x3::matches['!'];

    auto const entry   = x3::skip(ascii::space) [ channel ];
}

int main() {
    auto const str = "hello"s;

    AstChannel channel;
    if (parse(str.begin(), str.end(), Grammar::entry, channel)) {
        std::cout << channel.label << ',' << std::boolalpha << channel.complement << "\n";
    }
}

打印

hello,false

关于c++ - 来自备选方案的部分匹配的综合属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46912169/

相关文章:

c++ - Boost::spirit 属性类型不崩溃

c++ - 组合 `%` 和可选后缀时,自动属性传播有时不起作用

c++ - 如何在 x3 中使用继承属性重写 qi 解析器?

c++ - boost spirit X3 : Collapsing one-element lists

c# - 第一次执行设置后如何更改编程布局?

c++ - 如何使用istringstream提取混合格式

c++ - HTTP 状态码到 HRESULT 的映射

c++ - Boost.Spirit 将字符串解析为带基数的数字

c++ - 内部编译器错误,同时使用 boost spirit x3

C++ 继承无法正常工作