【发布时间】:2012-07-23 04:23:42
【问题描述】:
template <typename Iterator>
struct parse_grammar
: qi::grammar<Iterator, std::string()>
{
parse_grammar()
: parse_grammar::base_type(start_p, "start_p"){
a_p = ',' > qi::double_;
b_p = *a_p;
start_p = qi::double_ > b_p >> qi::eoi;
}
qi::rule<Iterator, std::string()> a_p;
qi::rule<Iterator, std::string()> b_p;
qi::rule<Iterator, std::string()> start_p;
};
// implementation
std::vector<double> parse(std::istream& input, const std::string& filename)
{
// iterate over stream input
typedef std::istreambuf_iterator<char> base_iterator_type;
base_iterator_type in_begin(input);
// convert input iterator to forward iterator, usable by spirit parser
typedef boost::spirit::multi_pass<base_iterator_type> forward_iterator_type;
forward_iterator_type fwd_begin = boost::spirit::make_default_multi_pass(in_begin);
forward_iterator_type fwd_end;
// prepare output
std::vector<double> output;
// wrap forward iterator with position iterator, to record the position
typedef classic::position_iterator2<forward_iterator_type> pos_iterator_type;
pos_iterator_type position_begin(fwd_begin, fwd_end, filename);
pos_iterator_type position_end;
parse_grammar<pos_iterator_type> gram;
// parse
try
{
qi::phrase_parse(
position_begin, position_end, // iterators over input
gram, // recognize list of doubles
ascii::space); // comment skipper
}
catch(const qi::expectation_failure<pos_iterator_type>& e)
{
const classic::file_position_base<std::string>& pos = e.first.get_position();
std::stringstream msg;
msg <<
"parse error at file " << pos.file <<
" line " << pos.line << " column " << pos.column << std::endl <<
"'" << e.first.get_currentline() << "'" << std::endl <<
" " << "^- here";
throw std::runtime_error(msg.str());
}
// return result
return output;
}
我有上面的示例代码(此处使用的代码来自 boost-spirit 网站)。
在规则 a_p 的语法中,我想使用语义动作并调用一个方法并将迭代器传递给它,如下所示:
a_p = ',' > qi::double_[boost::bind(&parse_grammar::doStuff(), this,
boost::ref(position_begin), boost::ref(position_end)];
如果方法doStuff的签名是这样的:
void doStuff(pos_iterator_type const& first, pos_iterator_type const& last);
任何想法如何做到这一点? 只要迭代器以其当前状态传递的方法,我不介意任何方式(如果我可以使用 boost::phoenix 或不确定如何做到这一点)。
【问题讨论】:
-
任何帮助将不胜感激,因为我急需解决方案。
-
可悲的是,他们的方式如此有效,当您赶时间时,这对我们来说并不重要。下一次,您将希望将其设为SSCCE,并解释一下您为什么/尝试实现(而不是仅仅解释您认为您将如何实现它)。这消除了潜在回答者的两个关闭。 (我很努力地回答大多数 Spirit 问题,但即使我也不必总是有时间找出你忘记为我列出的 6 个头文件,以及你使用了哪些命名空间等)
-
@sehe :对于头文件和命名空间真的很抱歉,是粘贴代码的错误。下次会记住它,也会编辑上面的代码。发生这种情况是因为我不想在这里粘贴大量代码。
标签: c++ parsing boost-spirit boost-spirit-qi