# 通知設計書 16-LinkerScriptParseError

## 概要

本ドキュメントは、Zigコンパイラにおける「LinkerScriptParseError」通知の設計仕様を定義する。LinkerScriptParseErrorは、リンカースクリプトの解析に失敗した場合に発生する致命的エラーである。

### 本通知の処理概要

LinkerScriptParseErrorは、GNU/ELF形式のリンカースクリプト（LDスクリプト）を解析する際に、構文エラーや不正なトークンが検出された場合に発生する致命的エラーである。

**業務上の目的・背景**：リンカースクリプトは、実行ファイルのメモリレイアウトやセクション配置を制御するために使用される。ZigコンパイラはGNU LDスクリプトの限定的なサブセットをサポートしており、これにより既存のシステムライブラリ（libcなど）のリンカースクリプトを処理できる。構文エラーを早期に検出し、問題の位置と内容を明確に報告することで、開発者がスクリプトを修正できるようにする。

**通知の送信タイミング**：リンク処理時、リンカースクリプトファイルの読み込みと解析フェーズで発生する。`LdScript.parse`関数内でトークン化と構文解析を行う際に検出される。

**通知の受信者**：コンパイラを実行している開発者、CI/CDシステム、またはビルドスクリプトがエラーメッセージの受信者となる。

**通知内容の概要**：エラーの種類（不正なトークン、予期しないトークン等）、エラー発生位置（行番号、列番号）、問題のトークン内容、およびリンカースクリプトファイルのパスが含まれる。

**期待されるアクション**：開発者は、エラーメッセージに示された位置のリンカースクリプトを確認し、構文エラーを修正する必要がある。また、Zigがサポートしていない高度なLD機能を使用している場合は、スクリプトを簡略化する必要がある。

## 通知種別

致命的エラー / リンクエラー

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（エラー発生時即時） |
| 優先度 | 高（致命的エラー） |
| リトライ | なし |

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

エラーは`link.Diags.failParse`関数を通じて報告される。エラーメッセージにはスクリプトファイルのパスが注記として追加される。

## 通知テンプレート

### エラーメッセージの場合

| 項目 | 内容 |
|-----|------|
| 出力先 | 標準エラー出力（stderr） |
| 形式 | エラーバンドル |

### 本文テンプレート

不正なトークンの場合:
```
error: invalid token in LD script: '{トークン内容}' ({行番号}:{列番号})
note: while parsing {スクリプトパス}
```

予期しないトークンの場合:
```
error: unexpected token in LD script: {トークン種別}: '{トークン内容}' ({行番号}:{列番号})
note: while parsing {スクリプトパス}
```

### 添付ファイル

なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| token_content | 問題のトークン内容 | Tokenizer | Yes |
| token_type | トークンの種別 | Token.Id | Yes |
| line | エラー発生行番号 | 解析位置 | Yes |
| column | エラー発生列番号 | 解析位置 | Yes |
| script_path | スクリプトファイルパス | Path | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| トークン化 | 不正文字検出 | 無効なトークン | invalid tokenエラー |
| 構文解析 | 予期しないトークン | 構文規則違反 | unexpected tokenエラー |
| 構文解析 | 未知のCPUアーキテクチャ | OUTPUT_FORMAT解析 | UnknownCpuArchエラー |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 正常なスクリプト | エラーは発生しない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[リンカースクリプト読み込み] --> B[トークン化]
    B --> C{トークン有効?}
    C -->|無効| D[invalid tokenエラー]
    C -->|有効| E[構文解析]
    E --> F{構文正常?}
    F -->|異常| G[unexpected tokenエラー]
    F -->|正常| H{OUTPUT_FORMAT?}
    H -->|あり| I{アーキテクチャ認識?}
    I -->|未知| J[UnknownCpuArchエラー]
    I -->|既知| K[解析継続]
    H -->|なし| K
    D --> L[Diags.failParse]
    G --> L
    J --> L
    L --> M[LinkFailure返却]
    M --> N[エラーバンドル生成]
    K --> O[LdScript返却]
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| LdScript.Command | サポートコマンド | OUTPUT_FORMAT, INPUT, GROUP, AS_NEEDED |
| LdScript.Token | トークン種別 | 字句解析用 |

### テーブル別参照項目詳細

#### LdScript.Command

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| output_format | 出力形式指定 | OUTPUT_FORMAT解析時 |
| input | 入力ファイル指定 | INPUT解析時 |
| group | グループ指定 | GROUP解析時 |
| as_needed | 条件付きリンク | AS_NEEDED解析時 |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| link.Diags.msgs | INSERT | パースエラー追加 |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| invalid token | 不正な文字・構文 | スクリプト構文修正 |
| unexpected token | 予期しないトークン位置 | 構文順序修正 |
| UnknownCpuArch | 未サポートのOUTPUT_FORMAT | サポート形式に変更 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | なし |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | なし |
| 1日あたり上限 | なし |

### 配信時間帯

制限なし

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

- スクリプトパスにはシステム構造情報が含まれる
- スクリプト内容の一部（トークン）がエラーメッセージに含まれる

## 備考

- ZigはGNU LDスクリプトの限定的なサブセットのみをサポート
- サポートするOUTPUT_FORMAT: elf64-x86-64, elf64-littleaarch64
- コメント（/* */）と改行は解析時にスキップされる

---

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

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

### 推奨読解順序

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

LdScriptパーサーの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | LdScript.zig | `src/link/LdScript.zig` | 1-19行目: LdScript構造体とError定義 |
| 1-2 | LdScript.zig | `src/link/LdScript.zig` | 93-112行目: Command列挙型 |

**読解のコツ**: `Error`はLinkFailure, UnknownCpuArch, OutOfMemoryの3種類。Commandは4つのLDスクリプトコマンドをサポート。

#### Step 2: パース処理を理解する

parse関数の実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | LdScript.zig | `src/link/LdScript.zig` | 21-86行目: parse関数の実装 |

**主要処理フロー**:
1. **28行目**: Tokenizerでトークン化開始
2. **42-47行目**: invalid token検出時のエラー報告
3. **67-80行目**: unexpected token検出時のエラー報告

#### Step 3: エラー報告を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | link.zig | `src/link.zig` | 347-356行目: Diags.failParse関数 |

**主要処理フロー**:
- **347行目**: `failParse`関数定義
- **354行目**: パス情報をnoteとして追加

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

```
link.File.flush
    │
    └─ リンカースクリプト処理
           │
           └─ LdScript.parse
                  │
                  ├─ Tokenizer.next (字句解析)
                  │      └─ invalid token → Diags.failParse
                  │
                  └─ Parser.start (構文解析)
                         ├─ outputFormat
                         │      └─ UnknownCpuArch
                         ├─ group / input
                         │      └─ UnexpectedToken → Diags.failParse
                         └─ asNeeded
```

### データフロー図

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

LDスクリプト ───────▶ Tokenizer ───────▶ トークン列
                          │
                          ▼
                      Parser
                          │
                    ┌─────┴─────┐
                    ▼           ▼
               成功       パースエラー
                    │           │
                    ▼           ▼
            LdScript    Diags.failParse ───▶ エラーバンドル
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| LdScript.zig | `src/link/LdScript.zig` | ソース | リンカースクリプトパーサー |
| link.zig | `src/link.zig` | ソース | Diags.failParse関数、リンク制御 |
