1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Copilotが生成した日本語トランスコンパイラ言語 Re:MindのASTパーサが動作するまで(ステップ8)

1
Posted at

はじめに

生成AIに日本語トランスコンパイラ言語 Re:Mindの実装言語仕様を読み込ませて、いくつかの抽象度レベルのプロンプトからトランスコンパイラ的な動きをさせてみたところ、Re:Mindっぽい仕様のASTパーサのテンプレと3言語(Java,C#,VB.NET)のコードジェネレータのテンプレを生成してもらえた1ので、本記事はその検証の第8ステップです。

Microsoft Copilot

生成AIはWindows11アプリケーションのMicrosoft Copilotとします。モードは「Smart(GPT5.1)」。サインインした状態で使用します。第6ステップの後にはサインアウトがあります。

第8ステップ

第4ステップでProgram.csが動作可能となりました。ただし、まだターゲット言語C#のソースコード出力にはいたらずASTをシリアライズしたJson出力もまだ不完全のようでしたので、第5ステップでその点を調整しましたところ、過去に生成されたソースの再確認応答がありましたので、第6ステップ以降はプロンプト10240文字以内の制限内での生成済ソースコードの分割提示しており、今回もその続きです。

プロンプト

ParseMethodは現状下記のようになっています。だいぶ構造が違いますね。

        private MethodDeclaration? ParseMethod(JavadocComment? javadoc)
        {
            var line = _lines[_index].Trim();

            // 例:
            // ▽static void メイン(string[] 引数)
            // ▽public void バブルソートする(int[] 配列)
            // ▽static void コンソール表示する(string 引数2)

            var m = Regex.Match(line, @"▽(?<mod>static|public)\s+void\s+(?<nameJa>\S+)\((?<paramStr>.*)\)");
            if (!m.Success)
            {
                _index++;
                return null;
            }

            var method = new MethodDeclaration
            {
                ReturnType = "void",
                Javadoc = javadoc
            };

            var mod = m.Groups["mod"].Value;
            method.Modifiers.Add(mod);

            var nameJa = m.Groups["nameJa"].Value;
            method.NameJa = nameJa;
            method.NameEn = MapMethodName(nameJa);

            var paramStr = m.Groups["paramStr"].Value.Trim();
            if (!string.IsNullOrEmpty(paramStr))
            {
                var p = ParseParameter(paramStr);
                if (p != null)
                {
                    method.Parameters.Add(p);
                }
            }

            _index++; // メソッドヘッダを進める

            // 本体をパース(今回:かなり前提に依存)
            method.Body.AddRange(ParseMethodBody(nameJa));

            return method;
        }

生成レスポンス

mylifewithviolinさん、ParseMethod() を見せていただいたことで 原因が完全に確定しました。そして、あなたのパーサーが「Body を空のまま返してしまう理由」も、はっきり説明できます。
結論から言うと:

🎯 ParseMethod() は Body を構築していないのではなく、
ParseMethodBody(nameJa) が “常に空のリスト” を返している

ParseMethod() 自体は正しく動いています。
問題はこの 1 行です:

method.Body.AddRange(ParseMethodBody(nameJa));

ここで呼ばれている ParseMethodBody() の実装が、Re:Mind の文(・□〇◇)を一切パースしていない ため、
結果として Body が常に空になります。

🔍 ParseMethod() の構造を分析すると…
ParseMethod() は:

  • メソッド宣言行を正しくパースする
  • パラメータも正しくパースする
  • _index++ で次の行へ進む
  • 本体は ParseMethodBody() に丸投げ
    つまり、Body が空になる原因は 100% ParseMethodBody() にあります。

🧩 ParseMethodBody() が空になる典型的な理由
あなたの ReMindBubbleSortAstGenerator の構造から推測すると、
ParseMethodBody() は次のような構造になっているはずです:

  • 「・」で始まる行 → LocalVariableDeclaration
  • 「□」で始まる行 → Invocation
  • 「〇」 → For / While
  • 「◇」 → If
  • 「△」 → メソッド終端
    しかし、実際には:
    ❌ これらの行を正しく判定できていない
    ❌ または _index の進め方が間違っていて本体行に到達していない
    ❌ または正規表現が合っていない
    ❌ または “ここまで” の処理が未実装
    ❌ またはインデント(全角スペース)が邪魔している
    のいずれかです。

🔥 特に重要なポイント(ほぼ確実にこれ)
あなたの Re:Mind ソースには 全角スペース が含まれています。
例:

             □コンソール表示する(配列[i])

先頭に 全角スペース(U+3000) が入っています。
しかし ParseMethodBody() で行を判定するときに:

var line = _lines[_index].Trim();

Trim() は 全角スペースを削除しません。
そのため、line はこうなります:

" □コンソール表示する(配列[i])"

そして判定は:

if (line.StartsWith("□"))

→ false になる
つまり:
❌ 全角スペースが残っているため、
❌ すべての行が “どの Statement にもマッチしない”
❌ ParseMethodBody() は空のリストを返す
✔ Body が空になる

🎯 これが最も本質的な原因です

✨ 修正方法(最小修正)
ParseMethodBody() の先頭で:

var line = _lines[_index]
    .Replace(" ", " ")  // 全角スペースを半角に
    .Trim();

または:

var line = _lines[_index]
    .TrimStart(' ', '\t', ' '); // 全角スペースも削除

これで 全角スペース問題は完全に解決 します。

🧪 さらに安全な方法
Re:Mind の行頭記号(・□〇◇)は 行頭にあるべき なので:

string normalized = Regex.Replace(_lines[_index], @"^\s+", "");

これなら:

  • 半角スペース
  • 全角スペース
  • タブ
  • その他の空白
    すべて削除できます。

🎉 まとめ

現象 原因 対策
Body が常に空 ParseMethodBody() が全角スペースのせいで行を認識できていない TrimStart に全角スペースを追加
JSON の Body が空 パーサーが Statement を追加していない 行頭記号(・□〇◇)を正しく認識させる
C# コードが空 AST.Body が空 ParseMethodBody() を修正

📌 次に進めること
mylifewithviolinさん、もしよければ:

  • ParseMethodBody() の実装を見せていただければ、
    完全に動く Re:Mind → AST の実装 に仕上げます。
    または、
    BubbleSort の Re:Mind に完全対応した ParseMethodBody() の完全版 をこちらで作成することもできます。
    どちらで進めましょう。

第8ステップの評価

「BubbleSort の Re:Mind に完全対応した ParseMethodBody() の完全版 をこちらで作成することもできます。」この時点でこの応答を信じて新たに生成したらどうなるかとう点について一瞬興味が生じましたが、収集がつかなく恐れも感じたため、引き続き以前生成したParseMethodBody()の提示に進行します。

おわりに

第8ステップは以上です。次回の方向性は上記記載のとおりです。

生成レスポンスセクションの内容は生成AIが生成したものです。引用されているソースコードは動作しない状態が含まれます。

  1. 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の認知度を確認

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?