我有一個由混合變量($(name)
)和變量值對($(name:value)
)組成的簡單文法。我有一個手工編碼的遞歸解析器,但有興趣將它用作學習Spirit的練習,最終(/很快)我將需要它來使用更復雜的語法。使用Boost.Spirit解析混合值和鍵值對
總之,一套我與(簡化從完整的語法)工作可能的形式是:
$(variable) // Uses simple look-up, recursion and inline replace
$(name:value) // Inserts a new variable into the local lookup table
我現在的規則是這樣:
typedef std::map<std::string, std::string> dictionary;
template <typename Iterator>
bool parse_vars(Iterator first, Iterator last, dictionary & vars, std::string & output)
{
using qi::phrase_parse;
using qi::_1;
using ascii::char_;
using ascii::string;
using ascii::space;
using phoenix::insert;
dictionary statevars;
typedef qi::rule<Iterator, std::string()> string_rule;
typedef qi::rule<Iterator, std::pair<std::string, std::string>()> pair_rule;
string_rule state = string >> ':' >> string; // Error 3
pair_rule variable =
(
char_('$') >> '(' >>
(
state[insert(phoenix::ref(statevars), _1)] |
string[output += vars[_1]] // Error 1, will eventually need to recurse
) >> ')'
); // Error 2
bool result = phrase_parse
(
first, last,
(
variable % ','
),
space
);
return r;
}
如果:這不是什麼很明顯,我不知道Spirit是如何工作的,而且文檔除了實際的解釋之外都有其他的東西,所以這大概需要一個小時的時間。
零件在可變規則我特別問題是領先的char_('$')
,但除去這會導致移位運算錯誤(編譯器解釋'$' >> '('
作爲右移位)。
編譯時,我得到有關狀態規則,特別是創造了對錯誤,並查找:
- 錯誤C2679:二進制「[」:沒有操作員發現這需要右手類型'const boost :: spirit :: _ 1_type'的操作數(或者沒有可接受的轉換)
- 錯誤C2512:'boost :: spirit :: qi :: rule :: rule':沒有適當的默認構造函數可用
更改查找(vars[_1]
)以簡單的+=
給出:
。錯誤C2665:「的boost ::精神:: char_class ::分類::是」:沒有15個重載可以轉換所有的參數類型
錯誤1似乎涉及到的類型(屬性?)的_1
佔位符,但應該是一個字符串,並且在用於打印或連接到輸出字符串時是。 2似乎引起的噪音1.
錯誤3,向下挖掘模板的誤差的疊層,似乎涉及不能夠轉動狀態規則成一對,這似乎奇數,因爲它幾乎完全匹配其中一條規則從this example。
如何修改變量規則以正確處理兩個輸入表單?
@peachykeen:我已經修復了我的代碼示例(我一直在用我的鼻子閱讀,因爲我完全錯過了'parse_vars' _template function_甚至沒有實例化的事實:)現在它運行並且測試對我來說確定。 – sehe 2012-02-05 16:48:15
我打算說,我試過了,它給了類似的錯誤;將在今天晚些時候再次測試,並讓你知道發生了什麼。 :) – ssube 2012-02-07 14:23:09
對於子集文法,更新實際上工作得很好。現在我必須補充其餘的... – ssube 2012-02-09 00:17:03