提升精神:"Semantic actions are evil"?
Boost Spirit: "Semantic actions are evil"?
阅读和观看这个演讲:http://boost-spirit.com/home/2011/06/12/ast-construction-with-the-universal-tree/
我发现了这句话——基本上我们被建议不要使用语义动作。
我必须承认,我已经有了这样的感觉:带有语义动作的语法实际上看起来有点丑。而且,当我需要扩展/更改它们时,需要对语义操作进行大量的"微观管理"。在演示文稿中演示的使用属性语法的方法似乎更加优雅和有前途。
所以我想问:这是一个"官方"的观点吗?我是否应该学习如何使用属性语法并更详细地避免语义操作?如果是这样的话——我想要求一些基本的(甚至是微不足道的)例子来演示这种方法——LISP解释器太复杂了,我无法咀嚼……
我相信哈特穆特马上就会回答。在此之前,这是我的看法:
不这不是一个正式的点。
语义动作有一些缺点
-
语义动作最简单的缺点是关注点分离的风格概念。您希望在一个地方表示语法,而在另一个地方表示语义。这有助于可维护性(特别是关于编译Spirit语法的冗长编译时间)
-
如果它们有副作用(这是经常发生的情况),则会产生更复杂的影响。想象一下,当语义操作具有副作用时,从已解析节点回溯:解析器状态将被恢复,但外部效果不会。
在某种程度上,仅使用属性就像在函数式程序中使用确定性的纯函数一样,当程序仅由纯函数组成时,更容易推断程序的正确性(或者,在本例中是语法状态机)。
语义行为倾向于(但不一定如此)通过值引入更多的复制;这与大量回溯相结合,可能会降低性能。当然,如果语义动作很"重",这本身就会阻碍解析的性能。
语义动作适用于各种用途。事实上,如果您需要解析具有上下文敏感性的重要语法,则无法转义它们。
-
考虑使用
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 ;
或者使用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
-
另外,有些作业真的是"又快又脏",不需要使用树或手工滚动的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 );
-
语义行为是灵业语义行为的镜像,它们通常比气造成的问题要少;因此,即使只是为了接口/API的一致性,语义操作也是"一件好事",并提高了Boost Spirit作为一个整体的可用性。
- 为什么在将 are 值引用分配给时被视为 l 值引用?
- 如何理解"Temporary objs are destroyed as the last step in evaluating the full-expression"?谁能用一些简单的例子来说明这
- GotW #88 中的"It doesn’t work for references that are members of objects"是什么意思?
- С 错误"s1, s2 are used uninitialised in this function"
- C++ GLSL 着色器:"error: GLSL 3.30 is not supported. Supported versions are: 1.10, 1.20, 1.30, 1.00 ES,
- "C4649: attributes are ignored in this context"的含义是什么?
- 如何修复c ++中的错误"vector iterators in range are from different containers"?
- 为什么编译器显示错误"no match for 'operator[]' (operand types are 'carti' and 'int')"
- "All arguments to functions are passed by value" C 中的,C++ 中对引用传递的混淆
- 右值到左值的转换和"named-refs-are-lvalues"规则
- MEX 编译给出"there are no arguments to ... that depend on a template parameter"错误
- 为什么编译器说"Static_cast from to which are not related"?
- 赫伯·萨特原子武器"Why Standalone Fences are Suboptimal"
- Openssl, 无效参数 ' Candidates are: int BN_set_word(bignum_st *, ?) '
- What are __builtin__functions for in C++?
- "Objects are basic run-time entities in an object-oriented system"是什么意思?
- igraph_neighborhood "Valgrind output: blocks are indirectly lost in loss record "
- 最新草案§8.5.3/5第(5.2.3/5)段(5.2.2.1)中的"user-defined conversions are not considered"是什么意思?
- PCAP Destination and Source are the same
- 提升精神:"Semantic actions are evil"?