提升精神:"语义行为是邪恶的"?

Kos*_*tya 21 c++ boost-spirit boost-spirit-qi

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

我必须承认,我已经感受到了类似的东西:具有语义行为的语法实际上看起来有点难看.而且,当我需要扩展/改变它们时,它完全采用语义动作进行了大量的"微观管理".在演示文稿中演示的具有属性语法的方法似乎更加优雅和有前途.

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

seh*_*ehe 28

我相信哈特穆特会在一秒钟内回答.直到那时,这是我的看法:

,这不是官方观点.

语义动作有一些缺点

  • 语义行为最简单的缺点关注点分离的风格概念.您希望在一个地方表达语法,在另一个地方表达语义.这有助于维护(特别是关于编译Spirit Grammars的冗长编译时间)

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

    在某种程度上,使用属性就像在功能程序中使用确定性的纯函数一样,当它仅纯函数组成时,更容易推断程序(或者在本例中为语法状态机)的正确性.

  • 语义动作倾向于(但不一定如此)引入更多的值复制; 与重型回溯相结合,可能会降低性能.当然,如果语义动作"重",这本身就会妨碍解析的性能.


语义动作有利于各种目的.实际上,如果你需要解析具有上下文敏感性的非平凡语法,你就无法逃脱它们.

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

    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
    ;
    
    Run Code Online (Sandbox Code Playgroud)

    或者使用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
    
    Run Code Online (Sandbox Code Playgroud)

    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
     );
    
    Run Code Online (Sandbox Code Playgroud)

    这里,语义动作是解析器功能的核心.它起作用,因为在具有语义动作的节点级别上不涉及回溯.

  3. 语义行为是Spirit Karma中语义行为的镜像,在这些行为中,它们通常比Qi中的问题少; 所以,即使只是为了接口/ API的一致性,语义动作也是"好事",并提升整体提升精神的可用性.