1

我正在为类似 C 的语言开发编译器,并且在语义分析和代码生成阶段遇到了一些困难。我的问题如下: 1)对于 if 语句,以下是语法:

if (expression) then
statement1;
statement2;
else
statement3;
end if;

现在,在我的目标代码中,它必须是带有 go to 语句的 3 地址代码,所以它应该

look something like:
if (Rx)  // Rx is the register where the expression is evaluated and stored
go to X1 //for if part
X2 // for else part;

所以现在,我的问题是,如何生成“转到”语句的地址?

2)这个问题是关于语义分析的:我已经能够为单个函数构建和使用符号表。我应该使用什么方法来构建函数调用的符号表?换句话说,对于不同的词汇级别?我知道这应该以某种方式涉及拥有多棵树。一棵树对应一个功能。但是从程序中间的某个地方指向不同的树的方法是什么?

我是初学者,因此任何建议/想法将不胜感激。

4

2 回答 2

1

这取决于编译器生成代码的方式和时间。

如果您的编译器按顺序生成代码(从代码的第一行到最后一行),那么您唯一能做的就是记住要跳转到的位置(将它们存储在表中),然后修补生成所有内容后的代码。

如果您的编译器自底向上(从最里面的语句到最外面的语句)生成代码,并且您的底层机器(物理或虚拟)支持相对跳转,那么您可以在生成代码时简单地生成相对跳转。例如。

假设你有这段代码:

if (condition) then
   someexpressionsA
else
   someexpressionsB
endif;

自底向上编译意味着代码会生成如下:

  • 首先是 someexpressionsA 的代码
  • 然后是 someexpressionsB 的代码
  • 然后是 if-then-else-endif 语句的代码

假设我们的编译器生成了一些表达式A 的代码,称为codeblockA(B 也一样)。那么 if-then-else-endif 语句的代码可以这样写(伪代码):

  • 检查条件
  • 如果条件为假,则跳转 sizeof(codeblockA+1) 进一步说明
  • 代码块A
  • 进一步跳转 sizeof(codeblockB)
  • 代码块B

如果条件包含多个条件(和、或、...),事情可能会变得更加棘手,但上面的示例应该可以帮助您入门。

于 2011-02-16T11:01:07.147 回答
0

您是否立即生成代码,而没有解析符号标签的“汇编程序”传递?在这种情况下,您必须构建一个包含所有标签和分支指令的表,然后在生成所有标签后对代码进行回补。

于 2011-02-16T10:41:10.960 回答