Spirit:无法在其规则定义中使用 x3::skip(skipper)[some recursive rule]

Posted

技术标签:

【中文标题】Spirit:无法在其规则定义中使用 x3::skip(skipper)[some recursive rule]【英文标题】:Spirit: Not able to use x3::skip(skipper)[some recursive rule] in its rule definition 【发布时间】:2017-07-24 13:44:56 【问题描述】:

假设我们要解析这样的递归块。当“skip_comments_tag”作为前缀添加到块中时,我们会递归地跳过该块中的所有 cmets(/*...*/)。


    
    
        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::make_contextx3::skip_directive 中)。 x3::no_casex3::with 也有这个问题,因为它们在实现中都使用了x3::make_context

问题:

    是否总有更好的方法来为这种类型编写解析器? 避免此类编译错误的问题以及如何避免? 或者x3::make_context 的实现是否被认为在此类问题上存在缺陷?

【问题讨论】:

【参考方案1】:

老实说,我确实认为这是make_context 设施中的一个限制,是的,它曾经困扰过我。

您可以通过使用 TU 分隔(BOOST_SPIRIT_DECLAREBOOST_SPIRIT_DEFINEBOOST_SPIRIT_INSTANTIATE 宏)。

老实说,我会在邮件列表中报告它:[spirit-general]

另见http://boost.2283326.n4.nabble.com/Horrible-compiletimes-and-memory-usage-while-compiling-a-parser-with-X3-td4689104i20.html(FWIW 我觉得“序列分区”问题无关)

【讨论】:

以上是关于Spirit:无法在其规则定义中使用 x3::skip(skipper)[some recursive rule]的主要内容,如果未能解决你的问题,请参考以下文章

Boost.Spirit.X3 中的船长

为啥 nvcc 无法使用 boost::spirit 编译 CUDA 文件?

Boost Spirit编译问题

boost::spirit 算术公式解析器无法编译

BOOST SPIRIT 解析 - 创建正确的 AST 树

Boost::Spirit 表达式解析器,带有定义的函数