在创建抽象语法树的上下文中什么是综合属性?
编译器解析源代码并构建抽象语法树。用于构造抽象语法树的函数返回构成综合属性的指针。它们是什么以及它们与继承属性有何不同?
编辑:我不知道这是否有帮助,但我最初在法语中听说过这些术语:属性合成,属性继承。
Compilers parse source code and build an abstract syntax tree. The functions used to construct an abstract syntax tree return pointers which constitute synthesized attributes. What are they and how do they differ from inherited attributes.?
edit: I don't know if this can help, but I originally heard of these terms in a French context: Attributs synthétisés, attributs hérités.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
属性是与核心兴趣相关的附加值。对于 AST,您可以将它们视为与每个 AST 节点关联的对(attribute_name、attribute_value),其中属性名称对应于一些有趣的事实类型,属性值对应于该事实的实际状态(例如,“(子树计数中的常量,12)”)。
继承和合成是描述如何为每个 AST 节点计算属性值的术语,通常与使用其子节点生成 AST 节点的语法规则相关。
综合属性是那些其值是根据子节点的属性值计算出来的,并且在树中向上传递。通常,合成属性的值被组合起来生成父节点的属性。如果一个 AST 节点有两个子节点,每个子节点都有自己的属性 (constants_in_subtree_count,5) 和 (constants_in_subtree_count,7),则通过向上传递这些属性,父节点可以计算其相应的属性 (constants_in_subtree_count,12)。
继承属性是从父级传递给子级的属性。如果函数 AST 的根“知道”函数返回类型是 (return_type,integer) 作为属性,则它可以将返回类型传递给函数根的子级,例如传递给函数体。该树深处的某个地方是一个实际的 return 语句;如果它接收到继承的属性(return_type,X),
它可以检查计算结果的类型是否正确。
在实践中,您希望能够为节点定义任意属性集,并将它们在树中上下传递,以实现处理 AST 所需的多种目的(构建符号表、构建控制流图、进行类型检查、计算指标、 ...)。 属性语法生成器是一种解析器生成器,它将采用语法规则、属性集定义,以及关于如何计算每个规则中涉及的节点的合成和继承属性的规则,并生成一个解析器和一个计算所有属性的 AST walker。
这个想法的价值在于它提供了一种由自动化支持的组织原则,可用于以常规方式计算有关 AST 的许多有趣的事情。否则,您就可以使用临时代码来编写所有这些内容。
我们的 DMS 软件重组工具包是一个 AST 操作系统(实际上是源到源程序转换),使用并行属性评估来计算 AST 上的各种有用分析:传统指标、符号表、类型检查(如我上面描述的返回类型检查)、从代码中提取控制和数据流作为通过子树计算的其他不太容易描述但有用的结果(“此表达式中的副作用赋值列表”)。为什么要平行?嗯,子树中的属性计算本质上是独立的,因此并行性已经存在,并且当您处理真正的大树时,性能很重要。 DMS 通常处理数千 个编译单元,每个编译单元都会生成一个(可能很大)AST。
Attributes are additional values associated with something of central interest. In the case of ASTs, you can think of them as pairs (attribute_name, attribute_value) associated with each AST node, where the attribute name corresponds to some interesting fact-type, and the attribute value corresponds to the actual state of that fact (e.g., "(constants_in_subtree_count,12)").
Inherited and synthesized are terms for describing how the attribute values are computed for each AST node, usually associated with the grammar rule that produces the AST node using its children.
Synthesized attributes are those whose value is computed from attribute values from children nodes, and are being passed up the tree. Often, values of synthesized attributes are combined to produce an attribute for the parent node. If an AST node has two children, each of which have their own attributes (constants_in_subtree_count,5) and (constants_in_subtree_count,7), then by passing those attributes up, the parent can compute his corresponding attribute (constants_in_subtree_count,12).
Inherited attributes are those passed from the parent down to the child. If the root of a function AST "knows" the function return type is (return_type,integer) as an attribute, it can pass the return type to the children of the function root, e.g. to the function body. Someplace deep down in that tree is an actual return statement; if it receives the inherited attribute (return_type,X),
it can check that the result it is computing is the correct type.
In practice, you want to be able to define arbitrary sets of attributes for nodes, and pass them up and down the tree for the multiple purposes required to process ASTs (building symbol tables, constructing control flow graphs, doing type checking, computing metrics, ...). An attribute grammar generator is a kind of parser generator that will take grammar rules, sets of attribute definitions, and rules about how to compute synthesized and inherited attributes for the nodes involved in each rule, and generates both a parser and an AST walker that computes all the attributes.
The value of this idea is it provides an organizing principle supported by automation, that can be used to compute many interesting things about ASTs in a regular way. Otherwise you get to code all that stuff using ad hoc code.
Our DMS Software Reengineering Toolkit is an AST manipulation system (actually source-to-source program transformations) that heavily uses parallel attribute evaluation to compute all kinds of useful analyses over ASTs: conventional metrics, symbol tables, type checks (like the return type check I described above), control and data flow extraction from code, as well as other not-so-easily described but useful results computed over subtrees ("list of side effecting assignments in this expression"). Why parallel? Well, attribute computations in subtrees are essentially independent, so the parallelism is already there, and when you deal with really big trees performance matters. DMS often deals with thousands of compilation units, each producing a (possibly big) AST.