代码生成跳转和标记
Code Generation jumps and marks
我只有这个部分是 JavaCC 的代码片段。
我的问题是跳转和标记命令是如何工作的。
第 9 行有一个条件跳转,第 16 行有一个常规跳转,它总是在 else 条件下执行。但是他们怎么知道跳到哪里呢?
markByLable 总是在 Jump 之后(我真的不知道它在做什么)。和第 20 行一样,还有一个 Descriptor 的假标签,但是在 else 语句之后。
因此,如果 if 条件不为真,第 8 行会跳转到它,它会跳过 else 条件。
Code as picture with some extra statements
非常感谢您的帮助。
括号内的代码不是JavaCC代码;这是 Java 代码。也就是说,class中的Label
、Descriptor
、m_codeGen
中的class只是写成普通的Java。如果您无法访问这些 classes,则必须根据它们的使用方式和您的图片来弄清楚它们的作用。
最好的策略可能是询问您从中获取图像的人。
对于像 if( E ) C else D
这样的 if 语句,您可以预期生成的代码看起来像这样
[Code for E]
JUMP_IF_FALSE to L1
L0: NOP
[Code for C]
JUMP to L2
L1: NOP
[Code for D]
L2: NOP
所以让我们跟踪在解析 if( E ) C else D
时执行的代码,对于某些表达式 E 和语句 C 和 D,并尝试弄清楚 out/guess 发生了什么。
desc = expr()
解析并发出 E. 的代码
- 根据您的图片,您可以看到调用
m_codeGen.falseJump(desc)
正在做两件事。它正在制作一个全新的标签(在我们的示例中为 L1),然后发出跳转到该标签的指令。我猜想它还做了一件图中没有显示的事情,那就是它创建了另一个新标签 (L0) 并将其分配给 desc.m_tLabel,否则该字段的初始化方式是个谜。 (也许该字段以其他方式初始化。)
- 下一个命令是
m_codeGen.markByLabel(desc.m_tLabel)
。根据您的图片,这似乎可以做两件事。 (我真的在这里猜测。)它发出(?)一个 NOP 指令,然后它告诉标签(L0)它正在通过设置标签的 m_statement_field
来标记该指令。 (因为没有分支,到L0,这一步大概可以省去,如果省了,那么desc.m_tLabel
字段初始化不初始化都无所谓了。)
stat()
解析并发出 C 代码。
- 接下来是
endifLabel = m_codeGen.createLabel()
。显然这会创建一个新标签 (L2)。
- 接下来是
m_codeGen.jump(endifLabel);
这必须发出无条件跳转(到L2)。
- 接下来是
m_codeGen.markByLabel(desc.m_fLabel);
。这会发出第二个 NOP 并对其进行标记(使用 L1)。
stat()
解析并发出 D 的代码。
- 终于是
m_codeGen.markByLabel(endifLabel);
了。这会发出最终的 NOP 并对其进行标记(使用 L2)。
我只有这个部分是 JavaCC 的代码片段。
我的问题是跳转和标记命令是如何工作的。 第 9 行有一个条件跳转,第 16 行有一个常规跳转,它总是在 else 条件下执行。但是他们怎么知道跳到哪里呢? markByLable 总是在 Jump 之后(我真的不知道它在做什么)。和第 20 行一样,还有一个 Descriptor 的假标签,但是在 else 语句之后。 因此,如果 if 条件不为真,第 8 行会跳转到它,它会跳过 else 条件。
Code as picture with some extra statements
非常感谢您的帮助。
括号内的代码不是JavaCC代码;这是 Java 代码。也就是说,class中的Label
、Descriptor
、m_codeGen
中的class只是写成普通的Java。如果您无法访问这些 classes,则必须根据它们的使用方式和您的图片来弄清楚它们的作用。
最好的策略可能是询问您从中获取图像的人。
对于像 if( E ) C else D
这样的 if 语句,您可以预期生成的代码看起来像这样
[Code for E]
JUMP_IF_FALSE to L1
L0: NOP
[Code for C]
JUMP to L2
L1: NOP
[Code for D]
L2: NOP
所以让我们跟踪在解析 if( E ) C else D
时执行的代码,对于某些表达式 E 和语句 C 和 D,并尝试弄清楚 out/guess 发生了什么。
desc = expr()
解析并发出 E. 的代码
- 根据您的图片,您可以看到调用
m_codeGen.falseJump(desc)
正在做两件事。它正在制作一个全新的标签(在我们的示例中为 L1),然后发出跳转到该标签的指令。我猜想它还做了一件图中没有显示的事情,那就是它创建了另一个新标签 (L0) 并将其分配给 desc.m_tLabel,否则该字段的初始化方式是个谜。 (也许该字段以其他方式初始化。) - 下一个命令是
m_codeGen.markByLabel(desc.m_tLabel)
。根据您的图片,这似乎可以做两件事。 (我真的在这里猜测。)它发出(?)一个 NOP 指令,然后它告诉标签(L0)它正在通过设置标签的m_statement_field
来标记该指令。 (因为没有分支,到L0,这一步大概可以省去,如果省了,那么desc.m_tLabel
字段初始化不初始化都无所谓了。) stat()
解析并发出 C 代码。- 接下来是
endifLabel = m_codeGen.createLabel()
。显然这会创建一个新标签 (L2)。 - 接下来是
m_codeGen.jump(endifLabel);
这必须发出无条件跳转(到L2)。 - 接下来是
m_codeGen.markByLabel(desc.m_fLabel);
。这会发出第二个 NOP 并对其进行标记(使用 L1)。 stat()
解析并发出 D 的代码。- 终于是
m_codeGen.markByLabel(endifLabel);
了。这会发出最终的 NOP 并对其进行标记(使用 L2)。