【问题标题】:boost spirit x3 int32 | double_ fails to parse double提升精神 x3 int32 | double_ 无法解析双精度
【发布时间】:2016-06-19 11:28:34
【问题描述】:

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

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 这样的双精度数

这里是直播demo

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

【问题讨论】:

    标签: c++ parsing c++14 boost-spirit boost-spirit-x3


    【解决方案1】:

    您的问题与this question非常相似。

    当整数解析器首先出现在您的语法中时,它是首选。对于输入"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

    【讨论】:

    • 哇谢谢你我不知道strict_real_policies模板
    【解决方案2】:

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

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

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

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

    【讨论】:

    • 这种方法通常会起作用,但在像this one 这样的情况下它会失败。如果您知道整数部分永远不会丢失,我认为(int_ &gt;&gt; !char_(".eE")) | float_ 应该是等效的并且(稍微)噪音较小。
    • 忘记了船长,所以应该变成lexeme[int_ &gt;&gt; !char_(".eE")] | double_
    • @sehe:在我使用的语法中,我禁用了所有的skipper。完整的规则实际上是non_nil_value = true_ | false_ | (qi::int_ &gt;&gt; !lit('.') &gt;&gt; !lit('e') &gt;&gt; !lit('E')) | qi::float_ | tstring_ | lua_string_ | table;。但总的来说,我想lexeme 应该参与其中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-20
    • 2016-09-10
    相关资源
    最近更新 更多