C++ boost spirit x3 int32 | double uu无法解析double

C++ boost spirit x3 int32 | double uu无法解析double,c++,parsing,c++14,boost-spirit,boost-spirit-x3,C++,Parsing,C++14,Boost Spirit,Boost Spirit X3,我正在尝试编写一个解析器,它可以解析int32\t或double。 作为第一次尝试,我编写了以下解析器: const auto int_or_double = boost::spirit::x3::int32 | boost::spirit::x3::double_; 我希望得到一个boost::variant 解析器成功地解析了像12100,-42,7这样的整数,但未能解析像13.243,42.7,12.0-10000.3这样的双精度整数 这里是现场直播 为什么这个解析器在双精度上会失败?您

我正在尝试编写一个解析器,它可以解析
int32\t
double
。 作为第一次尝试,我编写了以下解析器:

const auto int_or_double = boost::spirit::x3::int32 | boost::spirit::x3::double_;
我希望得到一个
boost::variant
解析器成功地解析了像
12100,-42,7
这样的整数,但未能解析像
13.243,42.7,12.0-10000.3这样的双精度整数

这里是现场直播


为什么这个解析器在双精度上会失败?

您的问题非常类似于

当整数解析器首先出现在语法中时,最好使用它。对于输入
“12.9”
,解析器将解析
“12.9
的整数部分,即
12
,并在
处停止

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

const auto double_or_int =  boost::spirit::x3::double_ | boost::spirit::x3::int32;
这将适用于
“12.9”

但是,由于double解析器也解析整数,因此即使输入是
“12”
,也始终会得到double:

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

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

我也不知道
严格的真实政策
,听起来很方便

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

(qi::int_ >> !lit('.') >> !lit('e') >> !lit('E')) | qi::float_
如果您看一下上的流程图
您可以看到,这三个字符涵盖了将数字解析为浮点的所有合法方式(在我的特殊问题中)

哇,谢谢你,我不知道
严格的实数策略
模板,这种方法通常是有效的,但在类似的情况下会失败。如果你知道整数部分永远不会丢失,我认为
(int\u>!char(“.eE”)| float
应该是等价的,并且(稍微)噪音更小。这就忘记了跳过程序,所以它应该变成
lexeme[int_>>!char_>>!char(.eE”)];double.
@sehe:在我使用的语法中,我禁用了所有的跳过程序。完整的规则实际上是
非零值=true_124; false|(qi::int_>!lit('.')>>!lit('.')>!lit('.')>!lit('e')>!lit('e')>!lit e'))| qi::float | tstring | lua | string | table;
。但一般来说,我想应该涉及
词素