Compiler construction 编译循环依赖项是如何工作的?

Compiler construction 编译循环依赖项是如何工作的?,compiler-construction,circular-dependency,Compiler Construction,Circular Dependency,我已经用Java做了这个例子,但我认为(未经测试)它可以在其他(所有?)语言中工作 你有2个文件。首先,M.java: public class MType { XType x; MType() {x = null;} } public class XType { MType m; public XType(MType m) {this.m = m;} } 第二,另一个文件(在同一目录中),XType.java: public class MType {

我已经用Java做了这个例子,但我认为(未经测试)它可以在其他(所有?)语言中工作

你有2个文件。首先,
M.java

public class MType {
    XType x;
    MType() {x = null;}
}
public class XType {
   MType m;
   public XType(MType m) {this.m = m;}
}
第二,另一个文件(在同一目录中),
XType.java

public class MType {
    XType x;
    MType() {x = null;}
}
public class XType {
   MType m;
   public XType(MType m) {this.m = m;}
}
好的,这是一个糟糕的编程,但是如果运行
javacxtype
它会编译:甚至编译
MType
,因为
XType
需要它。但是
MType
需要
XType
。。。这是怎么回事?编译器如何知道发生了什么

我想知道编译器(javac或您知道的任何其他编译器)是如何管理这种情况的,而不是如何避免这种情况


我这样问是因为我正在编写一个预编译程序,我想处理这种情况。

您需要进行2次通过,或采用以下方法:

像Java这样的语言需要一个多过程编译器,因为在使用之前不需要x的定义:

有多种方法,例如,您可以执行以下操作:


第一个过程可以查找所有变量声明,第二个过程可以查找方法声明,等等。直到最后一个过程使用所有这些信息编译最终代码。

您需要采用两个过程,或者采用以下方法:

像Java这样的语言需要一个多过程编译器,因为在使用之前不需要x的定义:

有多种方法,例如,您可以执行以下操作:


第一个过程可以查找所有变量声明,第二个过程可以查找方法声明,等等。直到最后一个过程使用所有这些信息来编译最终代码。

第一个文件不需要知道任何关于XType的信息,只需要知道它是一个类型,第二个文件中的MType也是如此。此外,在Java中,所有对象的大小实际上都相同(因为所有对象都是通过引用访问的),因此不需要对象的大小。在其他语言中,这不是这样的——你的代码不能在C++中编译,例如(语言语法分开)。第一个文件不需要知道XType的任何内容,除非它是一个类型,类似于第二个文件中的MyType。此外,在Java中,所有对象的大小实际上都相同(因为所有对象都是通过引用访问的),因此不需要对象的大小。其他语言不是这样的,例如,你的代码不会在C++中编译(语言语法分开)。它必须知道Xtype的方法。。否?此外,我不确定你所说的“所有对象实际上大小相同”是什么意思。他指的是(例如)
m
持有一个引用,并且所有引用都具有相同的大小。但这并不是类型所需的唯一信息。还需要知道它的成员以及关于它的超类型层次结构的大量信息。但是如果使用XType方法呢?它必须知道Xtype的方法。。否?此外,我不确定你所说的“所有对象实际上大小相同”是什么意思。他指的是(例如)
m
持有一个引用,并且所有引用都具有相同的大小。但这并不是类型所需的唯一信息。它还需要知道它的成员和关于它的超类型层次结构的大量信息。因此,当它编译第二个文件时,编译器已经知道第一个文件是什么?@Fabio-编译器的每个过程都会处理收集下一个过程所需信息的所有文件。因此,当它编译第二个文件时,编译器已经知道了第一个是什么?@Fabio-编译器的每个过程都会处理所有文件,收集下一个过程所需的信息。