c++ - boost::spirit 解析带有分隔符号的 double

标签 c++ boost-spirit-qi

我正在使用 boost::spirit 将文本解析为 double ,其字符可以用空格与数字分隔。

使用或滥用real_policies ,我找到了一个解决方案,但我不确定是否有更简单的方法来实现它。 有人可以给我提示吗?

Live Example

这是相关的代码片段:

template <typename T>
struct real_with_separated_sign_policies : boost::spirit::qi::real_policies<T>
{
    // allow skipping chars between a possible sign and a folling real number
    template <typename Iterator>
    static bool parse_sign(Iterator& first, Iterator const& last)
    {
        bool ret = qi::extract_sign(first, last);
        if (ret)
            qi::parse(first, last, *qi::lit(' '));
        return ret;
    }
};

template <typename Iterator, typename Skipper>
struct RealWithSeparatedSignParser
    : qi::grammar<Iterator, double(), Skipper>
{
    boost::spirit::qi::real_parser<double, real_with_separated_sign_policies<double> > RealWithSeparatedSignValue;

    RealWithSeparatedSignParser() : RealWithSeparatedSignParser::base_type(start)
    {
        start %= RealWithSeparatedSignValue;
    }

    qi::rule<Iterator, double(), Skipper> start;
};

int main() {
    std::string str = " -  1.234 ";

最佳答案

我会像你在这里那样做。您应该考虑恢复 first迭代器,以防进一步解析失败。

您可能需要仔细检查 multi_pass<> 上的刷新语义适应的迭代器(我认为没关系,因为包装 real_parser 无论如何都必须能够在失败时回溯)。


当然,考虑到语法的简单性,示例可以减少,但这不是我想的重点。

这是一个较短的演示,显示了更通用的跳过策略(默认使用 blank_type):

Live On Coliru

#include <boost/spirit/include/qi.hpp>

namespace qi = boost::spirit::qi;

template <typename T, typename Skipper = qi::blank_type>
struct skip_after_sign_policies : boost::spirit::qi::real_policies<T> {
    // allow skipping chars between a possible sign and a folling real number
    template <typename Iterator>
    static bool parse_sign(Iterator& first, Iterator const& last) {
        return qi::extract_sign(first, last)
            && qi::phrase_parse(first, last, qi::eps, Skipper {});
    }
};

int main() {
    qi::real_parser<double, skip_after_sign_policies<double> > grammar;

    std::string const str = " -  1.234 ";

    auto it = str.begin();
    double value;
    bool ok = phrase_parse(it, str.end(), grammar, qi::space, value);

    std::cout << std::boolalpha << ok << " " << value;
    if (it != str.end())
        std::cout << "Remaining: '" << std::string(it, str.end()) << "'\n";
}

打印

true -1.234

关于c++ - boost::spirit 解析带有分隔符号的 double ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34441164/

相关文章:

c++ - 使用语义操作填充嵌套结构

c++ - Boost Karma 对象方法调用

c++ - Boost.Spirit X3 中的错误处理和注释

c++ - 优化 boost::spirit::qi 解析器

c++ - 指针转换是否昂贵?

c++ - 在属于我的进程的 z 顺序中找到最高的非子窗口

C++ vector 访问错误

c++ - spirit 解析器属性传播规则的问题

c++ - 我需要包括什么才能使用 OpenClipboard()?

c++ - 在这种情况下我会使用哪个循环