【发布时间】:2014-07-07 17:35:23
【问题描述】:
我有一个 boost Spirit 解析器,它在 boost 1.46.1 上工作得很好,但在 boost 1.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.46.1 和 boost 1.53 中是不同的。 使用 boost 1.46.1 我有以下输出:
Boost version : 104601
Type : Position
Is Static : 1
Name :toto
Value :1;2;2
使用 boost 1.54 我有:
Boost version : 105400
Type :
Is Static : 1
Name :toto
Value :1;2;2
正如你在 boost 1.54 中看到的,解析器没有填充位置输出。
我阅读了(可能不仔细)Fusion and Spirit 的更新日志,但我不知道为什么会发生这种情况。
有人解释一下吗?
【问题讨论】:
-
你可以看到here
lit和ascii::string的属性。我认为它们自 1.46 以来没有改变,所以我不明白你的代码以前是如何工作的。
标签: boost boost-spirit boost-fusion