5

我试图理解以下结果。测试用例代码是

#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/variant/recursive_variant.hpp>
#include <boost/spirit/home/support/context.hpp>
#include <boost/spirit/home/phoenix.hpp>
#include <boost/foreach.hpp>

#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <vector>

namespace sp = boost::spirit;
namespace qi = boost::spirit::qi;
using namespace boost::spirit::ascii;

namespace fusion = boost::fusion;
namespace phoenix = boost::phoenix;

using phoenix::at_c;
using phoenix::push_back;
using phoenix::bind;

template <typename P>
void test_parser(
    char const* input, P const& p, bool full_match = true)
{
    using boost::spirit::qi::parse;

    char const* f(input);
    char const* l(f + strlen(f));
    if (parse(f, l, p) && (!full_match || (f == l)))
        std::cout << "ok" << std::endl;
    else
        std::cout << "fail" << std::endl;
}


int main() {

test_parser("+12345", qi::int_ ); //Ok
test_parser("+12345", qi::double_ - qi::int_ ); //failed, as expected
test_parser("+12345.34", qi::int_ );  // failed, as expected
test_parser("+12345.34", qi::double_ - qi::int_ );  //failed but it should be Ok!
};

这里的动机是我想将数字“12345”匹配为整数,而不是浮点数。'12345.34' 将匹配 double_ 而从不匹配 int_ 但倒数的情况不正确;'12345' 匹配整数 (int_) 和浮点数 (double_)。我尝试了 double_ - int_ 并成功匹配'12345'。但是我希望最后一个测试用例'12345.34'会积极匹配double_ - int_,但我得到的结果是不匹配。

为什么会这样,我如何获得一个只匹配整数和另一个只匹配浮点的解析器(如在 c 中,5.0 将被解释为浮点)

4

2 回答 2

14

对于您的具体示例,我认为它实际上在专业化下的Boost Spirit 文档中进行了描述。RealPolicies为了让你的事情更容易一些,我制作了一个快速的“真实”解析器,它只解析实数而不是整数(或者至少它适用于你的简化示例):

template <typename T>
struct strict_real_policies : qi::real_policies<T>
{
    static bool const expect_dot = true;
};

qi::real_parser< double, strict_real_policies<double> > real;

您可以像使用任何其他解析器(如 int_ 和 double_)一样使用它。您可能需要添加:

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

让它编译。

于 2010-06-26T23:40:11.027 回答
4

double-not-int 的问题qi::double_ - qi::int_在于单个解析器不必匹配整个输入即可成功匹配。对于“+12345.34”,qi::double_ 在整个事物上成功匹配,qi::int 在“+12345”上成功匹配,所以这qi::double_ - qi::int_是不匹配。对于差分运算符,请考虑分别应用每个解析器,以及每个解析器是否存在有效匹配,即使是输入的第一部分。

您可以通过在 qi::int_ 之后要求某种边界来获得所需的行为。当 qi::int_ 匹配浮点数的第一部分是有效浮点数时,接下来会发生什么(例如,“+12345.34”上的 qi::int_ 匹配“+12345”,在流上留下“.34”下一个)。因此,您可以对浮点数进行负面展望:

int_rule %= qi::int_ >> !qi::double_;

double_rule %= qi::double_ - int_rule; 

或者

double_rule %= qi::double_ - (qi::int_ >> !qi::double_); 

!qi::double对于空白和 eoi 也是如此,所以我认为这对于标准格式应该是相当普遍的。不过,这不适用于科学记数法。

于 2010-06-26T23:26:31.593 回答