使用带有 Boost::Spirit Grammars 的迭代器解析

发布于 2024-07-13 13:39:14 字数 1053 浏览 5 评论 0 原文

当我尝试使用迭代器形式解析 Spirit 语法时,出现从迭代器类型到 const char* 的参数传递转换错误。 我该如何解决?

有一些限制。 我在大输入上使用迭代器适配器,因此转换为 C 样式字符串对我来说是不可行的。

以下是演示该问题的示例代码:

#include <boost/spirit/core.hpp>
#include <boost/spirit/iterator/file_iterator.hpp>
#include <vector>
#include <string>
using std;
using boost::spirit;
struct ex : public grammar<route_grammar> {
  template <typename ScannerT> struct defintion {
    definition(ex const& self) {
      expression = real_p; 
    }
    rule<ScannerT> expression;
    rule<ScannerT> const& start() const { return expression; }
};

int main() {
  file_iterator<char> first;
  file_iterator<char> last = first.make_end();
  ex ex_p;
  parse_info<file_iterator<char> > info = parse(first, last, ex_p, space_p);
  return 0;
}

此代码中断:错误:无法转换 const boost::spirit::file_iterator; >const char* 参数传递

When I attempt to use the iterator form of parsing for a Spirit grammar I get a argument passing conversion error from the iterator type to const char*. How do I fix this?

There are some restrictions. I'm using an iterator adapter on large inputs, so it is not feasible for me to convert to a C style string.

Here is sample code demonstrating the issue:

#include <boost/spirit/core.hpp>
#include <boost/spirit/iterator/file_iterator.hpp>
#include <vector>
#include <string>
using std;
using boost::spirit;
struct ex : public grammar<route_grammar> {
  template <typename ScannerT> struct defintion {
    definition(ex const& self) {
      expression = real_p; 
    }
    rule<ScannerT> expression;
    rule<ScannerT> const& start() const { return expression; }
};

int main() {
  file_iterator<char> first;
  file_iterator<char> last = first.make_end();
  ex ex_p;
  parse_info<file_iterator<char> > info = parse(first, last, ex_p, space_p);
  return 0;
}

This code breaks with: error: cannot convert const boost::spirit::file_iterator<char_t, boost::spirit::fileiter_impl::mmap_file_iterator<char_t> > to const char* in argument passing

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

鲜肉鲜肉永远不皱 2024-07-20 13:39:15

编译错误不在提供的示例中。 在上面的语法中,我没有语义操作,而在我简化的代码中,我做了。

这些操作的回调使用 char* 而不是我使用的迭代器类型。

The compilation error was not in the sample provided. In the grammar above I have no semantic actions, while in the code I was simplifying I did.

The callbacks for those actions used char* instead of the iterator type I was using.

一人独醉 2024-07-20 13:39:15

您可以尝试确保您的语义操作在参数类型上是多态的。 准确地说,在代码中,您需要这样的操作:

struct my_action {
  template <class ParamType>
  void operator()(ParamType const & parameter) const {
    // deal with parameter
  }
};

您将使用如下所示的一元语义操作:

real_p[my_action()]

或者,如果您需要二元语义操作,您将执行以下操作:

struct binary_action {
  template <class ParamType>
  void operator()(ParamType const & param1, ParamType const & param2) const {
    // deal with either parameter
  }
};

(*char_p)[binary_action()]

You can try making sure that your semantic actions were polymorphic on the type of the argument. Precisely in code you'd want something like this:

struct my_action {
  template <class ParamType>
  void operator()(ParamType const & parameter) const {
    // deal with parameter
  }
};

You'd use a unary semantic action like this as shown below:

real_p[my_action()]

Or if you needed a binary semantic action, you'd do something like:

struct binary_action {
  template <class ParamType>
  void operator()(ParamType const & param1, ParamType const & param2) const {
    // deal with either parameter
  }
};

(*char_p)[binary_action()]
溺ぐ爱和你が 2024-07-20 13:39:14

很难从发布的代码中看出,因为它包含一些基本错误。
修正这些之后,它在我的机器上编译良好(使用 MSVC++7.1):

#include <boost/spirit/core.hpp>
#include <vector>
#include <string>
using namespace std;
using namespace boost::spirit;
struct ex : public grammar<ex> {
template <typename ScannerT> 
struct definition {
    definition(ex const& self)
    {
    expression = real_p; 
    }
    rule<ScannerT> expression;
    rule<ScannerT> const& start() const { return expression; }
};
};

int main() {
vector<char> v;
v.push_back('3'); v.push_back('.'); v.push_back('2');
ex ex_p;
parse_info<vector<char>::iterator> info = parse(v.begin(), v.end(), ex_p, space_p);
return 0;
}

Hard to tell from the code as posted, since it contains a few basic errors.
After correction of these, it compiles fine on my machine (with MSVC++7.1):

#include <boost/spirit/core.hpp>
#include <vector>
#include <string>
using namespace std;
using namespace boost::spirit;
struct ex : public grammar<ex> {
template <typename ScannerT> 
struct definition {
    definition(ex const& self)
    {
    expression = real_p; 
    }
    rule<ScannerT> expression;
    rule<ScannerT> const& start() const { return expression; }
};
};

int main() {
vector<char> v;
v.push_back('3'); v.push_back('.'); v.push_back('2');
ex ex_p;
parse_info<vector<char>::iterator> info = parse(v.begin(), v.end(), ex_p, space_p);
return 0;
}
原谅过去的我 2024-07-20 13:39:14

这是让 char * 指向与迭代器相同的元素的一种方法:

&v.front() // v.begin()
&v.back() + 1 // v.end()

我不确定如何编译它:

vector<char> v;
v.push_back("3.2");

Here is one way of getting the char *'s pointing at the same elements as the iterators:

&v.front() // v.begin()
&v.back() + 1 // v.end()

I'm not sure how you got this to compile though:

vector<char> v;
v.push_back("3.2");
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文