2012-03-28 26 views
2

如何使用boost ::精神与一个输入,而不是字符?boost ::精神与非标准(非字符串)输入流

在我的情况下,我有一个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和boost :: spirit :: lex :: token <>类似的东西。

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

编辑:

嗯,我回答了我自己的问题。如果有其他人可能会觉得它有用,我会留下来。基本知识解释为here。有一些警告。

  • 我的第一次尝试是使用boost :: variant来描述我的令牌。解析器要求令牌可以转换为布尔值。为了解决这个问题,我将boost :: variant包装在boost :: optional中。编辑:实际上,它似乎是强制执行此要求的调试功能。我目前的解决方案添加了一个自定义的调试处理程序,而不是股票,不再检查迭代器的值是否为“真”。
  • 同样,必须定义运算符< <,至少如果您想要调试输出。
  • 在parse()方法中,您需要检查迭代器是否在解除引用之前不在最后。
  • 如果您有很多令牌类型,您可能需要按照here所述的方式增加MPL向量和列表的大小。
+0

如果你不”在这里得到一个答案尝试在提升精神邮件列表中询问。它非常活跃。 https://lists.sourceforge.net/lists/listinfo/spirit-general – Smittii 2012-03-28 21:27:28

+0

或者如果没有人给你答案,你应该开始质疑,如果使用'boost :: spirit'真的是个好主意。 – 6502 2012-03-29 21:48:09

回答

1

你的自我的回答似乎为解决类似,但不同的问题:

  • 如何创建消耗非字符元素

但是解析器类,你原来的问题更多的是'我怎样才能使用灵魂解析器非char字符流'?

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

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

我没有时间来制定出一个简单的例子,但是,

+0

至于你的第一点,我同意一个程度。我认为这是理所当然的,如果有人能够弄清楚如何编写非字符分析器,那么用法很明显。我的示例的最后3行显示了一个消耗非法令牌的解析器。至于Lex,尽管将Lex与Spirit解析器一起使用会导致解析器消耗非字符标记流(具体来说,它会消耗boost :: spirit :: lex :: token <>流),但确实如此我可以告诉它不可能创建不引用基本字符流的Lex令牌。 – tgoodhart 2012-04-02 15:52:44

+0

@tgoodhart很好的总结。我同意 – sehe 2012-04-02 16:31:05