【问题标题】:compilers - Instruction Selection for type declarations in ASTcompilers - AST 中类型声明的指令选择
【发布时间】:2012-01-01 07:59:36
【问题描述】:

我正在学习编译器并为一种处理两种类型的简单语言创建代码生成器:字符和整数。

在用户输入被扫描器扫描然后被解析器解析后,我得到了输入的 AST 表示。我已经为一种更简单的语言生成了代码,它只处理带有整数、运算符和变量的表达式。

但是,使用这种新语言,我有时会得到一个类型声明的子树,如下所示:

(IS TYPE (x) (INT))

表示 x 是 INT 类型。

我的代码生成器中是否应该有一个案例来处理这些类型声明?或者这只是为了让语义分析器进行类型检查,所以我应该假设已经检查了类型并忽略树的这一部分并简单地为 x 赋值?

【问题讨论】:

  • 视情况而定。任何涉及x 的表达式是否会根据x 的类型改变行为?你能在知道类型的情况下生成更好的代码吗?等

标签: parsing compiler-construction types code-generation semantic-analysis


【解决方案1】:

这两种情况都是可能的,您需要更多地描述您的语言,看看您是否真的需要将该功能添加到您的代码生成器中,或者因为不必要而跳过它,并避免在这个困难而有趣的设计主题上做额外的工作一种编程语言。

您是否是“代码生成器”程序,它接收一种编程语言的输入代码(可能很小)并输出另一种编程语言的代码(可能很小)?

这个工具通常被称为“翻译器”。

你是“代码生成器”一个程序,它接收一种编程语言作为输入并输出汇编程序/字节码,如编程语言?

这个工具通常被称为“编译器”。

注意:“pile”是“stack”的同义词。

通常是 A.S.T.,存储操作或函数调用的类型。示例,在 c 中:

...
int a = 3;
int b = 5;
float c = (float)(a * b);
...

最后一行,生成一个 A.S.T.与此类似,(其他行跳过 A.S.T.):

..................................................................
..................................................................
......................+--------------+............................
......................|    [root]    |............................
......................| (no type) =  |............................
......................+------+-------+............................
.............................|....................................
.................+-----------+------------+.......................
.................|........................|.......................
...........+-----+-----+....+-------------+-------------+.........
...........| (int) c   |....| (float) (cast operation)  |.........
...........+-----------+....+-------------+-------------+.........
..........................................|.......................
....................................+-----+-----+.................
....................................| (int) ()  |.................
....................................+-----+-----+.................  
..........................................|.......................
....................................+-----+-----+.................
....................................| (int) *   |.................
....................................+-----+-----+.................
..........................................|.......................
..............................+-----------+-----------+...........
..............................|.......................|...........
........................+-----+-----+...........+-----+-----+.....
........................| (int)  a  |...........| (float) b |.....
........................+-----------+...........+-----------+.....
..................................................................
..................................................................

请注意,“(float)”将其转换为运算符或函数, 类似于你的问题。

祝你好运。

【讨论】:

    【解决方案2】:

    如果这是一个声明

    (IS TYPE (x) (INT))
    

    那么 x 应该在内存中布局。在 C 和自动变量的情况下,局部自动变量在堆栈上分配。要分配所需的堆栈大小,您应该知道所有本地变量的大小和大小来自类型。

    如果此变量存储在寄存器中,您应该选择所需大小的寄存器(想想 x86 与:AL、AX、EAX、RAX - 相同的寄存器具有不同的大小),如果您的目标有这样的。

    此外,当 AST 中存在模棱两可的操作时,需要 type,它可以对不同的数据大小进行操作(例如 char、short、int - 或 8 位、16 位、32 位等)。对于一些汇编程序,数据的大小被编码到指令本身;所以 codegen 应该记住变量的大小。

    或者,如果操作类型没有记录在 AST 中,则添加:

    (ADD (x) (y))
    

    可能意味着浮点数和整数相加(ADDFADD 指令),因此在 codegen 中需要 x 和 y 类型来选择正确的变体。

    【讨论】:

      猜你喜欢
      • 2020-10-05
      • 1970-01-01
      • 2011-05-07
      • 2017-09-21
      • 2014-12-01
      • 2015-08-12
      • 2016-10-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多