2012-11-13 109 views
2

我有一個包含SPIRIT語法不包括保留字:解析標識符,但在BOOST精神

small %= char_("a-z"); 
large %= char_("A-Z"); 
digit %= char_("0-9"); 
symbol %= char_("!#$%&*+./<=>[email protected]\\^|~:") | char_('-'); 
special %= char_("(),;[]`{}"); 
graphic %= small | large | symbol | digit | special | char_('"') | char_('\''); 

dashes %= lit("--")>>*lit("-"); 

varsym %= ((symbol-lit(':'))>>*symbol)-reservedop-dashes; 
reservedop %= string("..") | string(":") | string("::") | string("=") | string("\\") | string("|") | string("<-") | string("->") | string("@") | string("~") | string("=>"); 

精神並不需要一個單獨的詞法和語法分析器(見What are the Benefits of Using a Lexer?),我已經通過定義遵循這一做法前六條規則爲qi::rule<Iterator, char()>,後三條規則爲qi::rule<Iterator, std::string()>。請注意,這些規則因此沒有空白字符。

此外,請注意,我試圖解析的東西爲varsym,而不是reservedop。我只使用reservedop來排除varsym規則中的內容。

雖然在varsym中保留字的排除不起作用。 ==應該是有效的varsym,但忽略它,因爲它以=開頭,這是reservedop

回答另一個問題時建議使用定義諸如

reservedop_ %= reservedop >> !symbol 

,然後東西。不過,我不確定這是否有效,而且它看起來不太優雅。

在BOOST精神中做到這一點的正確方法是什麼?

+0

如果它是不是很明顯,這是一個用於解析Haskell這樣的語法的一部分這是對Haskell報告中規則的大致直譯。 – BenRI

回答

2

在我看來,你正在混淆lexing和解析階段。

他排除了varsym中的保留字不起作用。 ==應該是一個有效的varsym,但它被忽略,因爲它以= which是一個reservedop開頭。

多大意義的代碼顯示這種說法不化妝,因爲你永遠不告訴你如何使用規則:

rule1 = varsym | reservedop; // would parse "==" as varsym 
rule2 = reservedop | varsym; // would parse "==" as reservedop 

如果你想從「常規定義的標記工作EXPR寬恕請求作爲你的代碼似乎在暗示,看看使用精神與基於萊克斯 - 分詞器:

+0

感謝您的反饋。我編輯了上面的問題,通過指定我試圖將事物解析爲'varsym'而不是試圖將任何東西解析爲'reservedop'來更清楚地說明問題。但是,我並沒有使用單獨的詞法分析器,正如上面鏈接中的引用所述:「實際上,Spirit.Qi允許您在不使用詞法分析器的情況下編寫分析器,而直接解析輸入字符流,而且大部分這是Spirit自發明以來一直使用的方式。「 – BenRI

+0

@BenRI我同意,只是當你像這樣定義一個'字符'語法時,Lex可能會變得更快,特別是在進行有狀態的lexing時。說實話,在這種情況下,我非常(a)手工編寫解析器thingie(b)直接操作懶惰地索引到內存映射的數據區域。這將導致「零拷貝」(即,當不進行訪問時)操作。在這方面無法擊敗表演。 – sehe