在解析步骤中的 boost spirit 操作中共享本地数据
share local data in boost spirit actions inside the parse step
我想在语法规则的所有语义操作中共享一个数据。
这个问题的原因是构建解析器对象时的运行时问题。这需要太长时间,我经常需要它们..
目前我使用这个模式来访问规则操作中的共享变量(就像下面的伪代码一样)
struct my_grammar : public qi::grammar<Iterator, common_node(), eol_skipper >
{
int myLocalVar;
int localFunction(parameter)
{
return myLocalVar;
}
myRule1 = (...)[_val = phoenix::bind(&localFunction,this,_1)]
myRule2 = (...)[_val = phoenix::bind(&localFunction,this,_1)]
}
my_grammar worker;
boost::spirit::qi::phrase_parse(first, last, worker, eolSkipper, ret);
那么,是否有一种通用方法可以为解析调用提供 struct/class,而不是在任何规则中访问此数据及其相应的语义操作(期望使用语法对象的完整实例)?
目标应该是这样的
struct myLocalData
{
int myLocalVar;
int localFunction(parameter)
{
return myLocalVar;
}
} ;
struct my_grammar : public qi::grammar<Iterator, common_node(), eol_skipper >
{ // no more local variables here
myRule1 = (...)[_val = phoenix::bind(&localFunction,_ptr_to_instance_object, _1)]
myRule2 = (...)[_val = phoenix::bind(&localFunction,_ptr_to_instance_object, _1)]
}
myLocalData instance; // share this data in all rules
my_grammer worker;
boost::spirit::qi::phrase_parse(first, last, worker, eolSkipper, ret,instance);
自定义迭代器的解决方案有效.. 所以只需添加此迭代器(下面的代码)和“iter_pos”boost::spirit 帮助程序即可在规则内访问此迭代器。有了这个,您可以调用 iter.getData() 来访问所有规则的共享信息
class custom_iterator {
public:
typedef wchar_t value_type;
typedef std::ptrdiff_t difference_type;
typedef const value_type* pointer;
typedef const value_type& reference;
typedef std::forward_iterator_tag iterator_category;
custom_iterator() :handler_(nullptr) { }
custom_iterator(parserDataS* handler, scriptSTDWStringType::const_iterator iter)
:
handler_(handler), iter_(iter)
{ }
custom_iterator& operator++() {
++iter_;
return *this;
}
custom_iterator operator++(int) {
custom_iterator tmp = *this;
iter_++;
return tmp;
}
value_type operator*() const {
return *iter_;
}
friend bool operator==(custom_iterator a, custom_iterator b) {
return a.iter_ == b.iter_;
}
friend bool operator!=(custom_iterator a, custom_iterator b) {
return a.iter_ != b.iter_;
}
scriptSTDWStringType::const_iterator getIter() const { return iter_; }
parserDataS* getData() const { return const_cast<parserDataS *>(handler_); }
private:
scriptSTDWStringType::const_iterator iter_;
parserDataS* handler_;
};
我想在语法规则的所有语义操作中共享一个数据。
这个问题的原因是构建解析器对象时的运行时问题。这需要太长时间,我经常需要它们..
目前我使用这个模式来访问规则操作中的共享变量(就像下面的伪代码一样)
struct my_grammar : public qi::grammar<Iterator, common_node(), eol_skipper >
{
int myLocalVar;
int localFunction(parameter)
{
return myLocalVar;
}
myRule1 = (...)[_val = phoenix::bind(&localFunction,this,_1)]
myRule2 = (...)[_val = phoenix::bind(&localFunction,this,_1)]
}
my_grammar worker;
boost::spirit::qi::phrase_parse(first, last, worker, eolSkipper, ret);
那么,是否有一种通用方法可以为解析调用提供 struct/class,而不是在任何规则中访问此数据及其相应的语义操作(期望使用语法对象的完整实例)?
目标应该是这样的
struct myLocalData
{
int myLocalVar;
int localFunction(parameter)
{
return myLocalVar;
}
} ;
struct my_grammar : public qi::grammar<Iterator, common_node(), eol_skipper >
{ // no more local variables here
myRule1 = (...)[_val = phoenix::bind(&localFunction,_ptr_to_instance_object, _1)]
myRule2 = (...)[_val = phoenix::bind(&localFunction,_ptr_to_instance_object, _1)]
}
myLocalData instance; // share this data in all rules
my_grammer worker;
boost::spirit::qi::phrase_parse(first, last, worker, eolSkipper, ret,instance);
自定义迭代器的解决方案有效.. 所以只需添加此迭代器(下面的代码)和“iter_pos”boost::spirit 帮助程序即可在规则内访问此迭代器。有了这个,您可以调用 iter.getData() 来访问所有规则的共享信息
class custom_iterator {
public:
typedef wchar_t value_type;
typedef std::ptrdiff_t difference_type;
typedef const value_type* pointer;
typedef const value_type& reference;
typedef std::forward_iterator_tag iterator_category;
custom_iterator() :handler_(nullptr) { }
custom_iterator(parserDataS* handler, scriptSTDWStringType::const_iterator iter)
:
handler_(handler), iter_(iter)
{ }
custom_iterator& operator++() {
++iter_;
return *this;
}
custom_iterator operator++(int) {
custom_iterator tmp = *this;
iter_++;
return tmp;
}
value_type operator*() const {
return *iter_;
}
friend bool operator==(custom_iterator a, custom_iterator b) {
return a.iter_ == b.iter_;
}
friend bool operator!=(custom_iterator a, custom_iterator b) {
return a.iter_ != b.iter_;
}
scriptSTDWStringType::const_iterator getIter() const { return iter_; }
parserDataS* getData() const { return const_cast<parserDataS *>(handler_); }
private:
scriptSTDWStringType::const_iterator iter_;
parserDataS* handler_;
};