在编译器中键入检查

时间:2012-11-02 03:08:37

标签: compiler-construction typechecking

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

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

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

谢谢!

1 个答案:

答案 0 :(得分:4)

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

  • 每个变量都按其类型进行注释,并且由于您已经在块上进行了广度优先,因此在引用变量时必须修复所有变量类型。这适用于类字段,方法参数和本地范围的变量。
  • 每个文字产生一个默认类型(字符串是字符串,整数是,例如,32位整数,浮点数是双等)。
  • 二进制算术运算会根据一些排名规则插入隐式强制转换(选择任何一个,这并不重要)
  • 三元运算符检查第一个参数是否为布尔值,另外两个参数是否为同一类型
  • 方法调用在这里是最复杂的:你必须获得第一个可能的重载方法,其中包含可以隐式地转换所有参数的参数类型。如果有冲突,由你决定该做什么。
  • 等......

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