# 機能設計書 35-parseutils

## 概要

本ドキュメントは、Nimプログラミング言語の低レベル解析ユーティリティモジュールである`parseutils`モジュールの機能設計を記載する。parseutilsモジュールはトークン、数値、識別子などの解析に使用するヘルパー関数を提供する。

### 本機能の処理概要

parseutilsモジュールは文字列から数値や識別子を抽出するための低レベルな解析関数を提供する。正規表現やパーサジェネレータを使用せずに、シンプルなテキスト解析を行う場合に有用。

**業務上の目的・背景**：テキストデータの解析は多くのアプリケーションで必要とされる。parseutilsモジュールは、設定ファイル、ログファイル、データファイルなどの解析に必要な基本的な解析プリミティブを提供する。他の高レベルパーサ（parsecsv, parsecfg, parseopt等）の基盤としても使用される。

**機能の利用シーン**：
- 設定ファイルの解析
- ログファイルからのデータ抽出
- コマンドライン引数の解析
- DSL（ドメイン特化言語）の実装
- カスタムフォーマットのデータ解析

**主要な処理内容**：
1. 2進数解析（parseBin）
2. 8進数解析（parseOct）
3. 16進数解析（parseHex）
4. 10進数整数解析（parseInt）
5. 浮動小数点数解析（parseFloat）
6. 識別子解析（parseIdent）
7. 文字解析（parseChar）
8. 空白スキップ（skipWhitespace）
9. トークンスキップ（skip, skipIgnoreCase, skipUntil, skipWhile）
10. トークン抽出（parseUntil, parseWhile, captureBetween）

**関連システム・外部連携**：strutilsモジュールと連携。strscansモジュールの基盤として使用。

**権限による制御**：権限による制御は存在しない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 画面には関連しない（ライブラリモジュール） |

## 機能種別

テキスト解析 / データ抽出 / 数値変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| s | openArray[char] | Yes | 解析対象の文字列 | なし |
| number | var T | No | 解析結果を格納する変数（数値型） | SomeInteger |
| token | var string | No | 解析結果を格納する変数（文字列型） | なし |
| maxLen | int | No | 最大解析文字数（0で無制限） | 0以上 |

### 入力データソース

プログラム内の文字列データ。ファイル、ネットワーク、ユーザー入力など。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 解析文字数 | int | 解析した文字数（0の場合はエラー） |
| number | T (参照) | 解析された数値 |
| token | string (参照) | 解析されたトークン |

### 出力先

戻り値として解析文字数を返す。結果は参照パラメータに格納。

## 処理フロー

### 処理シーケンス

```
1. 入力文字列の受け取り
   └─ 開始位置から解析を開始
2. プレフィックスの確認（数値解析の場合）
   └─ 0b, 0o, 0x, #などのプレフィックスをスキップ
3. 文字の走査
   └─ 有効な文字が続く限り処理
4. 結果の格納
   └─ 解析結果を参照パラメータに格納
5. 解析文字数の返却
   └─ 解析した文字数を返す（エラー時は0）
```

### フローチャート

```mermaid
flowchart TD
    A[入力文字列] --> B{解析タイプ}
    B -->|数値| C[プレフィックス確認]
    B -->|識別子| D[先頭文字確認]
    B -->|トークン| E[終端文字まで走査]
    C --> F[有効桁の解析]
    D --> G[識別子文字の走査]
    F --> H{解析成功?}
    G --> H
    E --> H
    H -->|Yes| I[結果格納・文字数返却]
    H -->|No| J[0を返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | プレフィックス処理 | 0b/0B, 0o/0O, 0x/0X, #をプレフィックスとして認識 | 数値解析 |
| BR-02 | アンダースコア無視 | 数値中の_は無視される | 数値解析 |
| BR-03 | オーバーフロー非検出 | オーバーフローはチェックされない | 数値解析 |
| BR-04 | 識別子文字 | [A-Za-z_][A-Za-z0-9_]* | parseIdent |

### 計算ロジック

数値解析のビットシフト:
- parseBin: `output = output shl 1 or T(ord(s[i]) - ord('0'))`
- parseOct: `output = output shl 3 or T(ord(s[i]) - ord('0'))`
- parseHex: `output = output shl 4 or T(value)`

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | データベース操作なし |

### テーブル別操作詳細

データベース操作は行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 0（戻り値） | 解析失敗 | 有効な文字が見つからない | 戻り値のチェック |

### リトライ仕様

リトライは不要。戻り値で成功・失敗を判定。

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

トランザクション管理は不要。

## パフォーマンス要件

- すべての関数は線形時間O(n)以下
- noSideEffectプラグマにより副作用なし
- インライン展開可能な関数が多い

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

- オーバーフローチェックは行われないため、信頼できない入力には注意
- 解析結果の範囲チェックは呼び出し側で行うこと

## 備考

parseutilsはstrscansモジュールのscanfマクロの基盤として使用される。より高レベルな解析にはstrscansの使用を推奨。

---

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

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

### 推奨読解順序

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

定数定義を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | parseutils.nim | `lib/pure/parseutils.nim` | 定数定義（54-58行目） |

**読解のコツ**: Whitespace, IdentChars, IdentStartCharsはstrutilsと同じ定義。

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

モジュール冒頭のドキュメントを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | parseutils.nim | `lib/pure/parseutils.nim` | モジュールドキュメント（10-45行目） |

**主要処理フロー**:
1. **10-11行目**: トークン、数値、識別子の解析ヘルパー
2. **38-45行目**: 関連モジュールへのリンク

#### Step 3: 数値解析を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | parseutils.nim | `lib/pure/parseutils.nim` | parseBin（63-109行目） |
| 3-2 | parseutils.nim | `lib/pure/parseutils.nim` | parseOct（111-157行目） |
| 3-3 | parseutils.nim | `lib/pure/parseutils.nim` | parseHex（159-212行目） |

**主要処理フロー**:
- **92-104行目**: parseBinのメインループ（ビットシフトによる値の構築）
- **96行目**: 0b/0Bプレフィックスのスキップ
- **99行目**: アンダースコアの無視
- **100-102行目**: 2進数字の処理

#### Step 4: 識別子・トークン解析を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | parseutils.nim | `lib/pure/parseutils.nim` | parseIdent（214-249行目） |
| 4-2 | parseutils.nim | `lib/pure/parseutils.nim` | parseChar（251-265行目） |

**主要処理フロー**:
- **226-231行目**: parseIdent - 識別子の解析
- **227行目**: 先頭文字の確認（IdentStartChars）
- **229行目**: 後続文字の確認（IdentChars）

#### Step 5: スキップ関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | parseutils.nim | `lib/pure/parseutils.nim` | skipWhitespace, skip（267-301行目） |
| 5-2 | parseutils.nim | `lib/pure/parseutils.nim` | skipUntil, skipWhile（303-334行目） |

**主要処理フロー**:
- **267-276行目**: skipWhitespace - 空白のスキップ
- **278-291行目**: skip - トークンのスキップ
- **303-312行目**: skipUntil - 指定文字までスキップ

#### Step 6: parseUntil関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 6-1 | parseutils.nim | `lib/pure/parseutils.nim` | parseUntil（340-399行目） |

**主要処理フロー**:
- **340-356行目**: parseUntil(set[char]) - 文字集合まで解析
- **358-374行目**: parseUntil(char) - 単一文字まで解析
- **376-399行目**: parseUntil(string) - 文字列まで解析

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

```
parseutils.nim (メインモジュール)
    │
    ├─ 数値解析
    │      ├─ parseBin (2進数)
    │      ├─ parseOct (8進数)
    │      ├─ parseHex (16進数)
    │      ├─ parseInt (10進数)
    │      └─ parseFloat (浮動小数点)
    │
    ├─ 識別子・文字解析
    │      ├─ parseIdent (識別子)
    │      └─ parseChar (単一文字)
    │
    ├─ スキップ関数
    │      ├─ skipWhitespace
    │      ├─ skip / skipIgnoreCase
    │      ├─ skipUntil
    │      └─ skipWhile
    │
    └─ トークン抽出
           ├─ parseUntil
           ├─ parseWhile
           └─ captureBetween
```

### データフロー図

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

"0x4E69ED"     ───▶  parseHex          ───▶  (8, number=5138925)
                      (プレフィックス+16進数解析)

"Hello World"  ───▶  parseIdent        ───▶  (5, ident="Hello")
                      (識別子文字の走査)

"  text"       ───▶  skipWhitespace    ───▶  2
                      (空白のスキップ)

"key=value"    ───▶  parseUntil('=')   ───▶  (3, token="key")
                      (終端文字まで解析)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| parseutils.nim | `lib/pure/parseutils.nim` | ソース | メインモジュール、解析プリミティブ |
| strscans.nim | `lib/pure/strscans.nim` | ソース | scanf/scanpマクロ（parseutilsを使用） |
| strutils.nim | `lib/pure/strutils.nim` | ソース | 文字列操作（一部関数を再利用） |
| inclrtl.nim | `lib/system/inclrtl.nim` | ソース | ランタイムライブラリ連携 |
