# 機能設計書 25 --tokens オプション

## 概要

本ドキュメントは、CoffeeScript CLIツールの `--tokens` オプションの機能設計を記述する。このオプションは、レキサー（字句解析器）とリライターが生成するトークン列を人間が読める形式で出力する機能を提供する。

### 本機能の処理概要

`--tokens` オプションは、CoffeeScriptソースコードの字句解析結果をトークン列として表示する機能を提供する。各トークンはタグ（種別）と値のペアとして出力され、コンパイラがソースコードをどのように分解しているかを確認できる。

**業務上の目的・背景**：CoffeeScriptコンパイラの字句解析フェーズを理解したり、予期しない解析結果の原因を特定したりする際に、生成されるトークン列を確認することが有用である。`--tokens` オプションにより、ソースコードがどのようなトークンに分解されているかを可視化でき、レキサーの動作理解やデバッグに役立つ。

**機能の利用シーン**：
- 字句解析の結果を確認したい場合
- トークン化のルールを学習・理解したい場合
- CoffeeScriptコンパイラの開発・デバッグを行う場合
- 識別子、文字列、演算子などのトークン種別を確認したい場合

**主要な処理内容**：
1. CoffeeScriptソースコードをCoffeeScript.tokens()で字句解析
2. リライターによるトークン正規化（暗黙の括弧追加など）を実行
3. printTokens関数でトークン列を整形して出力
4. 各トークンは `[TAG value]` 形式で表示

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

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

## 関連画面

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

## 機能種別

デバッグ出力 / 字句解析結果表示

## 入力仕様

### 入力パラメータ

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

### 入力データソース

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

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| token list | string | トークン列の文字列表現（`[TAG value]` 形式の空白区切り） |

### 出力先

- 標準出力（process.stdout）

## 処理フロー

### 処理シーケンス

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

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

3. CoffeeScript.tokens() によるトークン生成
   └─ 字句解析 → リライター処理 → トークン列

4. printTokens関数による整形出力
   └─ 各トークンを [TAG value] 形式に変換
   └─ 改行文字を \\n にエスケープ
   └─ 空白区切りで結合して出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始: coffee --tokens source.coffee] --> B[引数パース]
    B --> C{--tokens 指定?}
    C -->|No| D[通常処理へ]
    C -->|Yes| E[ソースコード取得]
    E --> F[CoffeeScript.tokens 呼び出し]
    F --> G[トークン配列取得]
    G --> H[printTokens関数]
    H --> I{各トークンに対して}
    I --> J[tag = token#91;0#93;]
    J --> K[value = token#91;1#93;.toString]
    K --> L[改行を \\n にエスケープ]
    L --> M[#91;TAG value#93; 形式に整形]
    M --> N[空白で結合]
    N --> O[printLine: 標準出力へ]
    O --> P[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-25-01 | 改行エスケープ | トークン値内の改行文字は `\\n` にエスケープされる | トークン出力時 |
| BR-25-02 | 実行モード排他 | --tokens を指定するとコード実行は行われない | --tokens指定時 |
| BR-25-03 | 位置情報除外 | トークンの位置情報（行番号・列番号）は出力されない | トークン出力時 |
| BR-25-04 | 空白区切り | 各トークンは空白で区切られて1行に出力される | トークン出力時 |

### 計算ロジック

特になし

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

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

## エラー処理

### エラーケース一覧

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

### リトライ仕様

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

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

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

## パフォーマンス要件

特になし

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

- 特になし

## 備考

- トークンには位置情報（token[2]）も含まれているが、出力には含まれない
- リライター処理後のトークン列が出力されるため、暗黙の括弧なども含まれる
- トークンタグ例: IDENTIFIER, NUMBER, STRING, CALL_START, CALL_END, など

---

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

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

### 推奨読解順序

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

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

**読解のコツ**: `['--tokens', 'print out the tokens that the lexer/rewriter produce']` の形式で定義されている（短縮形なし）。

#### Step 2: トークン出力処理を理解する

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

**主要処理フロー**:
- **207行目**: `if opts.tokens` の条件分岐
- **208行目**: `printTokens CoffeeScript.tokens task.input, task.options`

#### Step 3: printTokens関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | command.coffee | `src/command.coffee` | printTokens関数（436-441行目） |

**主要処理フロー**:
- **436行目**: `printTokens = (tokens) ->`
- **437-440行目**: トークンをループして `[TAG value]` 形式に変換
- **441行目**: `printLine strings.join(' ')` で出力

#### Step 4: tokens関数の実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | coffeescript.coffee | `src/coffeescript.coffee` | tokens関数（183-184行目） |

**主要処理フロー**:
- **183行目**: `exports.tokens = withPrettyErrors (code, options) ->`
- **184行目**: `lexer.tokenize code, options`

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

```
exports.run (72行目)
    │
    └─ compileScript (202行目)
           │
           └─ [opts.tokens 分岐] (207行目)
                  │
                  └─ printTokens (436行目)
                         │
                         └─ CoffeeScript.tokens (208行目)
                                │
                                └─ lexer.tokenize (184行目)
                                       │
                                       ├─ Lexer.tokenize
                                       │      └─ 字句解析
                                       │
                                       └─ Rewriter.rewrite
                                              └─ トークン正規化
```

### データフロー図

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

CoffeeScriptソース ───▶ compileScript (202行目)
                              │
                              ▼
                        CoffeeScript.tokens (183行目)
                              │
                              ├─ lexer.tokenize (184行目)
                              │
                              └─ rewriter.rewrite
                                      │
                                      ▼
                              トークン配列
                                      │
                                      ▼
                        printTokens (436行目)
                              │
                              ├─ token[0] → TAG
                              └─ token[1].toString() → value
                                      │
                                      ▼
                        printLine ───▶ 標準出力
                        [TAG value] [TAG value] ...
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| command.coffee | `src/command.coffee` | ソース | CLIメイン処理、printTokens関数、--tokens分岐処理 |
| coffeescript.coffee | `src/coffeescript.coffee` | ソース | tokens関数の実装 |
| lexer.coffee | `src/lexer.coffee` | ソース | 字句解析器Lexerクラス |
| rewriter.coffee | `src/rewriter.coffee` | ソース | トークン正規化処理 |
| optparse.coffee | `src/optparse.coffee` | ソース | コマンドライン引数パーサー |
