为什么提振精神:: ::气::解析()未设置此​​的boost ::变种的价值? [英] Why does boost::spirit::qi::parse() not set this boost::variant's value?

查看:185
本文介绍了为什么提振精神:: ::气::解析()未设置此​​的boost ::变种的价值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

<击>当试图解析文本一个boost ::变种,变种的价值没有得到改变。
自己的解析器似乎做工精细,所以我的假设是,我做错事的变种code。

我使用升压1.46.1和<击>以下code编译在的Visual Studio 2008。

1日更新

hkaiser指出,规则和语法模板参数不能是,但变()。结果
这有一点进一步,因为我现在在 boost_1_46_1编译错误\\提升\\变种\\ variant.hpp(1304)。该评论说:

  //注意要USER:
这里//编译错误表示给定类型不是
//明确转换为变体的类型中的一种
//(或无转换存在)。

恩pression的那么显然属性(气:: double_ | +补气::字符_)不是的boost ::变体LT;双人间,标准::字符串&GT; 。但究竟是什么呢?

2日更新

使用的typedef的boost ::变体LT;双,性病::矢量&lt;&字符GT;&GT;变异; 适用于解析器。然而,这并不容易,因为标准::字符串使用...

 的#include&LT;升压/精神/有/ qi.hpp&GT;
#包括LT&;升压/ variant.hpp&GT;诠释的main()
{
    命名空间补气=的boost ::精神::补气;    的typedef的std ::字符串::为const_iterator迭代器;    常量的std ::字符串(富),B(0.5);    //这工作
    {
        标准::字符串stringResult;
        迭代ITA = a.begin();
        常量布尔isStringParsed =
            齐::解析(ITA,a.end(),+补气:: char_,stringResult);        双doubleResult = -1;
        迭代器ITB = b.begin();
        常量布尔isDoubleParsed =
            齐::解析(ITB,b.end(),齐:: double_,doubleResult);        性病::法院
                &LT;&LT; A解析的?&LT;&LT; isStringParsed&LT;&LT;
                值?&LT;&LT; stringResult&LT;&LT; \\ n
                &LT;&LT; B解析的?&LT;&LT; isDoubleParsed&LT;&LT;
                值?&LT;&LT; doubleResult&LT;&LT;的std :: ENDL;        //输出:
        //解析后? 1,价值?富
        // B解析的? 1,价值? 0.5
    }
    //这也适用现在
    {
        TYPEDEF提振::变体LT;双,性病::矢量&lt;&烧焦GT;&GT;变体; //矢量&lt;字符&gt;中不串!        结构variant_grammar:补气::语法&LT;迭代器,变()&GT; //变种(),而不是变!
        {
            齐::规则&LT;迭代器,变()&GT; m_rule; //变种(),而不是变!            variant_grammar():variant_grammar :: base_type(m_rule)
            {
                m_rule%=(气:: double_ | +补气:: char_);
            }
        };        variant_grammar varGrammar;        变异瓦拉(-1),varB(-1);
        迭代ITA = a.begin();
        常量布尔isVarAParsed =齐::解析(ITA,a.end(),varGrammar,翻);
        迭代器ITB = b.begin();
        常量布尔isVarBParsed =齐::解析(ITB,b.end(),varGrammar,varB);        //的std ::矢量&lt;&字符GT;不能投入的std ::法院,但
        需要//被转换为一个std ::字符串(或字符*)在前。
        //我想出的转换是非常丑陋的,但它不是重点
        //这个问题,无论如何,所以我省略了。
        //你得相信我在这里,当我说,它的工作原理..        //输出:
        // A(变种):解析的? 1,价值? foo,那么剩余的文本=''
        // B(变种):解析的? 1,价值? 0.5,剩余的文本=''
    }    返回0;
}


解决方案

该规则的属性必须使用的函数声明语法指定:

 齐::规则&LT;迭代器,变()&GT; m_rule;

我没有试过,但我相信这种变化后,它会工作(同样是必需的语法,顺便说一句)。

When trying to parse text into a boost::variant, the variant's value does not get changed. The parsers by themselves appear to work fine, so my assumption is that I'm doing something wrong with the variant code.

I'm using boost 1.46.1 and the following code compiles in Visual Studio 2008.

1st Update

hkaiser noted that the rule and grammar template arguments must not be Variant but Variant().
This got a bit "further" as I now have a compilation error in boost_1_46_1\boost\variant\variant.hpp(1304). The comment says:

// NOTE TO USER :
// Compile error here indicates that the given type is not 
// unambiguously convertible to one of the variant's types
// (or that no conversion exists).

So apparently the attribute of the expression (qi::double_ | +qi::char_) is not boost::variant<double, std::string>. But what is it then?

2nd Update

Using typedef boost::variant<double, std::vector<char>> Variant; works for the parser. However, this is not as easy to use as std::string...

#include <boost/spirit/include/qi.hpp>
#include <boost/variant.hpp>

int main()
{
    namespace qi = boost::spirit::qi;

    typedef std::string::const_iterator Iterator;

    const std::string a("foo"), b("0.5");

    // This works
    {
        std::string stringResult;
        Iterator itA = a.begin();
        const bool isStringParsed =
            qi::parse(itA, a.end(), +qi::char_, stringResult);

        double doubleResult = -1;
        Iterator itB = b.begin();
        const bool isDoubleParsed =
            qi::parse(itB, b.end(), qi::double_, doubleResult);

        std::cout
                << "A Parsed? " << isStringParsed <<
                ", Value? " << stringResult << "\n"
                << "B Parsed? " << isDoubleParsed <<
                ", Value? " << doubleResult << std::endl;

        // Output:
        // A Parsed? 1, Value? foo
        // B Parsed? 1, Value? 0.5
    }


    // This also works now
    {
        typedef boost::variant<double, std::vector<char>> Variant; // vector<char>, not string!

        struct variant_grammar : qi::grammar<Iterator, Variant()> // "Variant()", not "Variant"!
        {
            qi::rule<Iterator, Variant()> m_rule; // "Variant()", not "Variant"!

            variant_grammar() : variant_grammar::base_type(m_rule)
            {
                m_rule %= (qi::double_ | +qi::char_);
            }
        };

        variant_grammar varGrammar;

        Variant varA(-1), varB(-1);
        Iterator itA = a.begin();
        const bool isVarAParsed = qi::parse(itA, a.end(), varGrammar, varA);
        Iterator itB = b.begin();
        const bool isVarBParsed = qi::parse(itB, b.end(), varGrammar, varB);

        // std::vector<char> cannot be put into std::cout but
        // needs to be converted to a std::string (or char*) first.
        // The conversion I came up with is very ugly but it's not the point
        // of this question anyway, so I omitted it.
        // You'll have to believe me here, when I'm saying it works..

        // Output:
        // A (variant): Parsed? 1, Value? foo, Remaining text = ''
        // B (variant): Parsed? 1, Value? 0.5, Remaining text = ''
    }

    return 0;
}

解决方案

The rule's attribute must be specified using the function declaration syntax:

qi::rule<Iterator, Variant()> m_rule;

I have not tried, but I believe it will work after this change (the same is required for the grammar, btw).

这篇关于为什么提振精神:: ::气::解析()未设置此​​的boost ::变种的价值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆