4

我正在尝试编写一个解析器,它解析 aint32_t或 a double。作为第一次尝试,我编写了这个解析器:

const auto int_or_double = boost::spirit::x3::int32 | boost::spirit::x3::double_;

我希望得到一个boost::variant<int32_t, double> 解析器成功解析整数,12, 100, -42, 7但它无法解析双精度数13.243, 42.7, 12.0 -10000.3

这是一个现场演示

为什么这个解析器在双打上失败?

4

2 回答 2

6

您的问题与此问题非常相似。

当整数解析器首先出现在您的语法中时,它是首选。对于输入"12.9",解析器将解析其中的整数部分,"12.9并将12..live example

您必须颠倒顺序,以便双解析器优于整数解析器:

const auto double_or_int =  boost::spirit::x3::double_ | boost::spirit::x3::int32;

这现在适用于"12.9"live example

然而,由于双精度解析器也解析一个整数,所以即使输入是:你总是会得到双精度"12"live example

为了防止这种情况,您需要一个严格的双重解析器:

boost::spirit::x3::real_parser<double, boost::spirit::x3::strict_real_policies<double> > const double_ = {};

live example

于 2016-06-19T12:06:55.633 回答
1

我也不知道strict_real_policies,这听起来很方便。

我曾经像这样以更直接的方式解决了这个问题:

(qi::int_ >> !lit('.') >> !lit('e') >> !lit('E')) | qi::float_

如果您查看http://www.json.org/上的流程图​​, 您会发现这三个字符涵盖了将数字解析为浮点数的所有合法方式。(在我的特殊问题中。)

于 2016-06-19T14:16:04.013 回答