# 通知設計書 27-unexpected token

## 概要

本ドキュメントは、CoffeeScriptコンパイラにおける予期しないトークンエラー（unexpected token）の通知仕様を記述する。

### 本通知の処理概要

本通知は、CoffeeScriptソースコードにおいて、構文的に予期しないトークンが検出された場合に発生するエラーメッセージである。

**業務上の目的・背景**：CoffeeScriptコンパイラは、ソースコードを解析する際にトークン列を生成し、文法規則に従って構文木を構築する。この過程で、文法規則に合致しないトークンが出現した場合、「unexpected token」エラーを発生させる。このエラーは、文法エラーの最も一般的な形式であり、開発者に構文上の問題箇所を特定させるために重要な役割を果たす。

**通知の送信タイミング**：コンパイル時、パーサーがトークン列を解析する際、または特定のコンテキストで不正なトークンが検出された際に発生する。複数の箇所でこのエラーが生成される可能性がある。

**通知の受信者**：CoffeeScriptコンパイラを実行している開発者。コンソール出力またはエラーオブジェクトとして通知される。

**通知内容の概要**：エラーメッセージ「unexpected {tokenType}」とともに、予期しないトークンの位置情報と内容が提供される。

**期待されるアクション**：開発者は、エラー箇所の構文を確認し、正しいCoffeeScript構文に修正する必要がある。

## 通知種別

コンソールエラー出力 / SyntaxError例外

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（コンパイル処理中に即時発生） |
| 優先度 | 高（コンパイルエラー） |
| リトライ | なし（即時エラー終了） |

### 送信先決定ロジック

コンパイラを実行しているプロセスの標準エラー出力、またはAPIとして呼び出された場合はSyntaxError例外として呼び出し元に返される。

## 通知テンプレート

### コンソール出力の場合

| 項目 | 内容 |
|-----|------|
| 出力先 | stderr |
| 形式 | テキスト |

### 本文テンプレート

```
[ファイル名]:[行番号]:[列番号]: error: unexpected {tokenType}
[該当行のソースコード]
[エラー位置を示すキャレット]
```

### 添付ファイル

なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| filename | ソースファイル名 | コンパイルオプション | Yes |
| tokenType | トークンタイプまたは値 | エラー発生箇所による | Yes |
| line | エラー発生行番号 | トークン位置情報 | Yes |
| column | エラー発生列番号 | トークン位置情報 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| パーサー処理 | トークン解析 | 文法規則に合致しないトークン | パーサーが予期しないトークンを検出 |
| ノード処理 | オブジェクトリテラル解析 | 不正な演算子トークン | オブジェクトリテラル内で不正な演算子 |
| ノード処理 | パラメータ解析 | 不正なパラメータトークン | 関数パラメータで不正なトークン |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 正常なトークン | 文法規則に合致するトークンの場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[トークン解析開始] --> B{文法規則チェック}
    B -->|合致| C[次のトークンへ]
    B -->|不合致| D[予期しないトークン検出]
    D --> E[エラーメッセージ生成]
    E --> F[throwSyntaxError呼び出し]
    F --> G[SyntaxError生成]
    G --> H[エラーメッセージ出力]
    H --> I[コンパイル中断]
    C --> J{終了?}
    J -->|No| B
    J -->|Yes| K[処理完了]
```

## データベース参照・更新仕様

### 参照テーブル一覧

該当なし（ファイルベースのコンパイル処理）

### 更新テーブル一覧

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| SyntaxError | 文法規則に合致しないトークン | 構文を確認し修正 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（リトライなし） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 制限 | なし（コンパイル時エラー） |

### 配信時間帯

制限なし（コンパイル実行時に即時通知）

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

- エラーメッセージにはトークン値が含まれる可能性がある
- ソースコードの断片がログに残る可能性がある

## 備考

- このエラーは複数の箇所で生成される汎用的なエラータイプ
- 主な発生箇所：
  1. `coffeescript.coffee` - パーサーエラー時
  2. `nodes.coffee` - オブジェクトリテラルの演算子エラー
  3. `nodes.coffee` - パラメータの演算子エラー
- トークンタイプの表示は、制御文字の場合は名前に変換される

---

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

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

### 推奨読解順序

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

トークン構造とエラー情報を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | coffeescript.coffee | `src/coffeescript.coffee` | parser.yy.parseError関数 |

**読解のコツ**: パーサーエラーは、Jisonパーサーから呼び出されるparseError関数で処理される。

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

パーサーエラー処理のエントリーポイントを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | coffeescript.coffee | `src/coffeescript.coffee` | 245-251行目 - parseError処理 |

**主要処理フロー**:
1. **245行目**: エラーテキストの加工（制御文字の名前変換）
2. **251行目**: `throwSyntaxError "unexpected #{errorText}", errorLoc`

#### Step 3: ノードレベルのエラーを理解する

ノード処理中のunexpectedエラーを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | nodes.coffee | `src/nodes.coffee` | 2534行目 - オブジェクトリテラルの演算子エラー |
| 3-2 | nodes.coffee | `src/nodes.coffee` | 2588行目 - 追加の演算子エラー |
| 3-3 | nodes.coffee | `src/nodes.coffee` | 4344行目 - パラメータの演算子エラー |

**主要処理フロー**:
- **2534行目**: `prop.operatorToken.error "unexpected #{prop.operatorToken.value}"`
- **4344行目**: `token.error "unexpected #{token.value}"`

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

```
CoffeeScript.compile()
    │
    ├─ Parser.parse()
    │      └─ parseError()
    │             └─ throwSyntaxError("unexpected #{errorText}")
    │
    └─ nodes.compile()
           ├─ Obj.compileNode()
           │      └─ prop.operatorToken.error("unexpected ...")
           │
           └─ Param.compileToFragments()
                  └─ token.error("unexpected ...")
```

### データフロー図

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

x = { : value }       Parser.parse()               エラーメッセージ
       │                    │                      "unexpected :"
       ▼                    ▼
トークン列:          文法規則チェック
  IDENTIFIER x       予期しないトークン検出
  CALL_START =             │
  { ...                    ▼
  : (コロン)        parseError({...})
                           │
                           ▼
                    throwSyntaxError(
                      "unexpected :",
                      errorLoc
                    )
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| coffeescript.coffee | `src/coffeescript.coffee` | ソース | パーサーエラー処理 |
| nodes.coffee | `src/nodes.coffee` | ソース | ノードレベルのエラー処理 |
| helpers.coffee | `src/helpers.coffee` | ソース | throwSyntaxError、nameWhitespaceCharacter関数 |
| parser.js | `lib/coffeescript/parser.js` | 生成JS | Jisonパーサー（parseError呼び出し） |
