diff --git a/README_ja.md b/README_ja.md new file mode 100644 index 00000000..9efdc4ad --- /dev/null +++ b/README_ja.md @@ -0,0 +1,4 @@ +

+ Karaffe logo +

+

プログラミング言語 Karaffe

diff --git a/docs/AST_DOCUMENTATION_ja.md b/docs/AST_DOCUMENTATION_ja.md new file mode 100644 index 00000000..23d93ec5 --- /dev/null +++ b/docs/AST_DOCUMENTATION_ja.md @@ -0,0 +1,65 @@ +# Karaffeコンパイラ 抽象構文木 (AST) + +## 導入 + +抽象構文木(AST)は、プログラミング言語で書かれたソースコードの抽象的な構文構造を木構造で表現したものです。Karaffeコンパイラにおいて、ASTはあなたのKaraffeコードの重要な中間表現です。ソーステキストを解析した後、コンパイラはASTを構築します。この木は、意味解析、最適化、コード生成といった後続のコンパイルフェーズで使用されます。 + +ASTは、表面的な構文(括弧やセミコロンなど、その意味が木構造に暗黙的に含まれる場合)の多くを無視し、本質的な構成要素とその関係に焦点を当てることで、コードを構造的に扱う方法を提供します。 + +## コアコンセプト + +Karaffe ASTは、`src/main/java/org/karaffe/compiler/tree/` ディレクトリにあるいくつかのコアインターフェースとクラスを中心に構築されています。 + +### `Node` (`src/main/java/org/karaffe/compiler/tree/Node.java`) + +`Node` インターフェースは、AST内の単一のノードを表します。`Node` の主な側面は次のとおりです。 + +- **親子関係**: 各ノード(ルートを除く)は親を持ち、複数の子を持つことができ、木構造を形成します。`getParent()` や `getChildren()` のようなメソッドで走査が可能です。 +- **ノードタイプ**: すべてのノードは `NodeType`(下記参照)を持ち、それがどのような種類の言語構成要素を表すか(例:クラス定義、メソッド呼び出し、識別子)を指定します。 +- **ソース位置**: ノードは `Positioned` インターフェースを実装しており、元のソースファイル内での位置情報(行番号と列番号)を格納していることを意味します。これはエラー報告に不可欠です。 +- **操作**: このインターフェースは、`addChild(Tree child)` や `replaceThis(Tree after)` のように木を変更するためのメソッドを提供します。 + +### `Tree` (`src/main/java/org/karaffe/compiler/tree/Tree.java`) + +`Tree` インターフェースは `Node` を(`Term` を介して間接的に)拡張し、ASTを操作するためのより高レベルなオペレーションを提供します。これには以下が含まれます。 + +- **クエリ**: `dig(...)` や `climb(...)` のようなメソッドで、特定のノードやパターンを木の中で検索できます。 +- **プロセッサ**: `applyProcessor(Processor processor)` メソッドにより、ビジターパターンを使用して木に様々な操作(変換や解析など)を適用できます。 +- **挿入**: `insertBefore(Tree tree)` や `insertAfter(Tree tree)` のような便利なメソッドで、既存のノードに対して新しいノードを簡単に追加できます。 + +### `NodeType` (`src/main/java/org/karaffe/compiler/tree/NodeType.java`) + +このenumは、Karaffe ASTに存在しうるすべての可能なノードタイプを定義します。これらのタイプを理解することは、任意のKaraffeプログラムのASTの構造を理解する鍵となります。いくつかの重要な例を以下に示します。 + +- **`CompilationUnit`**: 単一ソースファイルのASTのルートです。 +- **`SourceFile`**: ソースファイル自体を表します。 +- **`Module`**: モジュール宣言を表します。 +- **`Package`**: パッケージ宣言を表します。 +- **`DefClass`**: クラス定義を表します。 +- **`DefConstructor`**: コンストラクタ定義を表します。 +- **`DefMethod`**: メソッド定義を表します。 +- **`DefVar`**: 変数定義(フィールド、ローカル変数)を表します。 +- **`Apply`**: メソッド呼び出しや関数適用を表します。 +- **`Select`**: オブジェクトやクラスのメンバーへのアクセス(例:`object.field`)を表します。 +- **`Identifier`**: 識別子(例:変数名、クラス名)を表します。 +- **`StringLiteral`**, **`IntLiteral`**: リテラル値を表します。 +- **`BinOp`**: 二項演算(例:`a + b`)を表します。 +- **`Assign`**: 代入操作を表します。 +- **`TypeName`**, **`VarName`**: 型名や変数名を表し、宣言や参照でよく使用されます。 + +これは網羅的なリストではありませんが、遭遇する可能性のある一般的なノードタイプの多くをカバーしています。 + +## さらなる探求 + +AST実装についてより深く掘り下げるには、ソースコードを直接調べることができます。 + +- **コアASTインターフェースとクラス**: [`src/main/java/org/karaffe/compiler/tree/`](./src/main/java/org/karaffe/compiler/tree/) + - [`Node.java`](./src/main/java/org/karaffe/compiler/tree/Node.java) + - [`NodeType.java`](./src/main/java/org/karaffe/compiler/tree/NodeType.java) + - [`Tree.java`](./src/main/java/org/karaffe/compiler/tree/Tree.java) + - [`SimpleTree.java`](./src/main/java/org/karaffe/compiler/tree/SimpleTree.java) (`Tree` の一般的な実装) + - [`TreeFactory.java`](./src/main/java/org/karaffe/compiler/tree/TreeFactory.java) (新しいツリーノードを作成するため) +- **AST Walker**: 木を走査するためには、[`src/main/java/org/karaffe/compiler/tree/walker/`](./src/main/java/org/karaffe/compiler/tree/walker/) を参照してください。 +- **AST Processor**: 木に対して実行される操作については、[`src/main/java/org/karaffe/compiler/tree/processor/`](./src/main/java/org/karaffe/compiler/tree/processor/) を参照してください。 + +これらのファイルと、それらがコンパイラ全体でどのように使用されているか(例:フロントエンドの解析段階やバックエンドのコード生成段階)を調べることで、KaraffeのASTについての包括的な理解を得ることができます。 diff --git a/docs/COMPILATION_PHASES_JA.md b/docs/COMPILATION_PHASES_JA.md new file mode 100644 index 00000000..26ca2756 --- /dev/null +++ b/docs/COMPILATION_PHASES_JA.md @@ -0,0 +1,58 @@ +# Karaffeコンパイラ:コンパイルフェーズ + +このドキュメントでは、Karaffeコンパイラの主要なコンパイルフェーズについて説明します。コンパイラは、Karaffeのソースコードを一連のステップで処理し、最終的に実行可能なコードまたはその他の出力を生成します。これらのステップは「フェーズ」として管理されます。 + +## コアコンセプト + +- **`Phase`**: コンパイルの個別の段階(例:解析、型チェック、コード生成)を表すインターフェース。各フェーズは `org.karaffe.compiler.phase.Phase` を実装します。 ([`src/main/java/org/karaffe/compiler/phase/Phase.java`](./src/main/java/org/karaffe/compiler/phase/Phase.java)) +- **`Phases`**: `Phase` オブジェクトのコレクション。コンパイラは通常、一連のフェーズを実行します。 ([`src/main/java/org/karaffe/compiler/phase/Phases.java`](./src/main/java/org/karaffe/compiler/phase/Phases.java)) +- **`CompilerContext`**: ソースファイル、解析結果、生成されたAST/IR、エラーや警告など、コンパイルの状態を保持するオブジェクト。フェーズは `CompilerContext` から読み取り、書き込みを行います。 ([`src/main/java/org/karaffe/compiler/util/CompilerContext.java`](./src/main/java/org/karaffe/compiler/util/CompilerContext.java)) +- **`DefaultPhasesFactory`**: 標準的なコンパイルフェーズのシーケンスを作成する責任を負います。 ([`src/main/java/org/karaffe/compiler/phase/DefaultPhasesFactory.java`](./src/main/java/org/karaffe/compiler/phase/DefaultPhasesFactory.java)) + +## 主なコンパイルフロー + +全体のコンパイルプロセスは `org.karaffe.compiler.KaraffeCompiler` によって調整されます。これはフロントエンドを呼び出し、次にバックエンドを呼び出します。 + +### 1. フロントエンドフェーズ (`org.karaffe.compiler.phase.frontend.karaffe.KaraffeFrontend`) + +`KaraffeFrontend` は、ソースコードを処理する初期フェーズをグループ化します。これらは通常、順次実行されます。 ([`src/main/java/org/karaffe/compiler/phase/frontend/karaffe/KaraffeFrontend.java`](./src/main/java/org/karaffe/compiler/phase/frontend/karaffe/KaraffeFrontend.java)) + +#### 1.1. 解析 (`KaraffeParsePhase`) +- **名前**: `frontend-karaffe-parser` +- **説明**: これは最初の主要なフェーズです。生のKaraffeソースコードを入力として受け取り、解析木(具象構文木またはCSTとも呼ばれる)を生成します。 + - ANTLRで生成された `KaraffeLexer` を使用して、ソースコードをトークンに分割します。 + - 次に `KaraffeParser` を使用して、`Karaffe.g4` で定義された文法に基づいて解析木を構築します。 +- **入力**: Karaffeソースファイル。 +- **出力**: ソースファイル名とその `KaraffeParser.SourceFileContext`(そのファイルの解析木のルート)のマップ。このマップは `CompilerContext` にキー `"parse.result"` で格納されます。 +- **ソース**: [`src/main/java/org/karaffe/compiler/phase/frontend/karaffe/KaraffeParsePhase.java`](./src/main/java/org/karaffe/compiler/phase/frontend/karaffe/KaraffeParsePhase.java) + +#### 1.2. 中間表現 (IR) 生成 (`IRPhase`) +- **名前**: `ir` +- **説明**: このフェーズは `KaraffeParsePhase` によって生成された解析木を受け取り、それらをより抽象的な表現である抽象構文木(AST)または類似の中間表現(IR)に変換します。このIRは、後続の分析および最適化フェーズで扱いやすくなります。 + - `IRGen` クラス(おそらくANTLRビジター)を使用して解析木をウォークし、IR/ASTを構築します。 + - 生成されるAST構造は `org.karaffe.compiler.tree.*` で定義されています(`AST_DOCUMENTATION_ja.md` を参照)。 +- **入力**: `CompilerContext` からの解析木マップ(キー: `"parse.result"`)。 +- **出力**: 生成されたIR/AST。(これを `CompilerContext` に保存したり、バックエンドで利用可能にする正確なメカニズムは、`IRGen` または `IR` オブジェクト自体の中にある可能性があります)。 +- **ソース**: [`src/main/java/org/karaffe/compiler/phase/frontend/karaffe/IRPhase.java`](./src/main/java/org/karaffe/compiler/phase/frontend/karaffe/IRPhase.java) +- **関連**: [`src/main/java/org/karaffe/compiler/phase/frontend/karaffe/IRGen.java`](./src/main/java/org/karaffe/compiler/phase/frontend/karaffe/IRGen.java) + +### 2. バックエンドフェーズ (例: `org.karaffe.compiler.phase.backend.jvm.BackendForJavaVM`) + +フロントエンドが完了した後、`KaraffeCompiler` は明示的にバックエンドを呼び出します。バックエンドは、IR/ASTを受け取り、ターゲット固有のコードを生成する責任を負います。 + +#### 2.1. JVMバックエンド (`BackendForJavaVM`) +- **名前**: `jvm` +- **説明**: このバックエンドは、Java仮想マシン(JVM)バイトコードを生成することを目的としています。 + - *注: 前回のレビュー時点では、このフェーズの `execute` メソッドは空であり、開発中であるか、ロジックが異なる方法でトリガーされる可能性を示唆しています。* +- **入力**: フロントエンドによって生成されたIR/AST。 +- **出力**: JVMバイトコード(例:`.class` ファイル)。 +- **ソース**: [`src/main/java/org/karaffe/compiler/phase/backend/jvm/BackendForJavaVM.java`](./src/main/java/org/karaffe/compiler/phase/backend/jvm/BackendForJavaVM.java) + +## ユーティリティフェーズ + +`DefaultPhasesFactory` は、ユーティリティフェーズも設定します。 +- **`ShowUsagePhase`**: コマンドラインの使用情報を表示します。 +- **`ShowVersionPhase`**: コンパイラのバージョンを表示します。 +- **`ShowReportsPhase`**: コンパイル中に生成されたエラー、警告、または情報メッセージを表示します。 + +この構造により、モジュール式で拡張可能なコンパイラ設計が可能になり、新しいフェーズを追加したり、既存のフェーズを変更してコンパイラの動作を変更または強化したりすることができます。 diff --git a/docs/GRAMMAR_OVERVIEW_JA.md b/docs/GRAMMAR_OVERVIEW_JA.md new file mode 100644 index 00000000..9f7da004 --- /dev/null +++ b/docs/GRAMMAR_OVERVIEW_JA.md @@ -0,0 +1,95 @@ +# Karaffeコンパイラ:ANTLR文法概要 (`Karaffe.g4`) + +このドキュメントでは、Karaffeプログラミング言語の構文を定義する `Karaffe.g4` ANTLR文法ファイルの概要を説明します。ANTLR (ANother Tool for Language Recognition) は、Karaffeでソースコードを読み取り、解析木(または具象構文木 - CST)を構築するために使用されるパーサジェネレータです。この解析木は、IR/AST生成フェーズなど、後のコンパイラフェーズで処理されます。 + +文法ファイル `Karaffe.g4` は次の場所にあります: [`src/main/antlr/Karaffe.g4`](./src/main/antlr/Karaffe.g4) + +## 文法ファイルの構造 + +`Karaffe.g4` ファイルは、主に2種類のルールで構成されています。 + +1. **パーサールール**: これらのルールは、言語の構文構造を定義します – キーワード、識別子、式、文などがどのように組み合わされて有効なKaraffeプログラムを形成するか。パーサールールの名前は通常、小文字で始まります (例: `sourceFile`, `classDef`, `expr`)。 +2. **レキサールール**: これらのルールは、言語の基本的なトークンを定義します – キーワード、識別子、リテラル(文字列、数値)、演算子など、最小の構成要素。レキサールールの名前は通常、大文字で始まります (例: `CLASS`, `IDENTIFIER`, `StringLiteral`)。 + +## 主要なパーサールール + +Karaffeコードの全体構造を定義する最も重要なパーサールールの一部を以下に示します。 + +- **`sourceFile`**: 完全なKaraffeソースファイルを解析するためのエントリポイント(または「開始記号」)です。基本的には、ソースファイルをクラス定義のシーケンス (`classDef*`) とそれに続くファイル終端マーカー (`EOF`) として定義します。 + ```antlr + sourceFile + : classDef* EOF + ; + ``` + +- **`classDef`**: クラス定義の構文を定義します。`CLASS` キーワードで始まり、`Identifier`(クラス名)が続き、オプションでクラス本体 (`typeDefBody`) が続きます。 + ```antlr + classDef + : CLASS Identifier nl? typeDefBody? nl? + ; + ``` + +- **`typeDefBody`**: 中括弧 `{ }` で囲まれたクラスの本体を表します。複数の `statement` を含むことができます。 + ```antlr + typeDefBody + : LBRACE nl? statement* RBRACE nl? + ; + ``` + +- **`statement`**: このルールは、クラス本体内に現れる可能性のあるさまざまな種類の文をカバーします。これには以下が含まれます。 + - `entryPointBlock`: `ENTRYPOINT` キーワードでマークされた特別なブロックで、おそらくプログラム実行のメインエントリポイントです。 + - `initBlock`: `INIT` キーワードでマークされたブロックで、おそらく初期化コード用です。 + - `varDef`: 変数定義(`DEF` キーワードを使用)。 + - `assign`: 代入文。 + - `expr`: 文として使用される一般的な式(例:関数呼び出し)。 + +- **`varDef`** および **`binding`**: これらのルールは、変数がどのように宣言されるかを定義します。`varDef` は `DEF` キーワードを使用し、その後に `binding`(`Identifier` と `typeName`)が続き、オプションで初期化子が続きます。 + ```antlr + varDef + : DEF binding ('=' initializer=expr)? nl? + ; + + binding + : Identifier typeName nl? + ; + ``` + +- **`expr`**: これは式の構造を定義する重要なルールです。Karaffeの式は次のようになります。 + - 識別子 (`id=Identifier`) + - リテラル (`lit=literal`) + - `this` キーワード (`t=THIS`) + - 関数呼び出し (`function=expr LPAREN args=exprList? RPAREN`) + - 二項演算 (`left=expr right=opExpr+` ここで `opExpr` は `op=binaryOperator right=expr`) + - メンバーアクセス (`target=expr DOT name=Identifier`) + - 括弧で囲まれた式 (`LPAREN inExpr=expr RPAREN`) + +- **`nl` / `newLine`**: これらのルールは、改行とセミコロンを文の終端記号またはオプションの区切り文字として処理します。 + +## 主要なレキサールール + +レキサールールは、入力テキストから直接認識されるトークンを定義します。 + +- **キーワード**: `CLASS`, `DEF`, `ENTRYPOINT`, `INIT`, `IF`, `WHILE`, `RETURN`, `TRUE`, `FALSE`, `NULL`, `THIS` など、多くのキーワードが定義されています。各キーワードは特定の文字列リテラルです (例: `CLASS: 'class';`)。 +- **`Identifier`**: 有効な識別子(クラス、メソッド、変数の名前)を構成するものを定義します。Karaffeでは、識別子は文字と数字のシーケンス、または演算子文字のシーケンス(例: `+`, `==`, `*`)にすることができます。 + ```antlr + Identifier + : Letter LetterOrDigit* + | OperatorChar+ + // ... 他の形式 + ; + ``` + これは、`+` や `*` のような記号がレキサーによって識別子として扱われ、演算子としての意味は、おそらく後の解析または意味解析段階で `binaryOperator` パーサールールに基づいて決定されることを意味します。 +- **`StringLiteral`**: 文字列リテラルを定義します (例: `"hello"`)。 +- **`IntegerLiteral`**: 整数リテラルを定義します (例: `123`, `0`)。 +- **演算子と句読点**: `LPAREN` (`(`), `RPAREN` (`)`), `LBRACE` (`{`), `RBRACE` (`}`), `DOT` (`.`), `COMMA` (`,`), `SEMI` (`;`) のようなトークンが定義されています。 +- **`WS` (空白)**: スキップするように定義されているため (`-> skip`)、空白は一般にトークンを区切る以外にはパーサーにとって重要ではありません。 + +## 仕組み + +Karaffeコンパイラがソースファイルに遭遇すると: +1. `KaraffeLexer`(`Karaffe.g4` から生成)がソースコードを読み取り、レキサールールに基づいてトークンのストリームに分割します(例:`CLASS`, `Identifier "MyClass"`, `LBRACE` など)。 +2. `KaraffeParser`(これも `Karaffe.g4` から生成)がこのトークンストリームを受け取り、`sourceFile` ルールから始めてパーサールールに照合しようとします。 +3. トークンストリームが文法に準拠している場合、パーサーは正常に解析木を構築します。この木はコードの構文構造を表します。たとえば、ツリー内の `classDef` ノードには、`CLASS` キーワード、クラス `Identifier`、およびその `typeDefBody` の子があります。 +4. この解析木は、抽象構文木(AST)を生成し、さらなる分析を実行するために、後続のコンパイラフェーズ(`COMPILATION_PHASES_JA.md` で説明されている `IRPhase` など)に渡されます。 + +`Karaffe.g4` 文法を理解することは、Karaffeコンパイラによって受け入れられる正確な構文と、ソースコードが最初にどのように処理されるかを理解するために不可欠です。