作者macbuntu (邀怪)
看板PLT
标题[问题] 如何处理 conditional operator
时间Fri Mar 20 16:31:26 2009
我正在写一个类似 Java (但不是 Java) 语言的 compiler,
对於 a ? b : c 这种 conditional operator 的型别不知该如和处理,
不知道有没有人知道这个部份应该要怎麽做?
我的问题是这样, 假设型别 X 跟 Y 有这样的继承架构 :
interface N1 {}
interface N2 {}
class A {}
class B extends A implements N1 {}
class C extends A implements N1 {}
class X extends B implements N2 {}
class Y extends C implemnets N2 {}
也就是说, A, N1, N2 都是 X, Y 共同的 parent types. 然後:
void func(A o) {}
void func(N2 o) {}
void test(boolean b) {
// should be ambiguous
func( b ? new X() : new Y()
);
}
在 Java 里的结果是 ambiguous, 但是 type checking 阶段要怎麽检查出来呢?
conditional expression 也是 expression 的一种, 而所有 expression 都应该
有一个唯一的 evalutation result type, 所以 exp1 ? exp2 : exp3 里面,
exp1 一定是 boolean, 而後应该要从 exp2 跟 exp3 中得到一个共同的型别当成
整个 conditional expression 的型别.
所以我原先试着定义两个型别 X, Y 之间的 "most specific common parent type",
在这里是 N2, 当成整个结果的型别, 但是这麽一来, 上面就会 bind 到 func(N2)
而不会是 ambiguous 了.
想了很久, 觉得要检查出 ambiguous, 似乎只有可能让 conditional expression
的结果型别不只一个, 变成 { X, Y } 或是 { A, N1, N2 } 这种集和,
然後才能带到 method resolving 的阶段做比对, 但这感觉有两个大缺点,
首先, 所有的 expression 都变成可能有不是唯一的 result type, 很麻烦,
再来是, method resolving 的复杂度马上指数成长, 因为可能的状况太多了:
void func( A a, N1 n1, N2 n2 ) {}
void func( Object o, N2 n2, A a ) {}
void test( boolean b ) {
func( b ? new X() : new Y(),
b ? new X() : new Y(),
b ? new X() : new Y() );
}
这排列组合下来 type checking 阶段会疯掉...
我试着看 Java Language Spec #15.25, 看了半天好像就是要靠 { A, N1, N2 }
这种集合... 所以这表示不是所有 expression 都有唯一的 result type 吗?
原来以为 a ? b : c 只是简单的 syntax sugar, 很意外竟然会这麽麻烦,
不知有没有人有处理这个的经验?
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 220.136.91.116
1F:推 godfat:看到第一句话才想起来,你在岚达网上发过言... XD 03/20 16:38
2F:→ macbuntu:哈是阿, compiler 的问题能问的地方还真不多 :P 03/20 17:41