日本語トランスコンパイラ言語 Re:Mindの試作を日本語プログラミング仕様記述言語 Re:Mindで内部設計する（ターゲット言語VB.NET）

# はじめに
自作言語Re:Mindの詳しい利用シーンのイメージは[こちらへ](https://qiita.com/mylifewithviolin/items/9d58db8a101807c19bde)。すみません、[試作段階です。](https://qiita.com/mylifewithviolin/items/abae37afefb42ca8ef31)日本語プログラミング言語で、C言語を由来とする新旧言語へのトランスコンパイラ言語です。最近、VB.NETもターゲット言語にしていたのを思い出しました。

## この記事内容の作業目的
自作言語Re:Mindの構文仕様策定の節目として、一昨年(2022年末)までに考案した内容プラスアルファを2022 Lv1としてまとめまていますが、その一部仕様を試作してみます。試作にあたって内部構想を、[日本語プログラミング仕様記述言語 Re:Mind](https://qiita.com/mylifewithviolin/items/52f806777e6ea031de94)で記述しておきます。本試作範囲は策定仕様のごくごく一部です。ターゲット言語は一部のみ対応、言語の対応ソース構文も超限定的です。


## この記事内容の保証
※この記事には仕様的な情報が含まれます。自作言語はまだ設計開発中のため、発案者による実装は存在しません。本記事に開示された仕様は次バージョンの仕様においては予告なく変更される場合があります。また、このバージョンの仕様内で補足や追加がなされる場合があります。


# 補足
日本語トランスコンパイラ言語 Re:Mind（リマインド）は[オープンな実装言語仕様](https://qiita.com/mylifewithviolin/items/9a6abbab62c0f5e27d4b)で、どなたでもコンパイラ・トランスコンパイラを実装することができます。

# 試作概要・試作目的
本試作では日本語トランスコンパイラ言語 Re:Mind（リマインド）の原型を検証し、いろいろな問題点を洗い出します。ターゲット言語のソースコード入力は実装言語のソースコードのインライン記述にとどまります。試作範囲は段階的に拡張してまいります。

## 本試作の設計言語
・プログラミング仕様記述言語 Re:Mind

日本語プログラミング仕様記述言語 Re:Mind（リマインド）は[オープンな設計言語仕様](https://qiita.com/mylifewithviolin/items/52f806777e6ea031de94)で、どなたでもこの記法を使いロジックを記述することができます。

## 本試作の実装言語
・C#
コンソールアプリケーションとして実装します。本記事はその内部仕様記述です。

## 本試作のターゲット言語
本試作のターゲット言語としては下記の4言語を想定しております、本記事はそのうちのVB.NETに該当する内容です。
・C#
・Java
・**VB.NET**　←本記事(内部仕様)の対象言語
・Mind

・想定稼働OS Windows

## 本試作のターゲット言語の対応仕様範囲
"Hellow World!"がコンソール出力されるソースコードを入力して（インライン・リテラルコーディング）、ターゲット言語のソースコードをコンソール出力する。（どの言語向けソースを出力するかは起動パラメータにする。）

### お題のターゲット言語出力ソースコード
#### VB.NET
```vb:VB.NET
    Imports System

    Namespace HelloWorld

        ''' <summary>プログラム型</summary>
        Module Program
            ''' <summary>メイン</summary>
            ''' <param name="args">引数</param>
            Sub Main(args As String())
                Console.WriteLine("Hello World!")
            End Sub
        End Module
    End Namespace
```

### お題のトランスコンパイラ言語 Re:Mind入力ソースコード(ターゲット言語依存)
#### VB.NET
既存ライブラリを引用する記述は毎回書く必要をなくす想定ですが、まだライブラリのサンプルコードは皆無のため、本試作ではライブラリ引用ソースコードも明確に書いてもらう想定です。Systemは既定のImports文として明示不要であっても既定でない今後のImports文のため、出力するとしています。

```mind:Re:Mind
    ▽名前空間 HelloWorld
        /**
        * Program
        */
        ▽モジュール プログラム型
            /**
            * Main
            * @param 引数 args
            */
            ▽メイン(string[] 引数)
               □コンソール.一行表示する("Hellow World!")
            △
        △
    △

    ■インポートする System
    ▼public static class コンソール Console
        ▼public static 一行表示する(string? value)
              WriteLine (string? value)
        ▲
    ▲
```


## 本試作の内部設計の妥当性
試作のため本実装には採用されない可能性があります。また、試作品の実装段階でフィードバック訂正される場合があります。トークナイザとコードジェネレータはありますが、パーサの設計（や他もすべて）は現時点で適当です。本試作では実装していませんが、ソースコードを生成したらターゲット言語のコンパイラにいったん投げて、文法チェックはターゲット言語コンパイラにお任せを想定しています。

# クラス構成
お手数ですが[内部設計（基本構成）](https://qiita.com/mylifewithviolin/items/0ecfbfbaafcce6645d82)をご参照ください。

# クラス・メンバの構成
お手数ですが[内部設計（基本構成）](https://qiita.com/mylifewithviolin/items/0ecfbfbaafcce6645d82)をご参照ください。

# クラスTargetVb

ターゲット言語VB.NETのトークナイザとコードジェネレータを保持するクラスの実装です。
## 列挙体、クラス(変数のみ)の宣言

お手数ですが[内部設計（基本構成）](https://qiita.com/mylifewithviolin/items/0ecfbfbaafcce6645d82)をご参照ください。

## SubMain
クラスProgramのメイン関数から、コンソールアプリケーションの起動パラメータで"vb"が指定されたときに実行されるサブメイン関数です。（クラスTargetVbの実質メイン関数）

このレベルでのC#をターゲットとしたクラスTargetCsとの差異はありません。詳細はお手数ですが[内部設計（ターゲット言語C#）](https://qiita.com/mylifewithviolin/items/a0754013787a513828a4)をご参照ください。

## SubMainから直接呼ばれる主要関数
### 名称辞書を初期化する
Dictionary型の名称辞書を今回のターゲット言語の使用する範囲で予約されている予約語の日本語名とオリジナル英語名を対応づけしておきます。
```mind:Re:Mind
    /**
    * initNameDictionary
    * @param 名称辞書 nameDictionary
    */
    ▽static 名称辞書を初期化する(辞書型<string, string> 名称辞書)
        □名称辞書.追加("名前空間","Namespace")
        □名称辞書.追加("クラス","Class")
        □名称辞書.追加("モジュール","Module")
        □名称辞書.追加("インポートする","Imports")
    △
```

### ノードカテゴライズする
第１引数の「ソース」はRe:Mind（リマインド）のソースコード文字列全体です。「ソース」を改行で分割して、各ソース行の先頭文字「ノード」でソース行をカテゴライズした第2引数「ソース行リスト」に格納し、「ソース」の中で■Imports句のソースコード行文字列を第3引数「インポートリスト」に格納します。

```mind:Re:Mind
    /**
    * nodeCategorized
    * @param ソース source
    * @param ソース行リスト sourcesLineList
    * @param インポートリスト importList
    * @param 名称辞書 nameDictionary
    */
    ▽static int ノードカテゴライズする(string ソース,リスト型<ソース行型> ソース行リスト,リスト型<string> インポートリスト,辞書型<string, string> 名称辞書)
        ・int 戻り値 = 1
        □ライン文字列配列 = ソース.Split("\r\n")
        〇i=0,i<ライン文字列配列.Length,i++ 繰り返す
                ・ソース行 =new ソース行型
                ・ソース行文字列=ライン文字列配列[i]
                □ソース行.ソース行番号=i+1
                □ソース行.オリジナルソース文字列=ソース行文字列
                □ソース行文字列=ソース行文字列.Trim()
                □ソース行.オリジナルインデント=ソース行.オリジナルソース文字列.Substring(0,ソース行.オリジナルソース文字列.Length-ソース行文字列.Length)
                □ソース行.ノード種類=ソース行ノードを判定する(ref ソース行文字列)//ノード種類を判定する
                ◇ソース行.ノード種類==ノード種類.例外　の場合
                    コンソール.一行表示する(ソース行.オリジナルソース文字列)               
                    □戻り値を　返す
                ◇ここまで 
                □ソース行.行文字列=ソース行文字列
                □ソース行リスト.追加(ソース行)
                ◇ソース行.ノード種類==ノード種類.引用開始　の場合
                    □ソース行文字列=名称辞書でターゲットソース行を置換する(名称辞書,ソース行文字列)
                    □インポートリスト.追加(ソース行文字列+";")//Usingリストに追加
                ◇ここまで 
        〇ここまで

        □ret=0//ここまで進行したら成功
        □戻り値を　返す
    △
```

### 名称辞書を収集する
第１引数の「ソース行リスト」はノードカテゴライズするでカテゴライズされたソース行型のリストで、これをもう一度分析して、第2引数の名称辞書に追記して返します。
ノード種類がJavaDoc備考開始の場合はソース行を先読みして、後続するソース行のノード種類がavaDoc備考途中の場合は英字の関数名をValueとして、定義開始の場合は日本語関数名をKeyとして名称辞書に格納します。また、JavaDoc備考変数の場合は日本語引数名、英字引数名を名称辞書に格納します。
```mind:Re:Mind
    /**
    * collectNameDictionary
    * @param ソース行リスト sourcesLineList
    * @param 名称辞書 nameDictionary
    */
    ▽static int 名称辞書を収集する(リスト型<ソース行型> ソース行リスト,辞書型<string, string> 名称辞書)
        ・int 戻り値 = 1
        〇i=0,i<ソース行リスト.Count,i++ 繰り返す
            ・ソース行=ソース行リスト.ElementAt(i)
            ・ノード種類 =ソース行.ノード種類
            ・ソース行文字列=ソース行.行文字列 ?? ""  
            ◇ノード種類　で分岐する
            ◇ノード種類列挙体.JavaDoc備考開始//JavaDoc備考開始
                    //ソース行を先読みする
                    ・string key=""
                    ・string value=""
                    ・string valueParam=""
                    ・bool appearValue=false
                    〇j=i+1,j<ソース行リスト.Count,j++ 繰り返す
                        ・ソース行forward=ソース行リスト.ElementAt(j)
                        ・ノード種類forward =ソース行forward.ノード種類
                        ・ソース行文字列forward=ソース行forward.行文字列 ?? ""
                        ◇ノード種類forward=ノード種類.JavaDoc備考途中 && appearValue==false　の場合
                            □appearValue=true
                            □value=ソース行forward.Replace(ソース行のノード種類.JavaDoc備考途中記号,"").Trim()
                        ◇ここまで
                        ◇ノード種類forward==ノード種類.定義開始 && appearValue の場合
                            □key=ソース行文字列forward.置換("static","").置換("public","")置換("private","").Trim()
                            ・pos=key.IndexOf(ソース行のノード種類.引数開始記号)
                            ◇pos>0　の場合//かっこが出現した場合
                                key=key.置換(key.Substring(pos),"")//かっこ開始から右側は除去
                            ◇ここまで
                            □pos=key.LastIndexOf(" ")
                            ◇pos>0　の場合//空白が出現した場合
                                key=key.Substring(pos).Trim()//空白から右側を対象とする
                            ◇ここまで
                            □名称辞書.追加(key,value)
                            □脱出する//ND_DEF_BEGINで必ずbreak
                        ◇ここまで
                        ◇ノード種類forward==ノード種類.JavaDoc備考変数 の場合
                            □valueParam=ソース行文字列forward.置換(ソース行のノード種類.JavaDoc備考途中記号,"").Trim();
                            □valueParam=valueParam.置換(ソース行のノード種類.JavaDoc備考変数記号,"").Trim();
                            ・keyValue=valueParam.Split(" ")
                            ◇keyValue.Length==2 の場合
                                □名称辞書.追加(keyValue[0],keyValue[1])
                            ◇ここまで
                        ◇ここまで
                    〇ここまで
                     □脱出する
           ◇ノード種類列挙体.JavaDoc備考途中//JavaDoc備考途中
           ◇ノード種類列挙体.JavaDoc備考変数//JavaDoc備考変数
           ◇ノード種類列挙体.JavaDoc備考終了//JavaDoc備考終了
                    □脱出する
           ◇ノード種類列挙体.引用定義開始//引用定義開始
                    ・string key2=""
                    ・string value2=""
                    ・string valueParam2=""
                    //classが存在したら当該行でkeyValue取得
                    ◇ソース行文字列.IndexOf("class")>=0 の場合
                        □valueParam2=ソース行文字列.置換("static","").置換("public","").置換("private","").置換("class","").Trim()
                        ・keyValue=valueParam2.Split(" ")
                        ◇keyValue.Length==2 の場合
                            □名称辞書.追加(keyValue[0],keyValue[1])
                        ◇ここまで
                    ◇他に
                        //classが存在しなければソース行を先読みする
                         □key2=ソース行文字列.置換("static","").置換("public","").置換("private","").Trim()
                        ・pos=key2.IndexOf(ソース行のノード種類.引数開始記号)
                        ◇pos>0　の場合//かっこが出現した場合
                            □key2=key2.置換(key2.Substring(pos),"").Trim()//かっこ開始から右側は除去
                        ◇ここまで
                        ・ソース行forward=ソース行リスト.ElementAt(i+1)
                        ・ノード種類forward =ソース行forward.ノード種類
                        ・ソース行文字列forward=ソース行forward.行文字列 ?? ""
                        □value2=ソース行文字列forward.置換("static","").置換("public","").置換("private","").Trim()
                        □pos=value2.IndexOf(ソース行のノード種類.引数開始記号)
                        ◇pos>0　の場合//かっこが出現した場合
                            □value2=value2.置換(value2.Substring(pos),"").Trim()//かっこ開始から右側は除去
                        ◇ここまで
                        □名称辞書.追加(key2,value2)
                    ◇ここまで
                    □脱出する
                //行レベルカテゴライズ済のため例外は生じない
            ◇ここまで
        〇ここまで
        □ret=0//ここまで進行したら成功
        □戻り値を　返す
    △
```

### トランスコンパイルする
第１引数の「ソース行リスト」はノードカテゴライズするでカテゴライズされたソース行型のリストで、これをもう一度分析して、第3引数の名称辞書を使ってターゲット言語の英字に置換してから、第2引数のターゲットソース行型のリストを返します。
```mind:Re:Mind
    /**
    * transcompile
    * @param ソース行リスト sourcesLineList
    * @param ターゲットソース行リスト targetSourcesLineList
    * @param 名称辞書 nameDictionary
    */
    ▽static int トランスコンパイルする(リスト型<ソース行型> ソース行リスト,リスト型<ターゲットソース行型> ターゲットソース行リスト,辞書型<string, string> 名称辞書)
        ・int 戻り値 = 1
    
        ・int ターゲットソース行番号=0
        〇i=0,i<ソース行リスト.Count,i++ 繰り返す
            ・ソース行=ソース行リスト.ElementAt(i)
            ・ノード種類 =ソース行.ノード種類
            
            ◇ノード種類　で分岐する
            ◇ノード種類列挙体.定義開始//定義開始
                   □戻り値=ターゲットソース行を生成する(ソース行,ターゲットソース行リスト,ノード種類,名称辞書,ref ターゲットソース行番号)
                   □脱出する
            ◇ノード種類列挙体.定義終了//定義終了
                   □戻り値=ターゲットソース行を生成する(ソース行,ターゲットソース行リスト,ノード種類,名称辞書,ref ターゲットソース行番号);
                   □脱出する
            ◇ノード種類列挙体.引用定義終了//引用定義終了
                   □脱出する
            ◇ノード種類列挙体.宣言開始//宣言開始
            ◇ノード種類列挙体.実行開始//実行開始
                   □戻り値=ターゲットソース行を生成する(ソース行,ターゲットソース行リスト,ノード種類,名称辞書,ref ターゲットソース行番号)
                   □脱出する
            ◇ノード種類列挙体.引用開始//引用開始
            ◇ノード種類列挙体.引用定義開始//引用定義開始
                   □脱出する
            ◇ノード種類列挙体.単行備考開始//単行備考開始
            ◇ノード種類列挙体.JavaDoc備考開始//JavaDoc備考開始
            ◇ノード種類列挙体.JavaDoc備考途中//JavaDoc備考途中
            ◇ノード種類列挙体.JavaDoc備考変数//JavaDoc備考変数
            ◇ノード種類列挙体.JavaDoc備考終了//JavaDoc備考終了
               □戻り値=ターゲットソース行を生成する(ソース行,ターゲットソース行リスト,ノード種類,名称辞書,ref ターゲットソース行番号)
               □脱出する
            //行レベルカテゴライズ済のため例外は生じない
            ◇ここまで
       〇ここまで

        □ret=0//ここまで進行したら成功
        □戻り値を　返す
    △
```

### コード出力する
インポートリストの内容を最初に出力して、続いてターゲットソース行リストを出力しますが、ソース行リストから元のインデントを復元しています。

```mind:Re:Mind
    /**
    * codeOutput
    * @param インポートリスト importList
    * @param ターゲットソース行リスト targetSourcesLineList
    * @param ソース行リスト sourcesLineList
    */
    ▽static コード出力するする(リスト型<string> ユージングリスト,リスト型<ターゲットソース行型> ターゲットソース行リスト,リスト型<ソース行型> ソース行リスト)
        〇i=0,i<ユージングリスト.Count,i++ 繰り返す
             ・ターゲットソース =インポートリスト.ElementAt(i)
             □コンソール.一行表示する(ターゲットソース)
        〇ここまで
        〇i=0,i<ターゲットソース行リスト.Count,i++ 繰り返す
             ・ターゲットソース =ターゲットソース行リスト.ElementAt(i)
             □コンソール.表示する(オリジナルのインデントを取得する(ソース行リスト,ターゲットソース.ソー0ス行番号))
             □コンソール.一行表示する(ターゲットソース.ターゲット行文字列)
        〇ここまで
    △
```
### 支援関数
#### ノードカテゴライズする から呼ばれる支援関数
##### ソース行ノードを判定する
ソース行のノードを判定して、ノード種類列挙体の特定値を返します。
```mind:Re:Mind
    /**
    * jugdeSourceLineNode
    * @param ソース行文字列 sourceLineString
    */
    ▽static ノード種類列挙体 ソース行ノードを判定する(string ソース行文字列)
        ・ノード種類 =new ノード種類列挙体
          ◇ソース行文字列.IndexOf(ソース行のノード種類.定義開始)==0 の場合
                □ノード種類=ノード種類列挙体.定義開始//定義開始
                □ソース行文字列=ソース行文字列.Substring(ソース行のノード種類.定義開始.Length)
         ◇他に ソース行文字列.IndexOf(ソース行のノード種類.定義終了)==0 の場合
                □ノード種類=ノード種類列挙体.ND_DEF_END;//定義終了
                □ソース行文字列=ソース行文字列.Substring(ソース行のノード種類.定義終了.Length)

         ◇他に ソース行文字列.IndexOf(ソース行のノード種類.宣言開始)==0 の場合
                □ノード種類=ノード種類列挙体.宣言開始//宣言開始
                □ソース行文字列=ソース行文字列.Substring(ソース行のノード種類.宣言開始.Length)

         ◇他に ソース行文字列.IndexOf(ソース行のノード種類.実行開始)==0 の場合
                □ノード種類=ノード種類列挙体.実行開始//実行開始
                □ソース行文字列=ソース行文字列.Substring(ソース行のノード種類.実行開始.Length)

         ◇他に ソース行文字列.IndexOf(ソース行のノード種類.引用開始)==0 の場合
                □ノード種類=ノード種類列挙体.引用開始//引用開始
                □ソース行文字列=ソース行文字列.Substring(ソース行のノード種類.引用開始.Length)

         ◇他に ソース行文字列.IndexOf(ソース行のノード種類.引用定義開始)==0 の場合
                □ノード種類=ノード種類列挙体.引用定義開始//引用定義開始
                □ソース行文字列=ソース行文字列.Substring(ソース行のノード種類.引用定義開始.Length)

         ◇他に ソース行文字列.IndexOf(ソース行のノード種類.引用定義中)==0 の場合
                □ノード種類=ノード種類列挙体.引用定義中//引用定義中
                □ソース行文字列=ソース行文字列.Substring(ソース行のノード種類.引用定義中.Length)

         ◇他に ソース行文字列.IndexOf(ソース行のノード種類.引用定義終了)==0 の場合
                □ノード種類=ノード種類列挙体.引用定義終了//引用定義終了
                □ソース行文字列=ソース行文字列.Substring(ソース行のノード種類.引用定義終了.Length)

         ◇他に ソース行文字列.IndexOf(ソース行のノード種類.単行備考開始)==0 の場合
                □ノード種類=ノード種類列挙体.単行備考開始//単行備考開始

         ◇他に ソース行文字列.IndexOf(ソース行のノード種類.JavaDoc備考開始)==0 の場合
                □ノード種類=ノード種類列挙体.JavaDoc備考開始//JavaDoc備考開始

         ◇他に ソース行文字列.IndexOf(ソース行のノード種類.JavaDoc備考途中)==0 の場合
              ◇ソース行文字列.IndexOf(ソース行のノード種類.JavaDoc備考変数)>=0 の場合
                   □ノード種類=ノード種類列挙体.JavaDoc備考変数//JavaDoc備考変数
              ◇他に ソース行文字列.IndexOf(ソース行のノード種類.JavaDoc備考終了)>=0 の場合
                   □ノード種類=ノード種類列挙体.JavaDoc備考終了//JavaDoc備考終了
              ◇他に
                   □ノード種類=ノード種類列挙体.JavaDoc備考途中//JavaDoc備考途中
              ◇ここまで

        ◇他に ソース行文字列== "" の場合
                □ノード種類=ノード種類列挙体.空改行//空改行
        ◇他に
                □ノード種類=ノード種類列挙体.例外//例外
        ◇ここまで
        □ノード種類を　返す
    △
```

#### トランスコンパイルする から呼ばれる支援関数
##### ターゲットソース行を生成する
```mind:Re:Mind
    /**
    * generateTargetSouceLine
    * @param ソース行 sourceLines
    * @param ターゲットソース行リスト targetSourcesLineList
    * @param ノード種類 nodeKind
    * @param 名称辞書 nameDictionary
    * @param ターゲットソース行番号 targetSouceLineNumber
    */
    ▽static int ターゲットソース行を生成する(ソース行型 ソース行,リスト型<ターゲットソース行型> ターゲットソース行リスト,ノード種類列挙体 ノード種類,辞書型<string, string> 名称辞書,ref int ターゲットソース行番号)
        ・int 戻り値 = 1
        ・ターゲットソース行 =new ターゲットソース行型
        ・ソース行文字列=ソース行.行文字列 ?? ""  
        ◇ノード種類　で分岐する
        ◇ノード種類列挙体.定義開始//定義開始
            □ターゲットソース行番号+=1
            □ターゲットソース行.ソース行番号=ソース行.ソース行番号
            □ターゲットソース行.ターゲット行文字列=名称辞書でターゲットソース行を置換する(名称辞書,ソース行文字列)//名称辞書で置換する
            □ターゲットソース行.ターゲットソース行番号=ターゲットソース行番号
            □ターゲットソース行リスト.追加(ターゲットソース行)

            □ターゲットソース行番号+=1
            □ターゲットソース行 =new ターゲットソース行型
            □ターゲットソース行.ソース行番号=ソース行.ソース行番号
            □ターゲットソース行.ターゲット行文字列=ターゲットソース行のノード種類.定義開始+改行コード//定義開始 中かっこ{を追加
            □ターゲットソース行.ターゲットソース行番号=ターゲットソース行番号
            □ターゲットソース行リスト.追加(ターゲットソース行)
            □脱出する
        ◇ノード種類列挙体.定義終了//定義終了
            □ターゲットソース行番号+=1
            □ターゲットソース行.ターゲットソース行番号=ターゲットソース行番号
            □ターゲットソース行.ターゲット行文字列=ターゲットソース行のノード種類.定義終了+改行コ//定義終了 中かっこ}を追加
            □ターゲットソース行.ターゲットソース行番号=ターゲットソース行番号
            □ターゲットソース行リスト.追加(ターゲットソース行)
            □脱出する
        ◇ノード種類列挙体.引用定義終了//引用定義終了
            □脱出する
        ◇ノード種類列挙体.宣言開始//宣言開始
        ◇ノード種類列挙体.実行開始//実行開始
            □ターゲットソース行番号+=1
            □ターゲットソース行.ターゲットソース行番号=ターゲットソース行番号
            □ターゲットソース行.ターゲット行文字列=名称辞書でターゲットソース行を置換する(名称辞書,ソース行文字列)+";"//名称辞書で置換し実行文終端;を追加
            □ターゲットソース行.ターゲットソース行番号=ターゲットソース行番号
            □ターゲットソース行リスト.追加(ターゲットソース行)
            □脱出する
        ◇ノード種類列挙体.引用開始//引用開始
        ◇ノード種類列挙体.引用定義開始//引用定義開始
            □脱出する
        ◇ノード種類列挙体.単行備考開始//単行備考開始
            □ターゲットソース行番号+=1
            □ターゲットソース行.ターゲットソース行番号=ターゲットソース行番号
            □ターゲットソース行.ターゲット行文字列=ソース行.行文字列//単行備考はそのまま
            □ターゲットソース行.ターゲットソース行番号=ターゲットソース行番号
            □ターゲットソース行リスト.追加(ターゲットソース行)
            □脱出する
        ◇ノード種類列挙体.JavaDoc備考開始//JavaDoc備考開始
            □脱出する
        ◇ノード種類列挙体.JavaDoc備考途中//JavaDoc備考途中
            □ターゲットソース行番号+=1
            □ターゲットソース行.ターゲットソース行番号=ターゲットソース行番号
            □ターゲットソース行.ターゲット行文字列= 名称辞書でJavaDoc備考途中を置換する(名称辞書,ソース行文字列,ターゲットソース行のノード種類.JavaDoc備考途中)
            □ターゲットソース行.ターゲットソース行番号=ターゲットソース行番号
            □ターゲットソース行リスト.追加(ターゲットソース行)
            □脱出する
        ◇ノード種類列挙体.JavaDoc備考変数//JavaDoc備考変数
            □ターゲットソース行番号+=1
            □ターゲットソース行.ターゲットソース行番号=ターゲットソース行番号
            □ターゲットソース行.ターゲット行文字列= 名称辞書でJavaDoc備考変数を置換する(名称辞書,ソース行文字列,ターゲットソース行のノード種類.JavaDoc備考変数)
            □ターゲットソース行.ターゲットソース行番号=ターゲットソース行番号
            □ターゲットソース行リスト.追加(ターゲットソース行)
            □脱出する
        ◇ノード種類列挙体.JavaDoc備考終了//JavaDoc備考終了
            □脱出する
        //行レベルカテゴライズ済のため例外は生じない
        ◇ここまで
        □ret=0//ここまで進行したら成功
        □戻り値を　返す
    △
```
##### 名称辞書でターゲットソース行を置換する
```mind:Re:Mind
    /**
    * nameDictionaryReplase
    * @param 名称辞書 nameDictionary
    * @param ソース行文字列 sourceLineString
    */
    ▽static string 名称辞書でターゲットソース行を置換する(辞書型<string, string> 名称辞書,string ソース行文字列)
        〇i=0,i<名称辞書.Count,i++ 繰り返す
            ・dic =名称辞書.ElementAt(i)
            ◇ソース行文字列.IndexOf(dic.Value)>=0 の場合
               □ソース行文字列=ソース行文字列.置換(dic.Key,dic.Value)
            ◇ここまで
        〇ここまで
        □ソース行文字列を　返す
    △
```
##### 名称辞書でJavaDoc備考途中を置換する
```mind:Re:Mind
    /**
    * nameDictionaryJavDocComMidNote
    * @param 名称辞書 nameDictionary
    * @param ソース行文字列 sourceLineString
    * @param JavaDoc備考途中 javDocComMidNote
    */
    ▽static string 名称辞書でJavaDoc備考途中を置換する(辞書型<string, string> 名称辞書,string ソース行文字列,string JavaDoc備考途中)
        〇i=0,i<名称辞書.Count,i++ 繰り返す
            ・dic =名称辞書.ElementAt(i)
            ◇ソース行文字列.IndexOf(dic.Value)>=0 の場合
               □ソース行文字列=JavaDoc備考途中.置換("jp",dic.Key)
               □脱出する
            ◇ここまで
        〇ここまで
        □ソース行文字列を　返す
    △
```
##### 名称辞書でJavaDoc備考変数を置換する
```mind:Re:Mind
    /**
    * nameDictionaryJavDocComParmNote
    * @param 名称辞書 nameDictionary
    * @param ソース行文字列 sourceLineString
    * @param JavaDoc備考変数 javDocComParmNote
    */
    ▽static string 名称辞書でJavaDoc備考変数を置換する(辞書型<string, string> 名称辞書,string ソース行文字列,string JavaDoc備考変数)
        〇i=0,i<名称辞書.Count,i++ 繰り返す
            ・dic =名称辞書.ElementAt(i)
            ◇ソース行文字列.IndexOf(dic.Key)>=0 の場合
               □ソース行文字列=JavaDoc備考変数.置換("jp",dic.Key).置換("en",dic.Value)
               □脱出する
            ◇ここまで
        〇ここまで
        □ソース行文字列を　返す
    △
```
# 参考リンク

https://qiita.com/mylifewithviolin/items/9a6abbab62c0f5e27d4b

https://qiita.com/mylifewithviolin/items/52f806777e6ea031de94

https://qiita.com/mylifewithviolin/items/ebb406bf5ea7a4eea24c