句法导向翻译
Syntax directed translation
我正在尝试编写语义规则,用于将给定 cfg 之后的表达式的语法定向翻译成 3 种代码表示形式。
考虑一下,
这里,为什么是||需要操作员? gen() 似乎是唯一需要的东西,因为它可以满足要求。
这组规则描述了一种属性语法,一种用于计算的方案
树的属性。这样的方案几乎总是纯功能性的(没有副作用)。它计算每个 rule/tree 节点的属性,在它们使用的符号中命名为 X.Y,其中 X 代表 rule/tree(例如 S 和 E 具有变体 E1 和 E2。Y 代表计算属性(在本例中,有 "code" 和 "place" 属性。
每条规则对应一个子树,E = E1 + E2 对应树(E+ E1 E2)S-expression。 "E.code:=..." 表示计算“...”并将结果分配给 "E(+)" 树根部的属性 "code"("synthesized" 属性); "E1.code:=..." 表示计算“...”并分配给 "E1" 叶("inherited attribute")。 "X.Y" 不在赋值的左侧表示 "fetch the value of attribute Y on node X".
使用的计算是"newtemp"(这实际上应该是"newtemp()"
因为它不是一个变量,而是一个函数),"gen( ... )" 和“||”。 "gen" 显然是在做制作个别说明书的关键工作。
但它的结果是什么?一个简单的答案是 "a string";更复杂的答案可能是生成指令的二进制表示。
“||”的目的assemble 代码生成步骤的结果进入生成代码的 流 ;如果 gen 结果是一个字符串,"||"可以是字符串连接,如果结果是二进制记录,它将二进制记录列表连接成一个列表。
您可能会感到困惑,认为 "gen" 只是产生了结果并将它们写入一个未提及的输出流。这将违反不允许这样的属性语法的精神。 “||”需要运算符来计算传递到树上的函数结果。
您可能会改变属性语法,因此 gen 会写入隐藏流。在那种情况下,所有“||”运算符消失了,之前计算的结果(如 "E1.code")的提及也消失了。如果您的属性树评估是 left-to-right、(大) 和 ,则可以使此工作正常,当严格从左到右完成。如果属性文法表示"E.code = E2.code || E1.code || gen(...)",也就是说,它正在对生成的代码进行重新排序,那么隐藏输出流技巧将不起作用。
换个角度:假设您想在大型程序上快速评估此属性语法。如果你坚持使用纯函数语法,那么你可以并行计算所有属性!您使用递归过程为每个 child 分叉辅助谷物。
[听起来很疯狂?不是,我有一个属性评估系统(见我的简历)正是按照这个原则工作]。隐藏的输出流在这种情况下也不起作用,因为并行性可能导致 children 以任何顺序访问。
我正在尝试编写语义规则,用于将给定 cfg 之后的表达式的语法定向翻译成 3 种代码表示形式。
考虑一下,
这里,为什么是||需要操作员? gen() 似乎是唯一需要的东西,因为它可以满足要求。
这组规则描述了一种属性语法,一种用于计算的方案 树的属性。这样的方案几乎总是纯功能性的(没有副作用)。它计算每个 rule/tree 节点的属性,在它们使用的符号中命名为 X.Y,其中 X 代表 rule/tree(例如 S 和 E 具有变体 E1 和 E2。Y 代表计算属性(在本例中,有 "code" 和 "place" 属性。
每条规则对应一个子树,E = E1 + E2 对应树(E+ E1 E2)S-expression。 "E.code:=..." 表示计算“...”并将结果分配给 "E(+)" 树根部的属性 "code"("synthesized" 属性); "E1.code:=..." 表示计算“...”并分配给 "E1" 叶("inherited attribute")。 "X.Y" 不在赋值的左侧表示 "fetch the value of attribute Y on node X".
使用的计算是"newtemp"(这实际上应该是"newtemp()" 因为它不是一个变量,而是一个函数),"gen( ... )" 和“||”。 "gen" 显然是在做制作个别说明书的关键工作。 但它的结果是什么?一个简单的答案是 "a string";更复杂的答案可能是生成指令的二进制表示。
“||”的目的assemble 代码生成步骤的结果进入生成代码的 流 ;如果 gen 结果是一个字符串,"||"可以是字符串连接,如果结果是二进制记录,它将二进制记录列表连接成一个列表。
您可能会感到困惑,认为 "gen" 只是产生了结果并将它们写入一个未提及的输出流。这将违反不允许这样的属性语法的精神。 “||”需要运算符来计算传递到树上的函数结果。
您可能会改变属性语法,因此 gen 会写入隐藏流。在那种情况下,所有“||”运算符消失了,之前计算的结果(如 "E1.code")的提及也消失了。如果您的属性树评估是 left-to-right、(大) 和 ,则可以使此工作正常,当严格从左到右完成。如果属性文法表示"E.code = E2.code || E1.code || gen(...)",也就是说,它正在对生成的代码进行重新排序,那么隐藏输出流技巧将不起作用。
换个角度:假设您想在大型程序上快速评估此属性语法。如果你坚持使用纯函数语法,那么你可以并行计算所有属性!您使用递归过程为每个 child 分叉辅助谷物。 [听起来很疯狂?不是,我有一个属性评估系统(见我的简历)正是按照这个原则工作]。隐藏的输出流在这种情况下也不起作用,因为并行性可能导致 children 以任何顺序访问。