【发布时间】:2012-02-26 14:03:11
【问题描述】:
我在使用 boost::spirit 制作的计算器时遇到了一个奇怪的问题。这个计算器应该把一个字符串作为参数,代表一系列用逗号分隔的算术表达式,比如“a+4*5,77,(b-c)*4”。它还允许字符串“?”并在这种情况下返回包含 -1 的数组。计算器使用 SymTable 进行初始化,这是一个模板类参数,用于描述任何提供 [string] -> int 运算符(例如:映射)的类,以解析变量的值。
以下代码适用于我的 Ubuntu 10.4,同时使用 gcc 4.6.2 和 gcc 4.4,以及 boost 1.47 和 1.48。过去它也可以在具有 gcc 4.5.3 和 boost 1.47 的 Cray Linux 机器上工作。
#include <boost/bind.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
namespace sp = boost::spirit;
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace Damaris {
template <typename Iterator, typename SymTable>
struct Calc : qi::grammar<Iterator, std::vector<int>(), ascii::space_type>
{
qi::rule<Iterator, std::vector<int>(), ascii::space_type> start;
qi::rule<Iterator, int(), ascii::space_type> expr;
qi::rule<Iterator, int(), ascii::space_type> qmark;
qi::rule<Iterator, int(), ascii::space_type> factor;
qi::rule<Iterator, int(), ascii::space_type> simple;
qi::rule<Iterator, std::string(), ascii::space_type> identifier;
qi::rule<Iterator, int(SymTable), ascii::space_type> value;
/**
* \brief Constructor.
* \param[in] sym : table of symboles.
*/
Calc(SymTable &sym) : Calc::base_type(start)
{
identifier = qi::lexeme[( qi::alpha | '_') >> *( qi::alnum | '_')];
value = identifier[qi::_val = qi::labels::_r1[qi::_1]];
simple = ('(' >> expr >> ')')
| qi::int_
| value(boost::phoenix::ref(sym));
factor %= (simple >> '*' >> factor)[qi::_val = qi::_1 * qi::_2]
| (simple >> '/' >> factor)[qi::_val = qi::_1 / qi::_2]
| (simple >> '%' >> factor)[qi::_val = qi::_1 % qi::_2]
| simple;
expr %= (factor >> '+' >> expr)[qi::_val = qi::_1 + qi::_2]
| (factor >> '-' >> expr)[qi::_val = qi::_1 - qi::_2]
| factor;
qmark = qi::char_('?')[qi::_val = -1];
start = qmark
| (expr % ',');
}
};
}
今天我再次尝试在 Cray 机器上编译相同的代码(我认为从那时起已经升级了),我尝试使用 gcc 4.6.2 和 gcc 4.5.2,以及 boost 1.48 和 1.49,然后我总是得到我不理解的相同编译错误:
/nics/b/home/mdorier/damaris-0.4/common/Calc.hpp:74:3: instantiated from 'Damaris::Calc<Iterator, SymTable>::Calc(SymTable&) [with Iterator = __gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >, SymTable = Damaris::ParameterSet]'
/nics/b/home/mdorier/damaris-0.4/common/MetadataManager.cpp:45:79: instantiated from here
/nics/b/home/mdorier/deploy/include/boost/spirit/home/qi/detail/assign_to.hpp:123:13: error: invalid static_cast from type 'const boost::fusion::vector2<int, int>' to type 'int'
Calc.hpp 中的第 74 行对应于“factor = ...”行。 指示的实例化行 (MetadataManager.cpp:45) 如下:
layoutInterp = new Calc<std::string::const_iterator,ParameterSet>(*parameters);
layoutInterp 的类型为 Calc*,参数的类型为 ParameterSet*。
知道这个错误是从哪里来的吗?谢谢
【问题讨论】:
标签: c++ boost-spirit