Boost 提升、精神、气:如何在规则中省略属性

Boost 提升、精神、气:如何在规则中省略属性,boost,boost-spirit-qi,Boost,Boost Spirit Qi,我对如何定义传递给qi::parse()的spirit::qi规则有点困惑,因为它应该省略firts和occurance。比如,我使用以下编译代码: std::string out_str; int out_int; std::string s2(",345"); bool rc = qi::parse(s2.begin(), s2.end(), qi::omit[qi::lit(",")] >> q

我对如何定义传递给qi::parse()的spirit::qi规则有点困惑,因为它应该省略firts和occurance。比如,我使用以下编译代码:

std::string out_str; int out_int;
std::string s2(",345");
bool rc = qi::parse(s2.begin(), s2.end(), qi::omit[qi::lit(",")] >>
                                          qi::int_, out_int);
但《守则》没有:

bool rc = qi::parse(s2.begin(), s2.end(), qi::omit[qi::lit(",")] >>
                                          qi::as_string[*qi::digit], out_str);
发射错误:
boost\boost\u 1\u 64\u 0\boost\spirit\home\qi\detail\assign\u to.hpp(153):错误C2440:“static\u cast”:无法从“const std::string”转换为“char”


有人能帮我理解我做错了什么吗?

假设你真的只是想解析一个整数列表,其中一些元素可能会出错,那么就按照你的意思拼写它:

-uint_ % ','
就这些。它可以很好地解析成一个
向量
,其中T是一个合适的整数类型,适合于您的应用程序域

演示 请参见

#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;

int main() {
    for (std::string const input : {"", ",", ",345", "1,,2,3,4,"}) {
        std::vector<int> the_important_stuff;
        bool ok = qi::parse(input.begin(), input.end(), -qi::uint_ % ',', the_important_stuff);

        if (ok)
            std::cout << "Input '" << input << "' parsed into " << the_important_stuff.size() << " integers\n";
        else
            std::cout << "Input '" << input << "' failed to parse\n";
    }
}
奖金 也可以忽略任何不重要的空白(即不在数字内),将调用更改为

    bool ok = qi::phrase_parse(input.begin(), input.end(), -qi::uint_ % ',', qi::space, the_important_stuff);

假设您真的只想解析一个整数列表,其中一些元素可能会出错,只需按照您的需要拼写它:

-uint_ % ','
就这些。它可以很好地解析成一个
向量
,其中T是一个合适的整数类型,适合于您的应用程序域

演示 请参见

#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;

int main() {
    for (std::string const input : {"", ",", ",345", "1,,2,3,4,"}) {
        std::vector<int> the_important_stuff;
        bool ok = qi::parse(input.begin(), input.end(), -qi::uint_ % ',', the_important_stuff);

        if (ok)
            std::cout << "Input '" << input << "' parsed into " << the_important_stuff.size() << " integers\n";
        else
            std::cout << "Input '" << input << "' failed to parse\n";
    }
}
奖金 也可以忽略任何不重要的空白(即不在数字内),将调用更改为

    bool ok = qi::phrase_parse(input.begin(), input.end(), -qi::uint_ % ',', qi::space, the_important_stuff);

IIRC,
lit
不会合成属性,因此
ommit
似乎是rendundant。你是对的。但是更改为qi::omit[qi::char_]>>qi::as_string[*qi::digit]对我来说也不起作用。类似地,
*qi::digit
的合成属性将是一个字符序列。这已经可以分配给
std::string
,因此这里也没有理由将
作为字符串。只需将语法写成
qi::lit(“,”>*qi::digit
——很好,谢谢Dan!IIRC,
lit
不会合成属性,因此
ommit
似乎是rendundant。你是对的。但是更改为qi::omit[qi::char_]>>qi::as_string[*qi::digit]对我来说也不起作用。类似地,
*qi::digit
的合成属性将是一个字符序列。这已经可以分配给
std::string
,因此这里也没有理由将
作为字符串。只需将语法写成
qi::lit(“,”>*qi::digit
——很好,谢谢Dan!谢谢你的回答,但关键是我不需要向量。比如说,我有一个字符串,其中固定长度的单词由“,”(例如:“#B7C82,339991,10!”,其中B7C82 id,“33”-应该是固定长度=2的字符串,“9991”-应该是固定长度=4的字符串,等等)。我知道我可以通过验证生成的属性长度在语义操作中设置qi::_pass=false,但我更喜欢使用类似qi::lit(“,”>>qi::repeat(2)[qi::char\u]>>qi::lit(“,”)的内容。老实说,我仍然不明白为什么qi::as_string[]会破坏编译。容器属性非常灵活。可以有许多子表达式构建单个容器属性,这确实会导致潜在的歧义/错误的启发式。但是,您仍然希望表达语法的意图,而不是“如何”。这意味着您应该简单地编写
qi::uint\u解析器
,而不是
qi::repeat(2)[qi::char\u]
文档中说,
qi::as_string`合成了一个字符容器,这不是您所需要的。另一方面,如果您需要一堆东西的字符串源代码,请将其包装在
qi::raw
(例如,
raw[int_u%,']
)中。感谢您提供有关qi::raw的提示!实时工作示例:。但是,我仍然只能猜测为什么qi::raw[qi::uint_parser{}]只发出第一个字符的属性,因为qi::raw应该返回一个范围。比如说,我有一个字符串,其中固定长度的单词由“,”(例如:“#B7C82,339991,10!”,其中B7C82 id,“33”-应该是固定长度=2的字符串,“9991”-应该是固定长度=4的字符串,等等)。我知道我可以通过验证生成的属性长度在语义操作中设置qi::_pass=false,但我更喜欢使用类似qi::lit(“,”>>qi::repeat(2)[qi::char\u]>>qi::lit(“,”)的内容。老实说,我仍然不明白为什么qi::as_string[]会破坏编译。容器属性非常灵活。可以有许多子表达式构建单个容器属性,这确实会导致潜在的歧义/错误的启发式。但是,您仍然希望表达语法的意图,而不是“如何”。这意味着您应该简单地编写
qi::uint\u解析器
,而不是
qi::repeat(2)[qi::char\u]
文档中说,
qi::as_string`合成了一个字符容器,这不是您所需要的。另一方面,如果您需要一堆东西的字符串源代码,请将其包装在
qi::raw
(例如,
raw[int_u%,']
)中。感谢您提供有关qi::raw的提示!实时工作示例:。但是,我仍然只能猜测为什么qi::raw[qi::uint_parser{}]会发出只有第一个字符的属性,因为qi::raw应该返回一个范围。