2017-07-24 62 views
2

假設我們想要解析像這樣的遞歸塊。當「skip_comments_tag」以塊爲前綴時,我們會以遞歸方式跳過此塊中的所有註釋(/*...*/)。精神:無法在其規則定義中使用x3 :: skip(skipper)[某些遞歸規則]

{ 
    {} 
    { 
     skip_comments_tag{ 
      {} /*comments*/ 
      { /*comments*/ } 
     } 
    } 
} 

很容易想出一個遞歸解析器,如Coliru

namespace Parser { 
    auto const ruleComment = x3::lit("/*") >> *(x3::char_ - "*/") >> "*/" | x3::space; 

    x3::rule<struct SBlockId> const ruleBlock; 
    auto const ruleBlock_def = x3::lit('{') >> *(ruleBlock | "skip_comments_tag" >> x3::skip(ruleComment)[ruleBlock]) >> '}'; 

    BOOST_SPIRIT_DEFINE(ruleBlock) 
} 

不過,這並不編譯(當parse函數被調用),因爲它會(在x3::skip_directivex3::make_context)產生無限的上下文。 x3::no_casex3::with也有這個問題,因爲它們全部在執行中使用x3::make_context

問題:

  1. 有總有更好的方式來寫解析器這種 問題,以避免這樣的編譯錯誤,又如何?
  2. 或者x3::make_context執行被認爲是這類問題的缺陷?

回答

1

老實說,我認爲這是make_context設施的限制,是的,它曾經咬過我。您可能可以通過使用TU分隔(BOOST_SPIRIT_DECLAREBOOST_SPIRIT_DEFINEBOOST_SPIRIT_INSTANTIATE宏)來避開它。

老實說,我會在郵件列表舉報:精神-一般]

參見http://boost.2283326.n4.nabble.com/Horrible-compiletimes-and-memory-usage-while-compiling-a-parser-with-X3-td4689104i20.html(FWIW我覺得「序列分割」的問題是不相關的)