使用非标准(非字符串)输入流的boost :: spirit

时间:2012-03-28 19:32:43

标签: c++ parsing boost boost-spirit

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

就我而言,我有一个std :: vector< AbstractBaseClass>我想把它作为一个标记流处理成我的语法,其中每个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&lt;&gt;的东西。和boost :: spirit :: lex :: token&lt;&gt;。

我已经考虑直接使用这些,但是这两个类似乎假设在lexer标记下有一个原始字符流,在我的情况下不是这样;我直接得到了令牌。

编辑:

好吧,我回答了自己的问题。我会留下这个以防万一其他人可能觉得它有用。基础知识解释here。有一些警告。

  • 我的第一次尝试是使用boost :: variant来描述我的标记。解析器要求令牌可转换为bool。为了解决这个问题,我将boost :: variant包装在boost :: optional中。编辑:实际上,似乎是调试功能强加了这个要求。我当前的解决方案添加了一个自定义调试处理程序,而不是一个不再检查迭代器的值是否为“true”的库存。
  • 类似地,运营商&lt;&lt;必须定义,至少如果你想要调试输出。
  • 在parse()方法中,您需要在取消引用之前检查迭代器是否在最后。
  • 如果您有许多令牌类型,您可能需要按照here所述增加MPL向量和列表的大小。

1 个答案:

答案 0 :(得分:1)

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

  • 如何创建使用非char元素的解析器类

但是,您的原始问题更像是如何使用精神解析器与非char标记流&#39;?

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

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

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