语法定向翻译

时间:2015-04-25 14:00:08

标签: compiler-construction abstract-syntax-tree context-free-grammar semantic-analysis

我正在尝试将表达式的语法指导翻译的语义规则编写为3代码表示。

考虑,

enter image description here

这里,为什么是||需要运营商? gen()是它所需要的唯一东西,因为它可以满足要求。

1 个答案:

答案 0 :(得分:4)

这套规则描述了归因语法,一种计算方案 树的属性。这些方案几乎总是纯粹的功能(没有副作用)。它是计算每个规则/树节点的属性,在它们使用的符号中命名为XY,其中X代表规则/树(例如,S和E代表变量E1和E2.Y代表计算属性(在这种情况下,有“代码”和“地方”属性。

每个规则对应于子树,E = E1 + E2到S-表达式表示法中的树(E + E1 E2)。 “E.code:= ...”表示计算“...”并将结果分配给“E(+)”树的根处的属性“代码”(“合成”属性); “E1.code:= ...”表示计算“...”并分配给“E1”叶(“继承属性”)。 “X.Y”不在赋值的左侧,表示“在节点X上获取属性Y的值”。

使用的计算是“newtemp”(这应该是“newtemp()” 因为它不是变量,而是函数),“gen(...)”和“||”。 “gen”显然是在制造个别指令的关键工作。 但它的结果是什么?一个简单的答案是“一个字符串”;更复杂的答案可能是生成的指令的二进制表示。

“||”的目的将代码生成步骤的结果汇总到生成代码的 stream 中;如果gen结果是一个字符串,“||”可以是一个字符串连接,如果结果是二进制记录,它将二进制记录列表连接成一个列表。

你可能会因为认为“gen”只是产生了结果并将它们写成未提及的输出流而感到困惑。这会违反属性语法的精神,但不允许这样做。 “||”需要运算符来计算在树上传递的函数结果。

您可能会弯曲属性语法,因此gen 写入隐藏的流。在那种情况下所有的“||”运算符消失了,提到的先前计算结果如“E1.code”也是如此。如果你的属性树评估是从左到右,(一个大的),你可以使这个工作,生成的子树组合生成结果流的顺序是正确的对。如果属性语法说“E.code = E2.code || E1.code || gen(...)”,也就是说,它正在重新排序生成的代码,那么隐藏的输出流技巧将不起作用。

采取不同的观点:想象一下你想在大型程序上快速评估这个属性语法。如果您坚持使用纯函数语法,那么您可以并行评估所有属性!您使用递归过程为每个孩子分配辅助谷物。 [声音疯了吗?事实并非如此,我有一个属性评估系统(参见我的简历),正是这个原理正是如此。在这种情况下,隐藏的输出流也不起作用,因为并行性可能导致以任何顺序访问子节点。