はじめに
日本語トランスコンパイラ言語 Re:Mindはたてつけとしてはオープンな実装言語仕様のため、どなたでも処理系を実装することが可能です。逆転の発想で生成AIに実装言語仕様を読み込ませて、いくつかの抽象度レベルのプロンプトからトランスコンパイラ的な動きをさせてみようと思っておりましたところ、ほぼ「棚ぼた」でRe:Mindっぽい仕様のASTパーサのテンプレと3言語(Java,C#,VB.NET)のコードジェネレータのテンプレを生成してもらえたので、本記事はその続きとも言える検証編の第4ステップです。
Microsoft Copilot
生成AIはWindows11アプリケーションのMicrosoft Copilotとします。モードは「Smart(GPT5.1)」。サインインした状態で使用します。いじりたおす編1第26ステップの後にはサインアウトがあります。
第4ステップ
前回ステップでProgram.csの中身はぐっと現実に近づきました。ただし、下記のコード部分は以前生成されたReMindParserクラスの実装と異なっているため、この点は(下記のコードスタイルのがよさそうとも言えるのですが)現状実装に沿って修正しました。(プロンプトに貼り付けた状態が現状のソースコードとなります。)
// 1. Re:Mind → AST
var parser = new ReMindParser();
var ast = parser.Parse(ReMindSourceCode);
プロンプト
パーサーは以前ReMindBubbleSortAstGeneratorクラスを生成していただいていましたので、下記のように調整してパーサー部分は問題なく引数整合させましたが、CSharpCodeGeneratorクラスのGenerateメソッドの引数のCompilationUnit型ast2にnull参照可能性の警告がでています。nullの場合のエラー処理またはnullセーフ―チェーンを構成できますか?
using System;
using System.Text.Json;
using ReMindAst;
using ReMindBackend;
using ReMindParser;
class Program
{
static void Main()
{
const string ReMindSourceCode = @"
▽名前空間 BubbleSort
/** Program */
▽public クラス プログラム型
...
";
// 1. Re:Mind → AST
var parser = new ReMindBubbleSortAstGenerator(ReMindSourceCode);
var ast = parser.Parse();
// 2. AST → JSON
string json = JsonSerializer.Serialize(ast, new JsonSerializerOptions
{
WriteIndented = true
});
Console.WriteLine("=== AST(JSON) ===");
Console.WriteLine(json);
// 3. JSON → AST
var ast2 = JsonSerializer.Deserialize<CompilationUnit>(json);
// 4. AST → C#コード
var generator = new CSharpCodeGenerator();
string cs = generator.Generate(ast2);
Console.WriteLine("=== C# Source ===");
Console.WriteLine(cs);
}
}
生成レスポンス
これは System.Text.Json のデシリアライズが null を返す可能性がある ために発生する、C# の正しい警告です。
(JsonSerializer.Deserialize() は、JSON が壊れていたり、型に合わなかったりすると null を返す可能性があるため)
つまり:
var ast2 = JsonSerializer.Deserialize<CompilationUnit>(json);
ここで ast2 は CompilationUnit?(null 許容) と推論されます。
そのため:
string cs = generator.Generate(ast2);
に対して「null かもしれない」という警告が出ます。
✅ 解決方法は 3 つあります
mylifewithviolinさんのプロジェクトの性質(AST → C# 生成は null では成立しない)を踏まえると、
最も安全で現実的な方法は「null チェックして例外を投げる」 です。
✅ 方法①:null チェックして例外を投げる(推奨)
var ast2 = JsonSerializer.Deserialize<CompilationUnit>(json);
if (ast2 is null)
{
throw new InvalidOperationException("AST のデシリアライズに失敗しました。");
}
var generator = new CSharpCodeGenerator();
string cs = generator.Generate(ast2);
これが最も安全で、C# の警告も消えます。
✅ 方法②:null 合体演算子で例外を投げる(より簡潔)
var ast2 = JsonSerializer.Deserialize<CompilationUnit>(json)
?? throw new InvalidOperationException("AST のデシリアライズに失敗しました。");
var generator = new CSharpCodeGenerator();
string cs = generator.Generate(ast2);
mylifewithviolinさんのコードスタイルにも合うと思います。
✅ 方法③:null 許容を外す(安全性は下がる)
どうしても警告を消したいだけなら:
var ast2 = JsonSerializer.Deserialize<CompilationUnit>(json)!;
! は「null ではないと信じる」という意味です。
ただし、本当に null が返ってきた場合は実行時例外になります。
🎯 結論:mylifewithviolinさんのプロジェクトには方法① or ② が最適
Re:Mind → AST → JSON → AST → C#
というパイプラインでは、AST が null になるのは 異常系 なので、
null チェックして例外を投げるのが最も自然です。
✨ 参考:最終的な Program.cs(安全版)
// 3. JSON → AST
var ast2 = JsonSerializer.Deserialize<CompilationUnit>(json)
?? throw new InvalidOperationException("AST のデシリアライズに失敗しました。");
// 4. AST → C#コード
var generator = new CSharpCodeGenerator();
string cs = generator.Generate(ast2);
Console.WriteLine("=== C# Source ===");
Console.WriteLine(cs);
mylifewithviolinさんの Re:Mind プロジェクトは、
AST → C# のパイプラインがどんどん整ってきていて、とても美しい構造になっています。
次は:
- JSON → AST のバリデーション
- パーサーのエラー報告
- C# / Java / VB.NET のコード生成の統一化
なども進められます。
どこを強化していきましょうか。
第4ステップの評価
あいかわらず先を急ぐ(ご提案してくる)Microsoft Copilotですが、今回のプロンプトに対する応答はけっこう丁寧だとわたしは感じました。方法③のことは知りませんでした。方法②を採用し、いったん完走することを確認しました。まだ動作結果は不完全ですので、引き続きCopilotとの対話を続けて、生成コードの品質を上げていきます。
おわりに
第4ステップは以上です。次回の方向性は上記のとおりです。
-
Microsoft Copilotで日本語トランスコンパイラ言語 Re:Mindをいじりたおす - Qiita
「Microsoft Copilotで日本語トランスコンパイラ言語 Re:Mindをいじりたおす」の記事リストです。(ステップ降順)
ステップ26 ターゲット言語JavaとVB.NETへの展開
ステップ25 ターゲット言語C#へのASTからの生成処理
ステップ24 ASTを生成するサンプル実装をC#で生成
ステップ23 マッピングルール生成
ステップ22 AST(抽象構文木)風の構造化表示
ステップ21 バブルソート 実行可能形式 ターゲットJava C# VB.NET
ステップ20 二分探索法 実行可能形式 ターゲットJava C# VB.NET
ステップ19 線形探索法 実行可能形式 ターゲットJava C# VB.NET
ステップ18 バブルソート 1案件づつやりなおし
ステップ17 二分探索法 1案件づつやりなおし
ステップ16 線形探索法 1案件づつやりなおし
ステップ15 3つの定番アルゴリズムソースの忘却原因調査
ステップ14 バブルソートソースの忘却発生再確認
ステップ13 二分探索法ソースの忘却発生
ステップ12 線形探索法の6言語変換
ステップ11 バージョン情報付きの3定番アルゴリズムソースのフィードバック修正
ステップ10 バージョン情報付きの3定番アルゴリズムソースのフィードバック修正
ステップ9 バージョン情報付きで3定番アルゴリズムソースの生成
ステップ8 バージョニングが可能か確認
ステップ7 Re:Mindの詳しい言語仕様の学習結果をバブルソートで確認
ステップ6 Re:Mindの詳しい言語仕様の学習結果を二分探索法で確認
ステップ5 Re:Mindの詳しい言語仕様の学習結果を線形探索法で確認
ステップ4 Re:Mindの詳しい言語仕様の学習成果を保持するスコープを確認
ステップ3 Re:Mindの詳しい言語仕様を学習できる方法を確認
ステップ2 Re:Mindの言語仕様の認知度を確認
ステップ1 Re:Mindの認知度を確認 ↩