# 機能設計書 24 --nodes オプション

## 概要

本ドキュメントは、CoffeeScript CLIツールの `--nodes` (`-n`) オプションの機能設計を記述する。このオプションは、パーサーが生成する構文木（Abstract Syntax Tree）を人間が読める形式で出力する機能を提供する。

### 本機能の処理概要

`--nodes` オプションは、CoffeeScriptコードをパースした結果の構文木を視覚的に表示する機能を提供する。コンパイラがソースコードをどのように解釈しているかを理解するためのデバッグ・学習ツールとして活用できる。

**業務上の目的・背景**：CoffeeScriptコンパイラの内部動作を理解したり、構文エラーの原因を特定したりする際に、パーサーが生成する構文木を確認することが有用である。`--nodes` オプションにより、ソースコードがどのようなノード構造に変換されているかを可視化でき、コンパイラの動作理解やデバッグに役立つ。

**機能の利用シーン**：
- コンパイラの内部動作を学習・理解したい場合
- 予期しないコンパイル結果の原因を調査したい場合
- CoffeeScriptコンパイラの開発・デバッグを行う場合
- CoffeeScriptの言語仕様を深く理解したい場合

**主要な処理内容**：
1. CoffeeScriptソースコードを字句解析してトークン列を生成
2. トークン列をパースして構文木（Nodes）を生成
3. 構文木のtoString()メソッドを呼び出して文字列表現を取得
4. 結果をtrim()して標準出力に表示

**関連システム・外部連携**：なし

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | CLIオプションのため関連画面なし |

## 機能種別

デバッグ出力 / 構文解析結果表示

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| --nodes / -n | boolean | No | 構文木出力モードを有効にする | オプションの有無で判定 |
| source | string | Yes | 解析対象のCoffeeScriptファイルまたはコード | ファイルが存在するか、有効なコードであること |

### 入力データソース

- ファイルシステム（CoffeeScriptソースファイル）
- コマンドライン引数（`--eval` 併用時）
- 標準入力（`--stdio` 併用時）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| node tree | string | 構文木のツリー表現文字列 |

### 出力先

- 標準出力（process.stdout）

## 処理フロー

### 処理シーケンス

```
1. コマンドライン引数をパース
   └─ --nodes オプションが指定されているか確認

2. ソースコードの取得
   └─ ファイル、--eval、--stdio から入力を取得

3. CoffeeScript.nodes() による構文木生成
   └─ 字句解析 → パース → ノード生成

4. 出力処理
   └─ nodes.toString() で文字列化
   └─ .trim() で末尾空白除去
   └─ printLine で標準出力に表示
```

### フローチャート

```mermaid
flowchart TD
    A[開始: coffee -n source.coffee] --> B[引数パース]
    B --> C{--nodes 指定?}
    C -->|No| D[通常処理へ]
    C -->|Yes| E[ソースコード取得]
    E --> F[CoffeeScript.nodes 呼び出し]
    F --> G[構文木オブジェクト取得]
    G --> H[.toString で文字列化]
    H --> I[.trim で末尾空白除去]
    I --> J[printLine: 標準出力へ]
    J --> K[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-24-01 | 末尾空白除去 | toString()の結果をtrim()で整形する | --nodes指定時 |
| BR-24-02 | 実行モード排他 | --nodes を指定するとコード実行は行われない | --nodes指定時 |
| BR-24-03 | インデント表現 | 構文木はインデントで階層構造を表現する | 出力時 |

### 計算ロジック

特になし

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| SyntaxError | 構文エラー | CoffeeScriptの文法エラー | エラーメッセージを標準エラー出力に表示して終了コード1 |
| ENOENT | ファイル不存在 | 指定されたファイルが存在しない | エラーメッセージを表示して終了コード1 |

### リトライ仕様

本機能はリトライ処理を行わない。

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

本機能はトランザクション処理を使用しない。

## パフォーマンス要件

特になし

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

- 特になし

## 備考

- `--ast` オプションとは異なり、CoffeeScript内部の構文木形式で出力される
- `--ast` はBabel互換のJSON形式、`--nodes` は人間が読みやすいインデント形式

---

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

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

### 推奨読解順序

#### Step 1: オプション定義を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | command.coffee | `src/command.coffee` | SWITCHESの `--nodes` 定義（45行目）を確認 |

**読解のコツ**: `['-n', '--nodes', 'print out the parse tree that the parser produces']` の形式で定義されている。

#### Step 2: ノード出力処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | command.coffee | `src/command.coffee` | compileScript関数内のnodes処理（209-210行目） |

**主要処理フロー**:
- **209行目**: `else if opts.nodes` の条件分岐
- **210行目**: `printLine CoffeeScript.nodes(task.input, task.options).toString().trim()`

#### Step 3: nodes関数の実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | coffeescript.coffee | `src/coffeescript.coffee` | nodes関数（189-191行目） |

**主要処理フロー**:
- **189行目**: `exports.nodes = withPrettyErrors (source, options) ->`
- **190行目**: `source = lexer.tokenize source, options if typeof source is 'string'`
- **191行目**: `parser.parse source`

#### Step 4: ノードのtoStringメソッドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | nodes.coffee | `src/nodes.coffee` | Baseクラスのtostring実装 |

**読解のコツ**: 各ノードクラスはBaseクラスを継承し、toString()メソッドで自身とchildren()の内容を再帰的に文字列化する。

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

```
exports.run (72行目)
    │
    └─ compileScript (202行目)
           │
           └─ [opts.nodes 分岐] (209行目)
                  │
                  └─ CoffeeScript.nodes (210行目)
                         │
                         ├─ lexer.tokenize
                         │      └─ トークン列生成
                         │
                         └─ parser.parse
                                └─ 構文木（Nodes）生成
                                       │
                                       └─ .toString()
                                              └─ ツリー形式文字列化
```

### データフロー図

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

CoffeeScriptソース ───▶ compileScript (202行目)
                              │
                              ▼
                        CoffeeScript.nodes (189行目)
                              │
                              ├─ lexer.tokenize (190行目)
                              │
                              └─ parser.parse (191行目)
                                      │
                                      ▼
                              構文木オブジェクト
                                      │
                                      ▼
                              .toString().trim() (210行目)
                                      │
                                      ▼
                              printLine ───▶ 標準出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| command.coffee | `src/command.coffee` | ソース | CLIメイン処理、--nodes分岐処理 |
| coffeescript.coffee | `src/coffeescript.coffee` | ソース | nodes関数の実装 |
| nodes.coffee | `src/nodes.coffee` | ソース | 構文木ノードクラス、toString実装 |
| lexer.coffee | `src/lexer.coffee` | ソース | 字句解析器 |
| parser.js | `lib/coffeescript/parser.js` | 生成ファイル | Jisonパーサー |
| optparse.coffee | `src/optparse.coffee` | ソース | コマンドライン引数パーサー |
