FGAB問題——C#の文法二義性


C# Annotated Standardの78ページには、C 2.0の文法的二義性についての説明と解釈がある.
いわゆるFGABの例について説明します.
参照
F(G<A, B>(7));
特別な規定がなければ、この文は2つの意味に解釈できます.
1、Fは2つのbool型パラメータを受け入れる方法であり、ここでの2つの実パラメータはそれぞれG(7)である.
2、Fは1つのパラメータを受け入れる方法であり、パラメータタイプはGの戻り値タイプと一致する.Gは2つの汎用パラメータを有する1つの形式パラメータを受け入れる方法であり,ここで汎用パラメータはそれぞれAとBであり,実際のパラメータは7である.
この二義性を解決するために、ECMA-334 C#4 th Editionには、tokenの列が
type-argument-list終了の
simple-name、
member-access、
pointer-member-accessでは、終了した>のtokenが検証されます.次の場合:
( } ] : ; , . ? == !=

のうちの1つ、では
type-argument-listは
simple-name、
member-access、
pointer-member-accessの一部では、他の可能な解析方法は無効です.逆に
type-argument-listは前のものではありません
simple-name、
member-access、
pointer-member-accessの一部は、他の有効な解析方法がなくても.
△同じ規定はマイクロソフトのC#3.0規範の7.5.4.2節にもある.
つまり前の
F(G<A, B>(7));

2番目の解釈として解析されるべきです.
F(G<A, B>7);

第一の解釈として解析されるべきである.
C#Annotated Standardの本では、この規定について詳しく説明していますが、なぜこのtokenを特殊な規定の対象として選んだのか--合理的なfollow setによって二義性を解消します.詳しくはそのまま本を読みましょう.ここでは言いません.
しかし、本の中で与えられた関連例は明らかに時代遅れだ.ここでの例は仕様で用いるFGABの例と似ており,以下のコードはマイクロソフトを用いる.NETとMonoのC#コンパイラはコンパイルできません:
Peter Goldeは
public class ShouldCompile {
    public static void Main( string[ ] args ) {
        int G = 1, A = 2, B = 2;
        int blah = F( G<A, B>>7 );
    }

    public static int F( bool b, int i ) {
        return 42;
    }
}
マイクロソフトのC#2.0コンパイラでコンパイルすることは確かにできません.
参照
D:\experiment>C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\csc fgab.cs
Microsoft(R)Visual C#2005コンパイラバージョン8.0.50727.3053
Microsoft(R)Windows(R)2005 Frameworkバージョン2.0.50727用
著作権所有(C)Microsoft Corporation 2001-2005.すべての権利を保持する.
fgab.cs(4,25):error CS 0246:タイプまたはネーミングスペース名「A」(usingが欠けているかどうか)が見つかりません.
命令またはプログラムセット参照?)
fgab.cs(4,28):error CS 0246:タイプまたはネーミングスペース名「B」(usingが欠けているかどうか)が見つかりません.
命令またはプログラムセット参照?)
fgab.cs(4,23):error CS 0307:変数「G」はタイプパラメータと一緒に使用できません
でもそれは数年前のコンパイラですね...去年出たC#3.0コンパイラで大丈夫です:
参照
D:\experiment>C:\WINDOWS\Microsoft.NET\Framework\v3.5\csc fgab.cs
Microsoft(R)に適用する.NET Framework 3.5版のMicrosoft(R)Visual C#2008コンパイラ3.5.30729.1版
著作権所有(C)Microsoft Corporation.すべての権利を保持する.
最近発表されたMono 2.0.1でも問題ありません.その中のmcs:
参照
D:\experiment>mcs fgab.cs
fgab.cs(4,13): warning CS0219: The variable `blah' is assigned but its value is never used
Compilation succeeded - 1 warning(s)
gmcsで:
参照
D:\experiment>gmcs fgab.cs
fgab.cs(4,13): warning CS0219: The variable `blah' is assigned but its value is never used
Compilation succeeded - 1 warning(s)