3
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のC#コード生成が動作するまで(ステップ4)

3
Posted at

はじめに

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

Microsoft Copilot

生成AIはWindows11アプリケーションのMicrosoft Copilotとします。モードは「Smart(GPT5.1)」。サインインした状態で使用します。

第4ステップ

「Re:MindのASTパーサが動作するまで」の12ステップでいったんC#のソースコードが生成されるようにはなりましたので、以降はC#コードジェネレータが正常動作することを目指しています。

プロンプト

下記のように書き換えたGenerateExpressionは何度も呼ばれましたがexpr switch文の中でInvocationExpressionに分岐することはなく、まだstatic void consoleOutの定義が出力されないのはなぜですか?

        private string GenerateExpression(Expression expr)
        {
            return expr switch
            {
                IdentifierExpression id => id.NameEn,
                LiteralExpression lit => lit.Value is string s ? $"\"{s}\"" : lit.Value!.ToString()!,
                BinaryExpression bin => $"{GenerateExpression(bin.Left)} {bin.Operator} {GenerateExpression(bin.Right)}",
                UnaryExpression un => $"{GenerateExpression(un.Operand)}{un.Operator}",
                MemberAccessExpression ma => $"{GenerateExpression(ma.Expression)}.{ma.MemberName}",
                ElementAccessExpression ea => $"{GenerateExpression(ea.ArrayExpression)}[{GenerateExpression(ea.IndexExpression)}]",
                InvocationExpression inv => GenerateInvocation(inv, _aliasMap),
                ArrayLiteralExpression arr => $"new {arr.ElementType}[] {{ {string.Join(", ", arr.Elements.Select(GenerateExpression))} }}",
                _ => "/* 未対応式 */"
            };
        }

生成レスポンス

ここは 完全に原因が特定できます。
GenerateExpression が InvocationExpression に一度も分岐しない理由は、
AST の中に「InvocationExpression が存在していない」からです。
つまり:

🎯 consoleOut メソッドの本体が「ExpressionStatement(InvocationExpression)」として AST に入っていない
だから GenerateExpression が何度呼ばれても、
InvocationExpression のケースに入ることはありません。

🔍 ログをもう一度見てください

[ParseMethodBody] method=コンソル表示する
  line[50]: "□コンソール.一行表示する(引数2)"  "□コンソール.一行表示する(引数2)"
  line[51]: "△"  "△"
[ParseMethodBody] stmts.Count = 0

つまり:

  • consoleOut メソッドの本体は 1 行だけ
  • その行はパーサーに認識されず
  • stmts.Count = 0
  • AST の Body は空
  • だから C# 出力も空

つまり、原因は「パーサーが consoleOut の呼び出しを拾えていない」こと
CSharpCodeGenerator の問題ではありません。
AST に InvocationExpression が存在しないので、
GenerateExpression が InvocationExpression に分岐しないのは当然です。

🔥 なぜパーサーが拾えていないのか?
あなたの ParseMethodBody の該当部分は:

if (Regex.IsMatch(line, @"^[□■]\s*コンソール表示する"))

しかし実際の行は:

□コンソール.一行表示する(引数2)

つまり:

  • 「コンソール表示する」ではなく
  • 「コンソール.一行表示する」
    なので、正規表現が完全に不一致です。

🎯 修正すべきはここ
❌ 今のコード(マッチしない)

if (Regex.IsMatch(line, @"^[□■]\s*コンソール表示する"))

✔ 修正案(コンソール.一行表示する を拾う)

if (Regex.IsMatch(line, @"^[□■]\s*コンソール\.一行表示する"))
{
    var expr = ParseConsoleWriteLineElement(line);
    stmts.Add(new ExpressionStatement { Expression = expr });
    _index++;
    continue;
}

✨ さらに汎用的にするなら
Re:Mind の import から「コンソール → Console」「一行表示する → WriteLine」が分かるので、
Imports を使って動的に判定するのが正しい設計です。

if (Regex.IsMatch(line, @"^[□■]"))
{
    var expr = ParseInvocationFromImports(line);
    if (expr != null)
    {
        stmts.Add(new ExpressionStatement { Expression = expr });
        _index++;
        continue;
    }
}

📌 まとめ

現象 原因 対策
GenerateExpression が Invocation に入らない AST に InvocationExpression が存在しない パーサーで consoleOut の呼び出しを拾う
consoleOut が空 ParseMethodBody がステートメントを追加していない 正規表現を「コンソール.一行表示する」に対応させる
GenerateInvocation が呼ばれない InvocationExpression が生成されていない パーサー修正で解決

ここを直せば consoleOut の中身が完全に生成されるようになります。
必要なら、ParseConsoleWriteLineElement の強化版も一緒に作れますよ。

第4ステップの評価

生成AIが提示してくる内容も即座に理解できるというわけではなく、修正内容を反映して動かしてみて意図がわかるという状況もあります。ASTパーサを介さない試作品と実装の考え方は同じ点もありますが、当然ながらそれよりは少し実装が複雑になっている面はあります。

おわりに

第4ステップは以上です。少し収束しはじめているような気がしますが、このやりとりだけでは厳しそうな感触もあります。そろそろ人間系でのデバッグ作業を検討する時期かもしれません。

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

  1. Microsoft Copilotで日本語トランスコンパイラ言語 Re:Mindをいじりたおす - Qiita
    「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の認知度を確認

  2. Copilotが生成した日本語トランスコンパイラ言語 Re:MindのASTパーサが動作するまで - Qiita
    「Re:MindのASTパーサが動作するまで」の記事リストです。(ステップ降順)
    ステップ12 いったん生成
    ステップ11
    ステップ10 生成済コードの伝達完了
    ステップ9
    ステップ8
    ステップ7
    ステップ6 生成済コードの伝達開始
    ステップ5
    ステップ4 Program.csが動作
    ステップ3
    ステップ2
    ステップ1 検証環境構築

3
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
3
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?