2012-03-28 48 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