Boost Spirit:“语义行为是邪恶的"? [英] Boost Spirit: "Semantic actions are evil"?

查看:40
本文介绍了Boost Spirit:“语义行为是邪恶的"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Reading and watching this presentation: http://boost-spirit.com/home/2011/06/12/ast-construction-with-the-universal-tree/
I've discovered this statement -- basically we are suggested not to use semantic actions.

我必须承认,我已经有这样的感觉:具有语义动作的语法实际上看起来有点丑陋.并且,当我需要扩展/更改它们时,需要大量的微观管理"与语义操作完全一致.演示文稿中演示的属性语法方法似乎更加优雅和有前途.

I must admit, that I've already felt something like that: grammars with semantic actions actually look kinda ugly. and, when I needed to extend/change them, it took a lot of "micromanagement" exactly with semantic actions. The approach with attribute grammar, demonstrated in the presentation, seems to be much more elegant and promising.

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

So I'd like to ask: is this is an "official" point? Should I learn how to work with attribute grammar and avoid semantic actions in more detail? If so -- I'd like to = ask for some basic (maybe even trivial) examples, demonstrating such an approach -- the LISP interpreter is too complex for me to chew...

推荐答案

我相信 Hartmut 会马上回答.到那时,这是我的看法:

这不是官方观点.

语义动作有一些缺点

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

  • The simplest disadvantage of semantic actions is the stylistic notion of separation of concerns. You want to express syntax in one place, and semantics in another. This helps maintainability (especially with regards to the lengthy compile times for compiling Spirit Grammars)

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

More complicated implications if they have side-effects (which is frequently the case). Imagine backtracking from a parsed node when the semantic action had a side-effect: the parser state will be reverted, but the external effects aren't.

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

In a way, using attributes only is like using deterministic, pure functions in a functional program, it is easier to reason about the correctness of a program (or, in this case the grammar state machine) when it is composed of pure functions only.

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

Semantic actions have a tendency (but not necessarily so) to introduce more copying around by value; this, in combination with heavy backtracking, could reduce performance. Of course, if the semantic action is 'heavy' this, in itself, is going to hinder performance of parsing.

语义动作有多种用途.事实上,如果你需要解析具有上下文敏感性的非平凡语法,你就无法逃避它们.

Semantic actions are good for various purposes. In fact, if you need to parse non-trivial grammars with context sensitivity you cannot escape them.

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

  1. Consider the use of qi::locals<> and inherited attributes (code from the Mini XML - ASTs! sample) - they involve semantic actions:

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
;

或者使用qi::本地人:

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,这些语义动作通常构成的问题较少,因为当它们回溯时,下次执行通过(相同的)语义动作时,local 将被新的覆盖,正确,值.

IMO, these semantic action pose less of a problem usually, because when they get backtracked, the next time execution passes (the same) semantic action, the local will just get overwritten by the new, correct, value.

此外,有些工作真的又快又脏",不保证使用 utree 或手动 AST 类型:

Also, some jobs are really 'quick-and-dirty' and don't warrant the use of utree or a hand-rolled AST type:

 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
 );

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

Here, the semantic action is the core of the parsers function. It works, because no backtracking is involved at the level of nodes with semantic actions.

语义动作是Spirit Karma中语义动作的镜像,它们通常比Qi中的问题更少;因此,即使只是为了接口/API 的一致性,语义操作也是一件好事",并且从整体上增强了 Boost Spirit 的可用性.

The semantic actions are a mirror-image of semantic actions in Spirit Karma, where they usually pose less of the problems than in Qi; so even if only for interface/API consistency, semantic actions are 'a good thing' and enhance the usability of Boost Spirit as a whole.

这篇关于Boost Spirit:“语义行为是邪恶的"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆