D言語のサブセットのZコンパイラ


D言語の文法規則をANTLRの文法スクリプトに書き換えたところ、30 K以上あり、コンパイルの際、多くのエラーが発生し、メモリが溢れてしまいました.考えてみると、私はANTLRにまだ詳しくありません.二、Digit MarsのD言語文法の紹介、多くの左再帰、いくつかの定義されていない過程、2つのスペルミス、1つの同名の同義ではない過程などがあります.この場合,30 K以上の文法スクリプトをすぐにコンパイルすることは困難である.
そこで、ANTLRでZコンパイラを実現することにしました.今回は、ZをDのサブセットとして、文法定義の大部分を直接Dの文法スクリプトからコピーすると、ANTLR、二、完成した文法ファイルを熟知することができ、Dにとっても役に立ちます.
Dのサブセットとして、Zは3つの注釈のようなDのスタイルの文法をサポートしています.
//    
/*    */
/+      +/

また、Dの「_」付き数値フォーマットもサポートされています.
int a = 123_456_789;

このバージョンではboolタイプをサポートしています.
bool b = true;
b = 30 > 10;

D言語での自動型導出もサポートされています.
auto a = 1;
auto b = true;
if(b) write(a);

その他の一般的なものはCとD公有です.例えば、16進数、8進数です.
int a = 0x83_af; //       
int b = 067;     //      

連等賦課:
a = b = c = 2;

++、--、+=、-=、*=、/=(++、--左オペレータ方式のみサポート):
int n = 10;
int a *= ++n;

for、while、do-whileサイクルも追加されました.
// 1   100   
// for   
int n = 0;
for(int i=1; i<=100; ++i)
    n += i;
write(n);
// while   
i = 0; n = 0;
while( i < 100 )
    n += ++i;
write(n);
// do-while   
i = 0; n = 0;
do
    n += ++i;
while( i < 100 )
write(n);

また,文法ファイルの大部分がDからコピーされているため,演算子の優先度もC/Dと同様である(つまり前回述べた「&&」の優先度が「|」より高いという問題である).負の記号は現在もこのように式に挿入されているので、前の版でスペースを付けなければならない問題だけでなく、変数の負を求めることもサポートされています.
int a = 10;
int b=5-3;    // 5 - 3
b=5--3;       // 5 - (-3);
b=7*-a;       // 7 * (-a);

変数を定義するときにカンマを使用できますが、通常の式ではカンマ方式はサポートされていません.また、ZにはDと大きな違いがあります.boolタイプとintタイプの間では相互変換が許されません.そうしないと、コンパイル時のエラーが発生します.if for while do-whileの条件式も最終的にboolタイプでなければなりません.
int n = 1;
bool a = n == 0;
a = a && n > 10 || n != 3;
bool b = n; // error
if(b) write(1);
if(n) write(2); // error

ANTLRは確かに文法の細部制御能力が強く,またASTを生成する能力も際立っている.ANTLRWorksは動作しない場合もありますが、実際のコード効果と異なる場合もあります.全体的には役に立ちます.ASTからコードを生成するのも前回より便利です.しかし、私の実装コードには多くの異常が直接断言で実装されており、行番号は印刷されていません.また、ANTLRはエラー復旧能力が強いため、コード解析でエラーが発生したかどうかをどう判断するかは不明ですが…
実行可能プログラムとソースコードは次のとおりです.