2011-02-18 87 views
7

我有一個語法,到目前爲止,一直使用標準的boost::spirit::ascii::space/boost::spirit::ascii::space_type隊長。Boost Spirit Qi重新建立跳過自定義跳過語法

我有使用船長沒有一些規則有的像

qi::rule<Iterator, PTR<Expression>(), ascii::space_type> expression; 
qi::rule<Iterator, PTR<Term>()> term; 

當我使用非跳過非終結點(如term)一個跳躍非終端(如expression),一切的內像我期望的那樣工作 - 空白僅在term非終結符內部很重要。

而且,到現在爲止,我已經細包括使用船長不使用qi::skip終結符號的內部restablish跳過非終結符,如

index = (qi::lit('[') >> qi::skip(ascii::space)[explist >> qi::lit(']')]); 

這樣,空白不顯著內[]括號,但是在外面。但是,現在我想添加我自己的自定義隊長(我想讓換行符顯着,然後添加註釋跳過)。我的隊長語法看起來像:

struct skip_grammar : qi::grammar<Iterator> { 
    qi::rule<Iterator> start; 
    skip_grammar() : skip_grammar::base_type(start) { 
    start = qi::char_("\t\r "); 
    } 
}; 

我已經能夠將其添加到我的規則定義就好像

qi::rule<Iterator, PTR<Expression>(), skip_grammar> expression; 

但我似乎無法弄清楚如何使用我跳過語法爲一個參數qi::skip(並替換ascii::space)。我試過使用類型,本地實例變量和全局實例變量。我得到的最遠的是讓clang抱怨我的skip_grammar需要一個拷貝構造函數。所以我嘗試在我的跳過語法中添加一個拷貝構造函數,但顯然boost::noncopyable基類是出於某種原因,因爲我的二進制文件幾乎立即進行了隔離。

我應該如何使用它?

感謝

回答

7

一個qi::grammar只是爲qi::rules的容器。它沒有複製構造函數,因爲這可能會在這些規則右側的解析器表達式中無意中創建懸掛引用。

使用語法作爲船長想要這樣做有點棘手,並且等於將語法的起始規則傳遞給跳過解析器。爲它創建一個規則實例可能更容易(尤其是如果你有一個規則隊長)。

在任何情況下,該規則需要傳遞給船長爲基準(通過調用規則的成員函數alias()):

skip_grammar skippper; 
index = '[' >> qi::skip(skipper.start.alias())[explist >> ']']; 

或簡單地:

rule<iterator> skipper = qi::char_("\t\r "); 
index = '[' >> qi::skip(skipper.alias())[explist >> ']']; 

混疊是因爲複製規則意味着什麼的具體細節。在Spirit的FAQ here中有更詳細的描述。

+0

好的太棒了。再次感謝您的所有幫助。另外,我應該使用規則而不是語法來跳過嗎?我不認爲phrase_parse採用了隊長的規則類型。 – jtolds 2011-02-18 22:17:53