2017-08-11 60 views
2

我基于我的应用程序关闭这个例子,并得到完全相同的结果。出于某种原因,输入字符串的内容全部被解析为融合结构'comments',并且没有任何东西被解析为融合结构'numbers'。所以不知道我在哪里错了。X3:这个解析器*(char-eol)是否消耗了所有行?

namespace client { 
    namespace ast { 

     struct number { 
      int num1; 
      int num2; 
     }; 

     struct comment { 
      std::string text; 
      bool dummy; 
     }; 

     struct input { 
      std::vector<comment> comments; 
      std::vector<number> numbers; 
     }; 
    } 
} 

BOOST_FUSION_ADAPT_STRUCT(client::ast::comment, text, dummy) 
BOOST_FUSION_ADAPT_STRUCT(client::ast::number, num1, num2) 
BOOST_FUSION_ADAPT_STRUCT(client::ast::input, comments, numbers) 

namespace client {  
    namespace parser { 

     namespace x3 = boost::spirit::x3; 
     using namespace x3; 

     x3::attr_gen dummy; 

     typedef std::string::const_iterator It; 

     using namespace x3; 

     auto const comment = *(char_ - eol) >> dummy(false); 
     auto const number = int_ >> int_; 

     auto lines = [](auto p) { return *(p >> eol); }; 

     auto const input = 
      lines(comment) >> 
      lines(number); 
    } 
} 

int main() 
{ 
    namespace x3 = boost::spirit::x3; 

    std::string const iss("any char string here\n1 2\n"); 

    auto iter = iss.begin(), eof = iss.end(); 

    client::ast::input types; 

    bool ok = parse(iter, eof, client::parser::input, types); 

    if (iter != eof) { 
     std::cout << "Remaining unparsed: '" << std::string(iter, eof) << "'\n"; 
    } 
    std::cout << "Parsed: " << (100.0 * std::distance(iss.begin(), iter)/iss.size()) << "%\n"; 
    std::cout << "ok = " << ok << std::endl; 

    // This range loop prints all contents if input. 
    for (auto& item : types.comments) { std::cout << "comment: " << boost::fusion::as_deque(item) << "\n"; } 

    // This loop prints nothing. 
    for (auto& item : types.numbers) { std::cout << "number: " << boost::fusion::as_deque(item) << "\n"; } 
} 

我更大的应用确实具有较大的输入文件和几个AST的是相同的,但它似乎我的所有例子都是由注释解析器消耗。

下面是完整的运行示例。

http://coliru.stacked-crooked.com/a/f983b26d673305a0

想法?

+0

'行(解析器)'做什么? – llonesmiz

+0

行(解析器)?行确保每个解析器(即行(注释),行(数字)后跟一个eol。 – Ender

+0

它不止于此...... – llonesmiz

回答

1

你把语法的想法从我的答案在这里:X3, how to populate a more complex AST?

有它的工作,因为行格式也不含糊。事实上,“变异”的方法,你就需要特别注意了,我注意到,在这个子弹:

  • 部门需要团队之前订购,或者你会得到“团队”相匹配,而不是部门

语法中存在着同样的歧义。 *(char_ - eol)匹配"1 2"就好了,所以显然它被添加为注释。您将不得不消除语法的歧义,或者以某种方式强制切换到“现在解析数字线”模式。

如果你完全不在乎数字行的前面是什么,只需使用x3::seek [ lines(number) ]即可。

+0

你能澄清一下关于“强制切换到'现在解析数字行'模式?“ – Ender

+0

消除语法歧义,例如['repeat(1)[comment]'](https://wandbox.org/permlink/yKd9mTOlBtKTVAB4)_ [注意你可以_assert_ it:['lines(!number >> comment]'](https://wandbox.org/permlink/sAlUOItRihTmnOSv),就像你一样,你可以使用'phrase_parse'可以看到,效率较低 – sehe

相关问题