Boost 这是一种精神回归吗?

Boost 这是一种精神回归吗?,boost,boost-spirit,boost-fusion,Boost,Boost Spirit,Boost Fusion,我有一个BoostSpirit解析器,它与Boost1.46.1配合得很好,但与Boost1.54不配合 该解析器从以下语句中提取信息,这是DSEL中的变量初始化:“Position#start=0;0;0”。 从这句话中提取的信息存储在一个结构中: 将存储变量的类型(此处为位置) 变量名称(此处为开始) “#”表示变量为“静态” 变量的值(0;0;0) 提取这些信息的代码如下所示: #include <iostream> #include <boost/spirit/in

我有一个BoostSpirit解析器,它与Boost1.46.1配合得很好,但与Boost1.54不配合

该解析器从以下语句中提取信息,这是DSEL中的变量初始化:“Position#start=0;0;0”。 从这句话中提取的信息存储在一个结构中:

  • 将存储变量的类型(此处为位置)
  • 变量名称(此处为开始)
  • “#”表示变量为“静态”
  • 变量的值(0;0;0)
提取这些信息的代码如下所示:

#include <iostream>
#include <boost/spirit/include/classic.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/include/qi_char_class.hpp>

using namespace std;
using namespace boost::spirit;

struct VariableInitialization
{
    std::string m_type;
    bool m_is_static;
    std::string m_name;
    std::string m_value;
};

BOOST_FUSION_ADAPT_STRUCT(
        VariableInitialization,
        (std::string, m_type)
        (bool, m_is_static)
        (std::string, m_name)
        (std::string, m_value)
        )

template <typename Iterator>
struct VariableInitializationParser : qi::grammar<Iterator, VariableInitialization(), ascii::space_type> {
/*!
* IsStatic is a mapping betwen a char and a boolean
*/
struct IsStatic_ : qi::symbols<char, bool> {
    IsStatic_()
    {
        add("@", false)("#", true);
    }
}IsStatic;

VariableInitializationParser() :
    VariableInitializationParser::base_type(start) {
    using qi::lit;
    using ascii::char_;
    using qi::_val;
    using qi::_1;
    /*!
     * For now, type is one of the three following litterals :
     */
    var_type %= lit("Position")|lit("String")|lit("Numeric")|lit("Integer")|lit("Trajectory");

    /*!
     * identifier is how a variable can be named. Name of variable is an alpha (a-zA-Z) or an _,followed
     * by any alpha numeric (a-zA-Z0-9) or a _. The followings are correct :
     * _toto _T5ot_To t1oTo ...
     * The following are incorrect
     * 12toto -tiotp ...
     */
    identifier %= ((ascii::alpha|char_('_')) >> *(ascii::alnum|char_('_')));

    /*!
     * var value can be anything because it's parsed by someone else.
     */
    var_value %= qi::lexeme[*(char_)];
    start = var_type >> IsStatic >> identifier >> '=' >> var_value;
}
qi::rule<Iterator, std::string(), ascii::space_type> var_type;
qi::rule<Iterator, std::string(), ascii::space_type> identifier;
qi::rule<Iterator, std::string(), ascii::space_type> var_value;
qi::rule<Iterator, VariableInitialization(), ascii::space_type> start;
};

int main()
{
    VariableInitialization variable;

    std::string input = "Position #toto=1;2;2";
    std::string::const_iterator iter = input.begin();
    std::string::const_iterator end = input.end();
    // The phrase_parse call wil fill the structure "variable" with the good values if the syntax is correct.
    // if the syntax is not correct, the method will return false.
    // So if input = "Integer #toto= 6", variable.m_type == "Integer", variable.m_isStatic==true,
    // variable.m_name=="toto" and variable.m_vale="6".
    VariableInitializationParser<std::string::const_iterator> m_parser;
    bool ok = phrase_parse(iter, end, m_parser, boost::spirit::ascii::space, variable);
    if(!ok) return false;
    std::cout << "Boost version : " << BOOST_VERSION << std::endl;
    std::cout << "Type : " << variable.m_type << std::endl
              << "Is Static : " << variable.m_is_static << std::endl
              << "Name :" << variable.m_name << std::endl
              << "Value :" << variable.m_value << std::endl;
    return 0;
}
使用boost 1.54,我有:

Boost version : 105400
Type : 
Is Static : 1
Name :toto
Value :1;2;2
正如您在boost 1.54中所看到的,解析器没有填充位置输出

我读过(也许不是很仔细)融合和精神的变化记录,我不知道为什么会发生这种情况


有人有解释吗?

没有,这不是回归。很明显,您依赖于未记录(可能未定义)的行为

只需将
lit
更改为
string
,或者稍微紧凑一点:

var_type = qi::raw[lit("Position")|"String"|"Numeric"|"Integer"|"Trajectory"];
查看它

#include <iostream>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/adapt_struct.hpp>

using namespace std;
using namespace boost::spirit;

struct VariableInitialization
{
    std::string m_type;
    bool m_is_static;
    std::string m_name;
    std::string m_value;
};

BOOST_FUSION_ADAPT_STRUCT(
        VariableInitialization,
        (std::string, m_type)
        (bool, m_is_static)
        (std::string, m_name)
        (std::string, m_value)
        )

template <typename Iterator>
struct VariableInitializationParser : qi::grammar<Iterator, VariableInitialization(), ascii::space_type> {
    struct IsStatic_ : qi::symbols<char, bool> {
        IsStatic_() {
            add("@", false)("#", true);
        }
    } IsStatic;

    VariableInitializationParser() :
        VariableInitializationParser::base_type(start) {
            using qi::lit;
            using ascii::char_;

            var_type   = qi::raw[lit("Position")|"String"|"Numeric"|"Integer"|"Trajectory"];

            identifier = (ascii::alpha|'_') >> *(ascii::alnum|'_');

            var_value  = qi::lexeme[*(char_)];
            start      = var_type >> IsStatic >> identifier >> '=' >> var_value;
        }

    qi::rule<Iterator, std::string(), ascii::space_type> var_type;
    qi::rule<Iterator, std::string(), ascii::space_type> identifier;
    qi::rule<Iterator, std::string(), ascii::space_type> var_value;
    qi::rule<Iterator, VariableInitialization(), ascii::space_type> start;
};

int main()
{
    VariableInitialization variable;

    std::string input = "Position #toto=1;2;2";
    std::string::const_iterator iter = input.begin();
    std::string::const_iterator end = input.end();

    VariableInitializationParser<std::string::const_iterator> m_parser;

    bool ok = phrase_parse(iter, end, m_parser, boost::spirit::ascii::space, variable);
    if(!ok) return false;

    std::cout << "Boost version : " << BOOST_VERSION        << "\n";
    std::cout << "Type : "          << variable.m_type      << "\n"
              << "Is Static : "     << variable.m_is_static << "\n"
              << "Name :"           << variable.m_name      << "\n"
              << "Value :"          << variable.m_value     << "\n";
}
#包括
#包括
#包括
使用名称空间std;
使用名称空间boost::spirit;
结构变量初始化
{
std::字符串m_类型;
布尔m_是静态的;
std::字符串m_名称;
std::字符串m_值;
};
增强融合适应结构(
变量初始化,
(标准::字符串,m_类型)
(布尔,m_是静态的)
(标准::字符串,m_名称)
(标准::字符串,m_值)
)
模板
结构变量初始化解析器:qi::grammar{
结构IsStatic:qi::符号{
IsStatic_uuz(){
加上(“@”,false)(“#”,true);
}
}不稳定;
VariableInitializationParser():
VariableInitializationParser::基本类型(开始){
使用qi::lit;
使用ascii::char;
var_type=qi::raw[lit(“位置”)|“字符串”|“数值”|“整数”|“轨迹”];
标识符=(ascii::alpha |‘’>>*(ascii::alnum |‘’);
var_value=qi::lexeme[*(char_)];
开始=变量类型>>IsStatic>>标识符>>'='>>变量值;
}
qi::规则变量类型;
qi::规则标识符;
qi::规则变量值;
qi::规则开始;
};
int main()
{
变量初始化变量;
std::string input=“Position#toto=1;2;2”;
std::string::const_迭代器iter=input.begin();
std::string::const_迭代器end=input.end();
变量初始化解析器m_解析器;
bool ok=phrase_parse(iter,end,m_解析器,boost::spirit::ascii::space,变量);
如果(!ok)返回false;
std::你能看到
lit
ascii::string
的属性吗?我想它们从1.46开始就没有改变过,所以我不明白你的代码以前是如何工作的。
#include <iostream>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/adapt_struct.hpp>

using namespace std;
using namespace boost::spirit;

struct VariableInitialization
{
    std::string m_type;
    bool m_is_static;
    std::string m_name;
    std::string m_value;
};

BOOST_FUSION_ADAPT_STRUCT(
        VariableInitialization,
        (std::string, m_type)
        (bool, m_is_static)
        (std::string, m_name)
        (std::string, m_value)
        )

template <typename Iterator>
struct VariableInitializationParser : qi::grammar<Iterator, VariableInitialization(), ascii::space_type> {
    struct IsStatic_ : qi::symbols<char, bool> {
        IsStatic_() {
            add("@", false)("#", true);
        }
    } IsStatic;

    VariableInitializationParser() :
        VariableInitializationParser::base_type(start) {
            using qi::lit;
            using ascii::char_;

            var_type   = qi::raw[lit("Position")|"String"|"Numeric"|"Integer"|"Trajectory"];

            identifier = (ascii::alpha|'_') >> *(ascii::alnum|'_');

            var_value  = qi::lexeme[*(char_)];
            start      = var_type >> IsStatic >> identifier >> '=' >> var_value;
        }

    qi::rule<Iterator, std::string(), ascii::space_type> var_type;
    qi::rule<Iterator, std::string(), ascii::space_type> identifier;
    qi::rule<Iterator, std::string(), ascii::space_type> var_value;
    qi::rule<Iterator, VariableInitialization(), ascii::space_type> start;
};

int main()
{
    VariableInitialization variable;

    std::string input = "Position #toto=1;2;2";
    std::string::const_iterator iter = input.begin();
    std::string::const_iterator end = input.end();

    VariableInitializationParser<std::string::const_iterator> m_parser;

    bool ok = phrase_parse(iter, end, m_parser, boost::spirit::ascii::space, variable);
    if(!ok) return false;

    std::cout << "Boost version : " << BOOST_VERSION        << "\n";
    std::cout << "Type : "          << variable.m_type      << "\n"
              << "Is Static : "     << variable.m_is_static << "\n"
              << "Name :"           << variable.m_name      << "\n"
              << "Value :"          << variable.m_value     << "\n";
}