我正在尝试编写语义规则,用于将给定cfg之后的表达式定向转换为3种代码表示形式。
考虑一下,

在这里,为什么要用维京操作符呢?gen()似乎是唯一需要的东西,因为它所做的是必需的。
发布于 2015-04-25 14:27:33
这组规则描述了一种属性文法,一种用于计算树的属性的方案。这类计划几乎都是纯功能性的(没有副作用)。它计算每个规则/树节点的属性,在它们使用的表示法中命名为X.Y,其中X代表规则/树(例如,带有变体E1和E2的S和E)。Y表示计算的属性(在本例中,有"code“和"place”属性)。
每个规则对应一个子树,E= E1 + E2到树(E+ E1 E2)。"E.code:=...“意思是“.”并将结果赋值给"E(+)“树(”合成“属性)根部的属性"code”;“E1.code:=.”意思是“.”并将其分配给"E1“叶(”继承的属性“)。"X.Y“不在赋值的左边,意思是”获取节点X上的属性Y的值“。
使用的计算是"newtemp“(这实际上应该是"newtemp()”,因为它不是变量,而是函数),"gen( . )“还有“女孩”。"gen“显然是在做制造个别指令的关键工作。但是它的结果是什么呢?一个简单的答案是“一个字符串”;一个更复杂的答案可能是生成指令的二进制表示。
其目的是将代码生成步骤的结果组装到生成的代码流中;如果gen结果是一个字符串,则可以是字符串连接,如果结果是二进制记录,则将二进制记录的列表连接到单个列表中。
你可能会因为认为"gen“只是产生了它的结果并编写了一个未提及的输出流而感到困惑。这将违反属性语法的精神,而属性语法不允许这样做。要计算传递到树中的函数结果,就需要使用“扣分”运算符。
您可能会扭曲属性语法,这样gen就会写入隐藏的流。在这种情况下,所有的“AC.26”操作符都会消失,就像前面提到的"E1.code“这样的计算结果一样。如果属性树的计算值是从左到右(很大),并且生成的子树组合生成结果流的顺序是正确的,则可以这样做。如果属性语法写着"E.code = E2.code = E1.code =E1.codetracesgen(.)“,也就是说,它正在重新排序生成的代码,那么隐藏的输出流技巧将无法工作。
采取不同的观点:想象一下,您想要在大型程序上快速评估这个属性语法。如果您坚持纯函数式语法,那么您可以并行地评估所有属性!您使用一个递归过程,该过程为每个子程序分叉助手谷物。听起来很疯狂?不是,我有一个属性评估器系统(请参阅我的bio),它正是基于这个原则工作的。在这种情况下,隐藏的输出流也不能工作,因为并行性可能导致以任何顺序访问子流。
https://stackoverflow.com/questions/29866122
复制相似问题