7

我目前正在尝试创建一个 TypeChecker,它将成功地对 MiniJava 程序进行类型检查。在过去的 10 个小时里,我一直在研究它,盯着它看,但我什至不知道从哪里开始。我已经放弃按时完成项目,但我仍然想了解它是如何完成的。我们得到了完整的 MiniJava 解析器和一组用于遍历抽象语法树的类以及两个不同的默认访问者,DepthFirstVisitor 和 GJDepthFirst。我们应该扩展这些访问者以完成项目。

我了解需要完成的非常基本的概念:我们需要捕获解析器无法捕获的代码中的错误。我们需要在 2 遍中运行代码。第一遍是构建符号表(?),第二遍是使用符号表来检查。这个对吗?但是后来我不知道从哪里或如何开始在代码中实现它。

我意识到这不是一个真正的问题.......但是任何形式的指导或帮助将不胜感激。我班上有几个朋友和我在同一条船上。

谢谢!

4

1 回答 1

6

由于您的语言类似于 Java,因此您可以进行简单的类型传播,而不是更通用的类型推断。首先,您必须定义一个新的 AST,每个表达式都用其类型进行注释。然后,执行深度优先(用于表达式)/广度优先(用于块语句)从旧 AST 转换为新 AST,对每个节点应用简单规则:

  • 每个变量都由其类型进行注释,并且由于您一直在对块进行广度优先处理,因此您必须在引用变量的那一刻固定所有变量类型。这适用于类字段、方法参数和局部范围的变量。
  • 每个文字都会产生一个默认类型(字符串是字符串,整数是 32 位整数,浮点数是双精度等)
  • 二元算术运算会根据一些排名规则插入隐式强制转换(选择任何一个,这并不重要)
  • 三元运算符检查第一个参数是否为布尔值并且其他两个参数是否属于同一类型
  • 方法调用在这里是最复杂的事情:您必须获得第一个可能的带有参数类型的重载方法,您可以将所有参数隐式转换为该方法。如果发生冲突,您应该怎么做。
  • 等等...

语句不能用类型注释,但您必须检查它们的表达式参数类型并可能进行隐式转换。您也可以在此阶段进行推断varauto类型(请注意,这不是“类型推断”,只是类型传播的一种特殊情况)。

于 2012-11-02T09:40:17.300 回答