【问题标题】:boost::spirit with non-standard (non-string) input stream具有非标准(非字符串)输入流的 boost::spirit
【发布时间】:2012-04-12 10:52:20
【问题描述】:

如何将 boost::spirit 与包含字符以外的其他内容的输入一起使用?

就我而言,我有一个 std::vector,我想将其视为语法中的令牌流,其中每个 AbstractBaseClass 都是一个令牌。比如:

struct AbstractBaseClass
{
};

struct ConcreteClassA : public AbstractBaseClass
{
};

struct ConcreteClassB : public AbstractBaseClass
{
};


std::vector<AbstractBaseClass> stream;
std::vector<AbstractBaseClass>::iterator iter = stream.begin();
std::vector<AbstractBaseClass>::iterator end = stream.end();
bool r = boost::spirit::qi::parse( iter, end, TOKEN_ID_FOR_CONCRETE_CLASS_A >> TOKEN_ID_FOR_CONCRETE_CLASS_B >> TOKEN_ID_FOR_CONCRETE_CLASS_A );

我需要将哪些方法添加到我的类中/令牌 ID 应该是什么样子才能支持这一点?

大概我需要提供一些类似于 boost::spirit::lex::token_def 和 boost::spirit::lex::token 的东西。

我已经研究过直接使用这些,但是这两个类似乎假设在词法分析器标记下有一个原始字符流,这在我的情况下是不正确的;我直接拿到token。

编辑:

好吧,我回答了我自己的问题。我会留下这个,以防其他人发现它有用。 here 解释了基础知识。有一些注意事项。

  • 我的第一次尝试是使用 boost::variant 来描述我的令牌。解析器要求标记可转换为布尔值。为了解决这个问题,我将 boost::variant 包裹在 boost::optional 中。编辑:实际上,似乎是调试能力强加了这个要求。我当前的解决方案添加了一个自定义调试处理程序,而不是不再检查迭代器的值是否为“true”的库存处理程序。
  • 类似地,必须定义运算符
  • 在 parse() 方法中,您需要在取消引用之前检查您的迭代器是否不在末尾。
  • 如果您有很多标记类型,您可能需要增加 MPL 向量和列表的大小,如 here 所述。

【问题讨论】:

  • 如果您在这里没有得到答案,请尝试在提升精神邮件列表中提问。它非常活跃。 lists.sourceforge.net/lists/listinfo/spirit-general
  • 或者如果没有人在这里给你答案,你应该开始质疑使用boost::spirit是否真的是个好主意。

标签: c++ parsing boost boost-spirit


【解决方案1】:

您的自我回答似乎解决了一个类似但不同的问题:

  • 如何创建一个使用非字符元素的解析器类

但是,您最初的问题更像是“我如何将精神解析器与非字符令牌流一起使用”?

在这种情况下,最有用的链接是Spirit Lex,它是集成到 Boost Spirit 框架中的 LexerTL。

如有必要,您可以轻松地使 Spirit Lex 公开令牌信息(超出令牌 ID),尽管默认情况下源迭代器范围始终可用。这样一来,您就可以非常灵活地混合搭配 Spirit Lex 和 Spirit Qi。

我没有时间做一个简单的例子,但是,

【讨论】:

  • 至于你的第一点,我在一定程度上同意。我理所当然地认为,如果有人能弄清楚如何编写非字符解析器,那么用法就很明显了。我的示例的最后 3 行显示了一个使用任意标记的解析器。至于 Lex,虽然将 Lex 与 Spirit 解析器一起使用确实会导致解析器消耗一个非字符标记流(具体来说,它消耗一个 boost::spirit::lex::token 流),但就我可以看出不可能创建不引用基本字符流的 Lex 标记。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多