【发布时间】:2014-05-21 16:09:07
【问题描述】:
我想改变语义动作中的局部变量值,如下所示:
#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <string>
namespace qi = boost::spirit::qi;
namespace spirit = boost::spirit;
namespace ascii = boost::spirit::ascii;
using boost::phoenix::ref;
using boost::phoenix::bind;
void dummy(const std::vector<char>& v, int& var)
{
var = 7;
}
template <typename Iterator>
struct x_grammar : public qi::grammar<Iterator, std::string(), ascii::space_type>
{
public:
x_grammar() : x_grammar::base_type(start_rule, "x_grammar")
{
using namespace qi;
int local_var = 0;
start_rule = (+(char_ - ";"))[bind(dummy, _1, ref(local_var))];
//repeat(ref(local_var))[some_rule];
}
private:
qi::rule<Iterator, std::string(), ascii::space_type> start_rule;
};
int main()
{
typedef std::string::const_iterator iter;
std::string storage("string;aaa");
iter it_begin(storage.begin());
iter it_end(storage.end());
std::string read_data;
using boost::spirit::ascii::space;
x_grammar<iter> g;
try {
bool r = qi::phrase_parse(it_begin, it_end, g, space, read_data);
std::cout << "Pass!\n";
} catch (const qi::expectation_failure<iter>& x) {
std::cout << "Error!\n";
}
}
我在使用 GCC 4.6.1 和 boost 1.55 时遇到一些烦人的编译错误。
【问题讨论】:
-
局部变量只“存在”到构造函数结束。如果您想做类似的事情,您需要使变量成为语法的成员(或者可能将其作为参数传递给构造函数)。同样使用
boost::phoenix::bind(或ref)和 c++11 编译器在没有命名空间限定的情况下与命名空间 std(在这种情况下为std::vector)中的类的参数一起使用时会出现 ADL 问题。你应该使用类似namespace phx=boost::phoenix;... phx::bind(dummy,_1,phx::ref(local_var));的东西。
标签: c++ boost boost-spirit boost-spirit-qi boost-phoenix