【问题标题】:Boost Spirit: "Semantic actions are evil"?Boost Spirit:“语义行为是邪恶的”?
【发布时间】:2024-04-22 18:15:02
【问题描述】:

阅读和观看此演示文稿: http://boost-spirit.com/home/2011/06/12/ast-construction-with-the-universal-tree/
我发现了这种说法——基本上建议我们不要使用语义动作。

我必须承认,我已经感受到了类似的感觉:带有语义动作的语法实际上看起来有点难看。并且,当我需要扩展/更改它们时,需要大量的“微观管理”来进行语义操作。演示文稿中演示的属性语法方法似乎更加优雅和有前途。

所以我想问一下:这是“官方”观点吗?我应该学习如何使用属性语法并更详细地避免语义动作吗?如果是这样——我想要求一些基本的(甚至可能是微不足道的)示例,展示这种方法——LISP 解释器对我来说太复杂了......

【问题讨论】:

标签: c++ boost-spirit boost-spirit-qi


【解决方案1】:

我相信 Hartmut 会在一秒钟内回答。到那时,这是我的看法:

这不是官方观点。

语义动作有一些缺点

  • 语义动作最简单的缺点关注点分离的风格概念。你想在一个地方表达语法,在另一个地方表达语义。这有助于可维护性(尤其是对于编译 Spirit Grammars 的冗长编译时间)

  • 如果它们有副作用(通常是这种情况),则会产生更复杂的影响。想象一下当语义动作有副作用时从已解析节点回溯:解析器状态将被恢复,但外部效果不会。

    在某种程度上,只使用属性就像在函数式程序中使用确定性的纯函数,更容易推断程序的正确性(或者,在这种情况下,语法 状态机),当它纯函数组成时。

  • 语义动作倾向于(但不一定如此)引入更多的价值复制;这与大量回溯相结合,可能会降低性能。当然,如果语义动作很“重”,这本身就会影响解析性能。


语义动作适用于各种目的。事实上,如果您需要解析具有上下文敏感性的重要语法,您就无法转义它们。

  1. 考虑使用qi::locals<>继承属性(来自Mini XML - ASTs! sample 的代码)——它们涉及语义操作:

    xml =
            start_tag                   [at_c<0>(_val) = _1]
        >>  *node                      
        >>  end_tag(at_c<0>(_val)) // passing the name from the 
                                   // ... start_tag as inherited attribute
    ;
    

    one using qi::locals

    rule<char const*, locals<char> > rl;
    rl = alpha[_a = _1] >> char_(_a); // get two identical characters
    test_parser("aa", rl); // pass
    test_parser("ax", rl); // fail
    

    IMO,这些语义动作通常不会造成什么问题,因为当它们被回溯时,下一次执行通过(相同的)语义动作时,本地将被新的,正确,值。

  2. 此外,有些工作确实“快速而肮脏”,不保证使用 utree 或手动 AST 类型:

     qi::phrase_parse(first, last, // imagine qi::istream_iterator... 
         intesting_string_pattern  // we want to match certain patterns on the fly
                [ log_interesting_strings ], // and pass them to our logger
         noise_skipper             // but we skip all noise
     );
    

    这里,语义动作是解析器函数的核心。它有效,因为在具有语义动作的节点级别不涉及回溯。

  3. 意业是灵业意业的镜像,在意业中的问题通常比气少;因此,即使只是为了接口/API 的一致性,语义操作也是“一件好事”,并从整体上增强了 Boost Spirit 的可用性。

【讨论】:

  • 您对最新版本的库 (X3) 中的语义操作有何看法?他们会在那里吗?
  • @Dukales 当然会。语义动作可能有不利的一面,但没有它们会更加严重。不过,我对 X3 的实际操作经验并不多
最近更新 更多