From 863a6ed0ad723e06c76f392d4fb3a5f6bd22863c Mon Sep 17 00:00:00 2001 From: Jun Kawasaki Date: Tue, 6 Oct 2026 13:01:11 +0900 Subject: docs: add Japanese translations for all chapters --- chapter07/README.ja.md | 229 ++++++++++++++++++++++++++++++++++++++++ chapter07/README.md | 2 + chapter07/docs/07-grammar.ja.md | 93 ++++++++++++++++ chapter07/docs/07-grammar.md | 2 + 4 files changed, 326 insertions(+) create mode 100644 chapter07/README.ja.md create mode 100644 chapter07/docs/07-grammar.ja.md (limited to 'chapter07') diff --git a/chapter07/README.ja.md b/chapter07/README.ja.md new file mode 100644 index 00000000..9b0c7747 --- /dev/null +++ b/chapter07/README.ja.md @@ -0,0 +1,229 @@ +# 第7章: While 文 + +[English](README.md) | 日本語 + +この文書は [原文](README.md) の日本語訳です。 + +[前の章: 第6章](../chapter06/README.ja.md) | +[次の章: 第8章](../chapter08/README.ja.md) + +# 目次 + +1. [バックエッジの扱い](#バックエッジの扱い) +2. [新しいノード型](#新しいノード型) +3. [詳細な手順](#詳細な手順) +4. [可視化](#可視化) +5. [入れ子のループ](#入れ子のループ) +6. [If を内包するループ](#if-を内包するループ) + +[linear](https://github.com/SeaOfNodes/Simple/tree/linear) ブランチの直線的な Git のリビジョン履歴で [この章](https://github.com/SeaOfNodes/Simple/tree/linear-chapter07) を読み、前の章と [比較](https://github.com/SeaOfNodes/Simple/compare/linear-chapter06...linear-chapter07) することもできます。 + +この章では `while` 文を導入します。 + +この章の [完全な言語文法](docs/07-grammar.ja.md) はこちらです。 + +## バックエッジの扱い + +ループ構造によって生じる難しさは、反復時に変数がループ本体へ戻ってくることです。たとえば、次のコードです。 + +```java +while(arg < 10) { + arg = arg + 1; +} +return arg; +``` + +変数 `arg` にはループ本体内で新しい値が代入され、その値がループ本体へ戻ります。 + +一般に、ループ構造を次のように書き換えます。 + +```java +loop_head: +if( !(arg < 10) ) + goto loop_exit; +arg = arg + 1; +goto loop_head; + +loop_exit: +``` + +これは説明のためのもので、この言語にはラベルや `goto` 文はありません。 + +SSA[^1] の観点では、`arg` が戻ってくるため、先頭に `phi` ノードが必要です。概念的には、次のような結果にしたいのです。 + +```java +// arg1 represents incoming arg +// +loop_head: +arg2 = phi(arg1, arg3); +if( !(arg2 < 10) ) + goto loop_exit; +arg3 = arg2 + 1; +goto loop_head; + +loop_exit: +``` + +`arg2` の phi が `arg3` を参照することに注目してください。`while` ループの条件を解析する時点では、`arg3` はまだわかりません。常に SSA 形式である Sea of Nodes グラフを正しく構築するために解決すべき問題の核心は、ここにあります。 + +[第5章](../chapter05/README.ja.md) を思い出してください。`if` 文の解析では、`if` の条件を過ぎるときにシンボルテーブルを複製します。後で2組のシンボルテーブルを `Region` でマージし、`if` 文の2つの分岐内で定義が変わったすべての名前に phi を作ります。`if` 文の場合、マージする定義がすでにわかっているマージ地点で phi を作ります。 + +ループ構造に対する基本的な考えは、ループ本体内でどの名前が再定義されるかわからないため、ループの `if` 条件に入る *前に*、シンボルテーブル内のすべての名前に対して積極的に phi を作ることです。ループが終わると、さかのぼって不要な phi を削除します。これを「eager phi(先行生成する phi)」方式と呼びます。[^2] + +[第8章](../chapter08/README.ja.md) では、名前の再定義に遭遇したときだけ phi を作る「lazy phi(遅延生成する phi)」方式を実装します。 + +## 新しいノード型 + +ノードの一覧は [第5章](../chapter05/README.ja.md) と同じですが、必要な追加ロジックの一部をより適切にカプセル化するため、`Region` のサブタイプ `Loop` を作ります。Loop と Phi のピープホール最適化では、バックエッジが必要な書き換えを、ループ本体の解析が完了するまで延期します。ほかのノードは通常どおり最適化を続けます。 + +## 詳細な手順 + +1. まず、`Region` の新しいサブクラス `Loop` を作ります。`Loop` は2つの制御入力を取ります。最初は入口、すなわち `$ctrl` の現在の束縛です。2つ目(`null`)は、ループ解析後に設定するバックエッジのためのプレースホルダーです。バックエッジの欠如は、Loop と対応する Phi が未完成であることを示します。そのため、それらのピープホール最適化は、各書き換えに必要な入力がそろうまで待ちます。 + + ```java + ctrl(new LoopNode(ctrl(),null).peephole()); + ``` + + 新しく作った Region が現在の制御になります。 + +2. 現在の Scope ノードを複製します。スコープ内のすべての階層のシンボルを複製し、`$ctrl` の束縛を除くすべてのシンボルに phi を作ります。 + + ```java + // Make a new Scope for the body. + _scope = _scope.dup(true); + ``` + + `dup` の呼び出しに引数 `true` を渡すことに注目してください。これが phi の作成を引き起こします。`dup()` メソッドで phi を作るコードを次に示します。 + + ```java + // boolean loop=true if this is a loop region + + String[] names = reverseNames(); // Get the variable names + dup.add_def(ctrl()); // Control input is just copied + for( int i=1; ikeep().peephole(); + // Setup projection nodes + Node ifT = new ProjNode(ifNode, 0, "True" ).peephole(); + ifNode.unkeep(); + Node ifF = new ProjNode(ifNode, 1, "False").peephole(); + ``` + +4. 現在のスコープをもう一度複製します。これはループ終了後に生き続ける出口スコープなので、出口スコープの `$ctrl` を `False` 射影に設定します。出口スコープは、ループの条件式の副作用も取り込みます。 + + ```java + // The exit scope, accounting for any side effects in the predicate + var exit = _scope.dup(); + exit.ctrl(ifF); + ``` + +5. 制御を `True` 射影に設定し、ループ本体を解析します。 + + ```java + // Parse the true side, which corresponds to loop body + ctrl(ifT); // set ctrl token to ifTrue projection + parseStatement(); // Parse loop body + ``` + +6. ループ本体の解析後、先ほど作ったすべての phi に戻って処理します。 + + ```java + // The true branch loops back, so whatever is current control gets + // added to head loop as input + head.endLoop(_scope, exit); + ``` + + `endLoop` メソッドは、ループ Region の2つ目の制御をバックエッジの制御に設定します。続いてすべての phi をたどり、それぞれの2つ目のデータ入力をループ本体の対応する項目に設定します。使われなかった phi はピープホール最適化され、元の入力に置き換わります。 + + ```java + Node ctrl = ctrl(); + ctrl.set_def(2,back.ctrl()); + for( int i=1; i 訳注: 原文の見出しは「Grammar for Chapter 6」ですが、このファイルは第7章に属するため、訳の見出しは第7章としています。文法は原文のまま保持しています。 + + +[第7章に戻る](../README.ja.md) + +```antlrv4 +grammar SimpleLanguage; + +program + : statement+ EOF + ; + +statement + : returnStatement + | declStatement + | blockStatment + | expressionStatement + | ifStatement + | whileStatement + ; + +whileStatement + : 'while' '(' expression ')' statement + ; + +ifStatement + : 'if' '(' expression ')' statement ('else' statement)? + ; + + +expressionStatement + : IDENTIFIER '=' expression ';' + ; + +blockStatement + : '{' statement+ '}' + ; + +declStatement + : 'int' IDENTIFIER '=' expression ';' + ; + +returnStatement + : 'return' expression ';' + ; + +expression + : comparisonExpression + ; + +comparisonExpression + : additiveExpression (('==' | '!='| '>'| '<'| '>='| '<=') additiveExpression)* + ; + +additiveExpression + : multiplicativeExpression (('+' | '-') multiplicativeExpression)* + ; + +multiplicativeExpression + : unaryExpression (('*' | '/') unaryExpression)* + ; + +unaryExpression + : ('-') unaryExpression + | primaryExpression + ; + +primaryExpression + : IDENTIFIER + | INTEGER_LITERAL + | 'true' + | 'false' + | '(' expression ')' + ; + +INTEGER_LITERAL + : [1-9][0-9]* + | [0] + ; + +IDENTIFIER + : NON_DIGIT (NON_DIGIT | DIGIT)* + ; + +NON_DIGIT: [a-zA-Z_]; +DEC_DIGIT: [0-9]; +``` diff --git a/chapter07/docs/07-grammar.md b/chapter07/docs/07-grammar.md index 21c5ad0a..51ef8ebe 100644 --- a/chapter07/docs/07-grammar.md +++ b/chapter07/docs/07-grammar.md @@ -1,5 +1,7 @@ # Grammar for Chapter 6 +English | [日本語](07-grammar.ja.md) + ```antlrv4 grammar SimpleLanguage; -- cgit v1.2.3