# 機能設計書 88-パーサー

## 概要

本ドキュメントは、Juliaのパーサー機能の設計を記述する。JuliaSyntax.jl をメインパーサーとし、Flisp（Femtolisp）ベースのレガシーパーサーをフォールバックとして備えた、ソースコードの構文解析システムである。

### 本機能の処理概要

パーサーは、Julia ソースコードのテキストを受け取り、抽象構文木（AST）に変換する機能である。

**業務上の目的・背景**：プログラミング言語の実行には、まずソースコードテキストをコンピュータが理解できる構造化された表現（AST）に変換する必要がある。Julia のパーサーは、Julia 固有の構文（多重ディスパッチ、ブロードキャスト演算子、マクロ、文字列補間、行列リテラル等）を正確に解析する。JuliaSyntax.jl は Julia 自体で記述された新しいパーサーであり、エラー回復機能やより良いエラーメッセージを提供する。

**機能の利用シーン**：
- ソースファイルの `include` / `require` 時の解析
- REPL での入力式の解析
- マクロ展開時の文字列パース（`Meta.parse`）
- IDE/エディタでのシンタックスハイライトと補完

**主要な処理内容**：
1. トークン化（lexing）: ソーステキストをトークン列に分割
2. パース（parsing）: トークン列から構文木を構築
3. リテラルパース: 文字列・数値等のリテラルの解釈
4. 構文木の Expr 変換: JuliaSyntax の構文木から Core.Expr への変換
5. エラー回復: 構文エラー時の部分的な解析続行

**関連システム・外部連携**：REPL（No.102）がユーザー入力の解析にパーサーを使用。マクロシステム（No.54）がマクロ展開時にパーサーを呼び出す。eval（No.58）がパース結果の AST を評価する。

**権限による制御**：特になし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | Juliaプロンプト（julia>） | 補助機能 | JuliaSyntaxベースのパーサーによる入力式の構文解析。括弧対応・入力完了判定に使用 |
| 11 | フォールバックREPL | 補助機能 | parse_input_line()内でのJuliaSyntaxによる構文解析 |

## 機能種別

計算処理（構文解析処理）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| source | String / IO | Yes | 解析対象のJuliaソースコード | UTF-8エンコーディング |
| rule | Symbol | No | パースルール（:all, :statement, :atom）。デフォルトは :all | 有効なルール名 |
| filename | String | No | ソースファイル名（エラーメッセージ用） | - |

### 入力データソース

- ソースファイル（`include` / `require` 経由）
- REPL 入力
- `Meta.parse` への文字列引数

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Expr | Core.Expr | Julia の標準 AST 表現 |
| SyntaxNode | JuliaSyntax.SyntaxNode | JuliaSyntax の構文木（詳細情報付き） |
| GreenNode | JuliaSyntax.GreenNode | 位置情報付きの構文木 |
| Diagnostics | Vector{Diagnostic} | パースエラー・警告のリスト |

### 出力先

- eval / 型推論 / マクロ展開への入力
- REPL のエラー表示

## 処理フロー

### 処理シーケンス

```
1. ParseStream の構築
   └─ ソーステキストからトークンストリームを初期化
2. トークン化（lexing）
   └─ Tokenize モジュールによるトークン分割
3. パース
   └─ ParseState を初期化
   └─ ルールに応じた解析関数を呼び出し
     ├─ :all → parse_toplevel
     ├─ :statement → parse_stmts
     └─ :atom → parse_atom
4. 構文木の構築
   └─ build_tree で GreenNode/SyntaxNode を構築
5. Expr への変換
   └─ SyntaxNode → Core.Expr の変換
6. エラー処理
   └─ ParseError があれば Diagnostics に格納
```

### フローチャート

```mermaid
flowchart TD
    A[ソースコード入力] --> B[ParseStream 構築]
    B --> C[トークン化]
    C --> D[ParseState 初期化]
    D --> E{パースルール}
    E -->|:all| F[parse_toplevel]
    E -->|:statement| G[parse_stmts]
    E -->|:atom| H[parse_atom]
    F --> I[build_tree]
    G --> I
    H --> I
    I --> J[SyntaxNode → Expr 変換]
    J --> K{エラーあり?}
    K -->|Yes| L[ParseError 生成]
    K -->|No| M[Expr を返却]
    L --> M
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-88-01 | スペース感度 | 行列リテラル内では `x -y` が2つの式（x, -y）として解釈される（space_sensitive モード） | 行列リテラル内 |
| BR-88-02 | コロンレンジ | 三項演算子の解析中はコロンレンジが無効化される（range_colon_enabled = false） | 三項演算子内 |
| BR-88-03 | end シンボル | 配列インデックス内では `end` が予約語ではなくシンボルとして扱われる | インデックス式内 |
| BR-88-04 | for ジェネレータ | マクロ引数解析中に `for` が出現するとジェネレータ式として解釈される | マクロ引数内 |
| BR-88-05 | エラー回復 | 構文エラー発生後もパースを続行し、可能な限り多くの診断情報を収集する | パースエラー時 |

### 計算ロジック

特になし。パーサーは再帰降下法に基づく文脈自由文法の解析器である。

## データベース操作仕様

本機能はデータベースを使用しない。

### 操作別データベース影響一覧

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ParseError | 不正な構文 | Diagnostics に記録。REPL ではエラー表示後に続行 |
| - | incomplete_tag | 入力が不完全（閉じ括弧不足等） | REPL では追加入力を待つ |
| - | ArgumentError | 不正な rule パラメータ | 例外 throw |

### リトライ仕様

REPL では入力が不完全な場合、追加入力を待って再パースする。

## トランザクション仕様

該当なし。

## パフォーマンス要件

- パース速度はREPLの応答性に直結するため、高速であるべき
- JuliaSyntax.jl は Julia で記述されており、JITコンパイル後は高速に動作
- 大きなソースファイルのパースも線形時間で完了すべき

## セキュリティ考慮事項

- パーサーはコード実行を行わないため、パース自体は安全
- ただし、パース結果が eval に渡されるため、入力ソースの信頼性は重要

## 備考

- Flisp パーサーは `src/flisp/` にあり、レガシーサポートとして残されている
- JuliaSyntax は Julia v1.12 以降で SyntaxGraph もサポート
- `parsestmt`, `parseall`, `parseatom` がパブリック API として export されている

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | parser.jl | `JuliaSyntax/src/julia/parser.jl` | ParseState 構造体（1-42行目）: パーサーの状態管理 |
| 1-2 | JuliaSyntax.jl | `JuliaSyntax/src/JuliaSyntax.jl` | モジュール構成（1-111行目）: 全体のファイル構成と export 一覧 |

**読解のコツ**: ParseState の各フィールド（range_colon_enabled, space_sensitive, for_generator, end_symbol, whitespace_newline, where_enabled）はコンテキスト依存の構文解析を制御するフラグである。Julia の文法は文脈に応じて演算子の解釈が変わるため、これらのフラグが重要な役割を果たす。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | parser_api.jl | `JuliaSyntax/src/julia/parser_api.jl` | parse! 関数（47-60行目）: メインのパースAPI |
| 2-2 | parser_api.jl | `JuliaSyntax/src/julia/parser_api.jl` | ParseError 構造体（7-16行目）: パースエラーの表現 |

**主要処理フロー**:
1. **47行目**: parse! がエントリーポイント。rule パラメータでパースモードを選択
2. **52行目**: ParseState を ParseStream から構築
3. **53-59行目**: rule に応じて parse_toplevel / parse_stmts / parse_atom を呼び出し

#### Step 3: トークン化を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | tokenize.jl | `JuliaSyntax/src/julia/tokenize.jl` | トークナイザの実装 |
| 3-2 | kinds.jl | `JuliaSyntax/src/julia/kinds.jl` | トークン種別（Kind）の定義 |

#### Step 4: 構文木構築を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | green_node.jl | `JuliaSyntax/src/porcelain/green_node.jl` | GreenNode: 位置情報付き構文木 |
| 4-2 | syntax_node.jl | `JuliaSyntax/src/porcelain/syntax_node.jl` | SyntaxNode: 利用しやすい構文木 |
| 4-3 | expr.jl | `JuliaSyntax/src/integration/expr.jl` | SyntaxNode → Core.Expr 変換 |

#### Step 5: Flisp パーサーを理解する（レガシー）

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | flisp.c | `src/flisp/flisp.c` | Flisp インタプリタのメイン |
| 5-2 | julia_extensions.c | `src/flisp/julia_extensions.c` | Julia 固有の Flisp 拡張 |

### プログラム呼び出し階層図

```
Base.include / Meta.parse / REPL入力
    |
    +-- JuliaSyntax.parse! (parser_api.jl)
    |      +-- ParseState 構築 (parser.jl)
    |      +-- トークン化 (tokenize.jl)
    |      +-- parse_toplevel / parse_stmts / parse_atom (parser.jl)
    |      +-- build_tree (green_node.jl / syntax_node.jl)
    |      +-- SyntaxNode → Expr 変換 (expr.jl)
    |
    +-- (フォールバック) Flisp パーサー
           +-- fl_parse (flisp.c)
           +-- julia_extensions (julia_extensions.c)
```

### データフロー図

```
[入力]                    [処理]                         [出力]

ソーステキスト     --> トークン化                   --> Token列
Token列            --> 再帰降下パース               --> GreenNode (CST)
GreenNode          --> build_tree                    --> SyntaxNode
SyntaxNode         --> Expr変換                      --> Core.Expr (AST)
エラー情報         --> Diagnostics 収集              --> ParseError / warnings
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| JuliaSyntax.jl | `JuliaSyntax/src/JuliaSyntax.jl` | ソース | モジュール定義・ファイル構成 |
| parser.jl | `JuliaSyntax/src/julia/parser.jl` | ソース | ParseState と再帰降下パーサー |
| parser_api.jl | `JuliaSyntax/src/julia/parser_api.jl` | ソース | パブリック API（parse!, parsestmt 等） |
| tokenize.jl | `JuliaSyntax/src/julia/tokenize.jl` | ソース | トークナイザ |
| kinds.jl | `JuliaSyntax/src/julia/kinds.jl` | ソース | トークン種別定義 |
| literal_parsing.jl | `JuliaSyntax/src/julia/literal_parsing.jl` | ソース | リテラルの解析 |
| green_node.jl | `JuliaSyntax/src/porcelain/green_node.jl` | ソース | GreenNode 構文木 |
| syntax_node.jl | `JuliaSyntax/src/porcelain/syntax_node.jl` | ソース | SyntaxNode 構文木 |
| expr.jl | `JuliaSyntax/src/integration/expr.jl` | ソース | Expr 変換 |
| hooks.jl | `JuliaSyntax/src/integration/hooks.jl` | ソース | Base との統合フック |
| parse_stream.jl | `JuliaSyntax/src/core/parse_stream.jl` | ソース | ParseStream データ構造 |
| source_files.jl | `JuliaSyntax/src/core/source_files.jl` | ソース | ソースファイル管理 |
| diagnostics.jl | `JuliaSyntax/src/core/diagnostics.jl` | ソース | エラー診断 |
| flisp.c | `src/flisp/flisp.c` | ソース | Flisp インタプリタ（レガシーパーサー） |
| julia_extensions.c | `src/flisp/julia_extensions.c` | ソース | Julia 固有の Flisp 拡張 |
