Spirit Boost real_p解析器行为奇怪

Spirit Boost real_p parser behaving strangely

本文关键字:Boost real Spirit      更新时间:2023-10-16

我有以下问题:我正在重用使用real_p解析器解析实数的旧代码。我想捕获每个数字,将其转换为字符串,并将其放入字符串向量中。我使用下面的代码,其中l_double是double类型的变量,convertdouble函数将double类型转换为字符串,以及result。m_literalValues是字符串向量。但是,代码不会将解析后的值赋给l_double。

rule<> alternative3 =   +(real_p        [assign_a(l_double)]
                                        [push_back_a(result.m_LiteralValues, convertdouble(l_double))]
                                        >>  str_p(",")
                            )

有谁知道我做错了什么吗?

注意:我不会重新设计旧代码,这比给出的例子要复杂得多。我只是想提取所有已解析值的字符串,并将它们放入字符串向量中。

问题似乎在push_back_a(result.m_LiteralValues, convertdouble(l_double)),特别是在convertdouble(l_double)push_back_a要求它的第二个参数是存储在"策略持有人参与者"中的引用,因此使用函数调用会导致错误。如果您不需要存储l_double,而只是将其作为临时对象使用,那么完成所需任务的一种方法是创建您自己的phoenix函数,其行为类似于这里所解释的push_back_a(完整示例在这里)。您可以这样定义phoenix函数:

struct push_back_impl
{
    template <typename Container, typename Item>
    struct result
    {
        typedef void type;
    };
    template <typename Container, typename Item>
    void operator()(Container& c, Item const& item) const
    {
        c.push_back(convertdouble(item));
    }
};
function<push_back_impl> const push_back = push_back_impl();

,然后像这样定义规则:

rule<> alternative3 =   +( real_p[push_back(var(result.m_LiteralValues),arg1)] >>  str_p(",") );

完整的可编译代码(如果不能或不想使用c++11,请更改for循环以显示结果):

#include <boost/spirit/include/classic_core.hpp>
#include <boost/spirit/include/classic_operators.hpp>
#include <boost/spirit/include/phoenix1_functions.hpp>
#include <boost/spirit/include/phoenix1_primitives.hpp>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
using namespace boost::spirit::classic;
using namespace phoenix;
std::string convertdouble(const double& d)
{   
    std::stringstream ss;
    ss<<d;
    return ss.str();
}
struct push_back_impl
{
    template <typename Container, typename Item>
    struct result
    {
        typedef void type;
    };
    template <typename Container, typename Item>
    void operator()(Container& c, Item const& item) const
    {
        c.push_back(convertdouble(item));
    }
};
function<push_back_impl> const push_back = push_back_impl();
struct Results
{
    std::vector<std::string> m_LiteralValues;
};

int main()
{
    Results result;
    char const* test="2.5,3.6,4.8,";
    rule<> alternative3 =   +( real_p[push_back(var(result.m_LiteralValues),arg1)] >>  str_p(",") );
    if(parse(test,alternative3,space_p).full)
    {
        std::cout << "success" << std::endl;
        for(auto& str :result.m_LiteralValues)
            std::cout << str << std::endl;
    }
    else
    {
        std::cout << "failure" << std::endl;
    }
    return 0;                       
}