如何使用 boost::spirit 解析可能丢失的无符号整数?

问题描述 投票:0回答:1

我需要将两个由空格分隔的无符号整数解析为两个 std::Optional。其中一个或两个都可以是nan。例如,有效输入:“123 456”或“123 nan”或“nan 456”或“nan nan”。最优雅的规则是什么?谢谢!

c++ boost-spirit
1个回答
0
投票

假设有些事情,

  • 类似

    的属性类型
    using Pair = std::pair<std::optional<int>, std::optional<int>>;
    
  • 使用灵气

  • 不希望不区分大小写

  • 需要消耗全部输入

  • 在输入中始终需要两个标记,仅当不明确时才需要空格(例如,

    1nan
    被发现没有空格)

我建议类似的东西

auto optint = qi::copy(qi::int_ | "nan");
qi::rule<It, Pair()> p = qi::skip(qi::space) [ optint >> optint ];

演示

住在Coliru

#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted/std_pair.hpp>
#include <optional>
#include <iomanip>
namespace qi = boost::spirit::qi;

using Pair = std::pair<std::optional<int>, std::optional<int>>;
using It   = std::string::const_iterator;

template <typename T> std::string display(std::optional<T> const& v) {
    return v? std::to_string(v.value()) : "nullopt";
}

static inline std::ostream& operator<<(std::ostream& os, Pair const& pair) {
    return os << "(" << display(pair.first) << ", " << display(pair.second) << ")";
}

int main() {
    auto optint = qi::copy(qi::int_ | "nan");
    qi::rule<It, Pair()> p = qi::skip(qi::space) [ optint >> optint ];

    for (std::string const input : {"123 456", "123 nan", "nan 456", "nan nan"}) {
        Pair parsed;
        if (parse(begin(input), end(input), p >> qi::eoi, parsed)) {
            std::cout << quoted(input) << " -> " << parsed << std::endl;
        } else {
            std::cout << quoted(input) << " -> Did not parse" << std::endl;
        }
    }
}

印刷

"123 456" -> (123, 456)
"123 nan" -> (123, nullopt)
"nan 456" -> (nullopt, 456)
"nan nan" -> (nullopt, nullopt)
© www.soinside.com 2019 - 2024. All rights reserved.