はじめに
生成AIに日本語トランスコンパイラ言語 Re:Mindの実装言語仕様を読み込ませて、いくつかの抽象度レベルのプロンプトからトランスコンパイラ的な動きをさせてみたところ、Re:Mindっぽい仕様のASTパーサのテンプレと3言語(Java,C#,VB.NET)のコードジェネレータのテンプレを生成してもらえたので、本記事はその検証の第6ステップです。
Microsoft Copilot
生成AIはWindows11アプリケーションのMicrosoft Copilotとします。モードは「Smart(GPT5.1)」。サインインした状態で使用します。いじりたおす編1第26ステップの後にはサインアウトがあります。
第6ステップ
第4ステップでProgram.csが動作可能となりました。ただし、まだターゲット言語C#のソースコード出力にはいたらずASTをシリアライズしたJson出力もまだ不完全のようでしたので、第5ステップでその点を調整しましたところ。その応答でReMindBubbleSortAstGeneratorを見せてくれとのことでした。しかし、いじりたおす編でCopilotが生成したこのクラスのコードはCopilotのプロンプト文字数上限を超えてしまうようでした。そこで、人間系のオペレーションとしては問題のある個所をデバッグ実行である程度特定して提示するとしています。
プロンプト
パーサーのソースコードは10240文字を超えてしまうためすべてはお伝え出来ないのですが、デバッグ実行してみた感じ、下記の範囲のコードが走行されていました。
public class ReMindBubbleSortAstGenerator
{
private readonly string[] _lines;
private int _index;
public ReMindBubbleSortAstGenerator(string source)
{
_lines = source.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None);
_index = 0;
}
public CompilationUnit Parse()
{
var cu = new CompilationUnit();
// 名前空間
NamespaceDeclaration ns = ParseNamespace();
cu.Namespaces.Add(ns);
// System import は固定で追加(今回のソース前提)
cu.Imports.Add(BuildSystemImport());
return cu;
}
private NamespaceDeclaration ParseNamespace()
{
// ▽名前空間 BubbleSort
var ns = new NamespaceDeclaration();
while (_index < _lines.Length)
{
var line = _lines[_index].Trim();
if (line.StartsWith("▽名前空間"))
{
var name = line.Replace("▽名前空間", "").Trim();
ns.Name = name;
_index++;
break;
}
_index++;
}
// クラスを一つだけパース(今回の前提)
ns.Classes.Add(ParseClass());
return ns;
}
生成レスポンス
mylifewithviolinさん、ここまでの情報で 原因がほぼ確定 しました。
そして、あなたが貼ってくださったパーサーのコード断片は、まさに問題の本質を示しています。
🎯 結論
パーサーが「クラス宣言まで」しか処理しておらず、
メソッド本体(Body)を一切パースしていないため、
AST の Body が常に空になる。
つまり:
- JSON は正しい
- デシリアライズも正しい
- C# コードジェネレータも正しい
- パーサーが Body を構築していないため、結果として空の AST が生成されている
ということです。
🔍 なぜそう言えるのか(根拠)
あなたが貼ってくれたコードは:
ns.Classes.Add(ParseClass());
しかし ParseClass() の中身が貼られていない。
そして、ParseNamespace() の中では:
- 名前空間名を読む
- クラスを 1 つだけパースする
ここまでしかしていません。
つまり:
✔ メソッド宣言を読むコードがあるかどうか不明
✔ メソッドの Body を読むコードがあるかどうか不明
✔ ステートメント(・□〇◇)を読むコードがあるかどうか不明
そして JSON では:
"Body": []
これは パーサーが Body に何も追加していない ことを意味します。
🧩 さらに重要な点
あなたの JSON には メソッド宣言は存在している ので、
ParseClass() の中で メソッド宣言まではパースできている ことが分かります。
しかし Body が空なので:
❌ ParseMethod() の中で Body を構築していない
または
❌ ParseStatements() が呼ばれていない
または
❌ ParseStatements() が空実装
または
❌ _index の進め方が間違っていて Body の行に到達していない
のいずれかです。
🔍 さらに深掘り:あなたのパーサー構造から推測できること
あなたのパーサーは:
-
_linesに全文を split -
_indexを進めながら行単位でパース -
Trim()してキーワードを判定
という構造です。
この方式だと、次のような問題が起きやすいです:
❗ 問題1:ParseClass() が「△」を見つけた時点で return してしまう
Re:Mind の構造は:
▽クラス
▽メソッド
本体
△
△
もし ParseClass() が「△」を見つけたら return する実装だと、
メソッド本体の行に到達する前に return してしまう ことがあります。
❗ 問題2:ParseMethod() が Body を読む前に return している
メソッド宣言は読めているので、ParseMethod() は存在します。
しかし Body が空なので:
-
〇(for/while) -
・(変数宣言) -
□(メソッド呼び出し) -
◇(if)
などの行を ParseMethod() が無視している 可能性が高いです。
❗ 問題3:インデントや記号(・□〇◇)の判定が正しく動いていない
あなたの Re:Mind ソースは:
・int[] 配列 = 15,13,9,6,4,1
しかし Trim() すると:
・int[] 配列 = 15,13,9,6,4,1
この行をパーサーが拾っていない可能性があります。
🎯 どうすれば原因を特定できるか(最短の方法)
✔ 1. ParseClass() の return 直前でログを出す
Console.WriteLine("Class parsed. Methods count = " + cls.Methods.Count);
✔ 2. ParseMethod() の return 直前でログを出す
Console.WriteLine("Method parsed. Body count = " + method.Body.Count);
これで:
- ParseMethod() が Body を構築していないのか
- ParseClass() がメソッド本体に到達していないのか
が一瞬で分かります。
🎯 さらに一歩:あなたが貼ったコードから確実に言えること
あなたの ParseNamespace() は クラス宣言の開始位置までしか進んでいない。
つまり:
✔ ParseClass() が「クラス本体の行」を読む責任を持っている
✔ ParseClass() の中でメソッド本体を読む必要がある
❌ しかし実際には Body が空なので、ParseClass() が不完全
ということです。
✨ 次のステップ(あなたが選べます)
-
ParseClass() のコードを見せていただければ、Body が空になる原因を完全に特定できます。
(全文でなくても、メソッドを読む部分だけで十分です) -
または、
ReMindBubbleSortAstGenerator の構造を推測して、正しい ParseClass() / ParseMethod() / ParseStatements() のテンプレートを作成する
こともできます。
mylifewithviolinさん、どちらで進めましょう。
第6ステップの評価
今回のプロンプトに対する応答は、だいぶ詳細に立ち入った内容となりました。次ステップの提示も以前のような盛った言い回しはなく、具体的な選択肢となっております。どの段階で生成AIとの対話を離脱して人間系のデバッグで仕上げていくか悩ましいところですが、生成AIを使った実装支援はわたしも興味深いので、もう少し対応してみます。
おわりに
第6ステップは以上です。次回の方向性はParseClass() 関連のコードを提示していく流れとなります。ログにはReMindBubbleSortAstGeneratorの出力結果が記録されているので、このログのテキストを遡って確認してくれると人間系の手間はだいぶ省力化される気はします。
-
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の認知度を確認 ↩