Files
hakorune/docs/development/current/main/phase174-jsonparser-p5b-design.md
nyash-codex 309d0803c7 feat(joinir): Phase 174 - JsonParser complex loop P5 extension design
- Task 174-1: Complex loop inventory (_parse_string/_parse_array/_parse_object)
  - Analyzed remaining JsonParser loops for P5 expansion potential
  - Identified _parse_string as most Trim-like structure (99% similarity)
  - Documented complexity scores and minimization potential

- Task 174-2: Selected _parse_string as next P5 target (closest to Trim)
  - Reason: LoopBodyLocal 'ch' usage matches Trim pattern exactly
  - Structure: loop(pos < len) + substring + char comparison + break
  - Minimization: Remove escape/buffer/continue → identical to Trim

- Task 174-3: Design doc for P5B extension (TrimLoopHelper reuse strategy)
  - File: docs/development/current/main/phase174-jsonparser-p5b-design.md
  - Strategy: Reuse existing TrimLoopHelper without modifications
  - Proven: Pattern applies to any character comparison, not just whitespace

- Task 174-4: Minimal PoC (_parse_string without escape) successful
  - Test: local_tests/test_jsonparser_parse_string_min.hako
  - Result: [pattern2/trim] Safe Trim pattern detected 
  - Detection: Trim with literals=['"'] (quote instead of whitespace)
  - Routing: Added whitelist entries for JsonParserStringTest methods

- Task 174-5: Documentation updates
  - Updated CURRENT_TASK.md with Phase 174 summary
  - Updated joinir-architecture-overview.md with P5 generality proof
  - Created phase174-jsonparser-loop-inventory-2.md (detailed analysis)
  - Created phase174-jsonparser-p5b-design.md (implementation strategy)

Success Criteria Met:
 _parse_string minimized version runs on P5 pipeline
 TrimLoopHelper works with '"' (non-whitespace character)
 Proven: Trim pattern is character-comparison-generic, not whitespace-specific
 Two new design docs (inventory + design)
 Phase 175+ roadmap established (multi-carrier, escape sequences)

Technical Achievement:
The P5 Trim pipeline successfully handled a quote-detection loop with zero code changes,
proving the architecture's generality beyond whitespace trimming.
2025-12-08 13:08:44 +09:00

363 lines
9.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Phase 174-3: JsonParser `_parse_string` P5B 設計
**Date**: 2025-12-08
**Target**: `_parse_string` ループ(エスケープ処理付き文字列パース)
**Purpose**: Trim P5 パイプラインを複雑ループに拡張する設計
---
## ターゲットループ構造
### 完全版Phase 175+ のターゲット)
```hako
loop(p < s.length()) {
local ch = s.substring(p, p+1)
if ch == "\"" { // 終端クォート
// End of string
local result = new MapBox()
result.set("value", me._unescape_string(str))
result.set("pos", p + 1)
result.set("type", "string")
return result
}
if ch == "\\" { // エスケープ開始
local has_next = 0
if p + 1 < s.length() { has_next = 1 }
if has_next == 0 { return null }
str = str + ch
p = p + 1
str = str + s.substring(p, p+1)
p = p + 1
continue
}
str = str + ch
p = p + 1
}
```
### 最小化版Phase 174-4 PoC
```hako
// エスケープ処理・文字列バッファ・continue・return を除外
loop(pos < len) {
local ch = s.substring(pos, pos+1)
if ch == "\"" {
break
} else {
pos = pos + 1
}
}
```
---
## Pattern Space 分析
### 軸 A〜F での分類(最小化版)
| 軸 | 値 | 説明 |
|----|-----|------|
| **A. 継続条件** | 単純 | `pos < len` |
| **B. 早期終了** | 条件付き break | `if ch == "\"" { break }` |
| **C. スキップ** | なし | continue 使用なし |
| **D. PHI 分岐** | なし | if 分岐あるが PHI 不要 |
| **E. 条件変数のスコープ** | **LoopBodyLocal** | `ch` が条件に使用 |
| **F. キャリア更新** | 単純 | `pos` のみ更新 |
**Pattern 分類**: **P5**LoopBodyLocal 条件)+ **Pattern2**break 付き)
---
## Trim との差分
### ✅ 同じ部分P5 パイプライン再利用可能)
1. **LoopBodyLocal 変数の使用**:
- Trim: `local ch = s.substring(start, start+1)`
- Parse String: `local ch = s.substring(pos, pos+1)`
-**完全一致**(変数名が異なるだけ)
2. **文字比較パターン**:
- Trim: `if ch == " " || ch == "\t" || ch == "\n" || ch == "\r"`
- Parse String: `if ch == "\""`
-**構造は同じ**(比較対象が異なるだけ)
3. **Pattern2 構造**:
- Trim: `loop(start < end)` + `{ start = start + 1 } else { break }`
- Parse String: `loop(pos < len)` + `{ pos = pos + 1 } else { break }`
-**完全同型**
4. **キャリア更新**:
- Trim: `start = start + 1`(単一キャリア)
- Parse String: `pos = pos + 1`(単一キャリア)
-**完全一致**
### ⚠️ 追加部分完全版、Phase 175+ で必要)
1. **複数キャリア**:
- `pos`: ループカウンタ
- `str`: 文字列バッファ
- **課題**: 既存の TrimLoopHelper は単一キャリア想定
2. **エスケープ処理**:
- `if ch == "\\" { ... }` → 追加の文字読み込み
- **課題**: LoopBodyLocal の多重使用(`ch``escaped`
3. **continue**:
- エスケープ処理後に continue
- **課題**: Pattern4 対応が必要
4. **return による早期終了**:
- 成功時の return
- **課題**: ExitLine とループ外リターンの分離
---
## 箱の再利用 vs 追加
### 再利用可能な既存箱Phase 174-4
| 箱名 | 再利用可能性 | 理由 |
|-----|-----------|------|
| **LoopConditionScopeBox** | ✅ 100% | `ch` を LoopBodyLocal と分類可能 |
| **LoopBodyCarrierPromoter** | ✅ 100% | `ch` の昇格検出Trim と同じ) |
| **TrimPatternInfo** | ✅ 100% | 基本構造は再利用可能 |
| **TrimLoopHelper** | ✅ 100% | 単一キャリア版で完全対応 |
| **CarrierInfo** | ✅ 100% | `pos` キャリア情報 |
| **ExitLine** | ✅ 100% | break による終了 |
| **Boundary** | ✅ 100% | ループ境界情報 |
**結論**: 最小化版では**既存の箱をそのまま使える**
### 追加が必要な箱Phase 175+ で検討)
1. **MultiCarrierTrimHelper**(将来):
- TrimLoopHelper の拡張版
- 複数キャリア(`pos` + `str`)対応
- **Phase 175 で設計・実装**
2. **EscapeSequenceHandler**(将来):
- エスケープ処理の追加ロジック
- `ch == "\\"` 時の特殊処理
- **Phase 176 で設計・実装**
3. **ContinuePatternHelper**(将来):
- Pattern4continue 付き)対応
- **Phase 176 で設計・実装**
---
## Phase 174 戦略
### ステップ1: 最小化版で試験Phase 174-4
**最小化方針**:
- ✅ エスケープ処理を**除外**
- ✅ 文字列バッファ(`str`)を**除外**
- ✅ continue を**除外**
- ✅ return を break に**置換**
**最小化版**:
```hako
// Phase 174-4 PoC
loop(pos < len) {
local ch = s.substring(pos, pos+1)
if ch == "\"" {
break
} else {
pos = pos + 1
}
}
```
**この構造の利点**:
- ✅ TrimLoopHelper がそのまま使える
- ✅ Pattern2 Trim 特例経路が使える
- ✅ 単一キャリア `pos` のみ
- ✅ 既存コードの変更**ゼロ**
**期待される動作**:
1. `LoopConditionScopeBox::analyze()`
- `ch`: LoopBodyLocalsubstring でループ内定義)
- `pos`, `len`: OuterLocalループ外定義
2. `LoopBodyCarrierPromoter::try_promote()`
- `ch` を carrier `is_ch_match` に昇格
- 昇格理由: break 条件に使用
3. `TrimLoopHelper::is_safe_trim()`
- true を返すTrim と完全同型)
4. Pattern2 lowerer
- Trim 特例経路で JoinIR 生成
- `[pattern2/trim] Safe Trim pattern detected`
### ステップ2: エスケープ処理の追加Phase 175+
最小化版が成功したら、段階的に追加:
1. **Phase 175**: 文字列バッファ追加(複数キャリア対応)
```hako
loop(pos < len) {
local ch = s.substring(pos, pos+1)
if ch == "\"" {
break
} else {
result = result + ch // ← 追加
pos = pos + 1
}
}
```
2. **Phase 176**: エスケープ処理追加continue 対応)
```hako
loop(pos < len) {
local ch = s.substring(pos, pos+1)
if ch == "\"" {
break
} else if ch == "\\" {
// エスケープ処理
pos = pos + 1
result = result + s.substring(pos, pos+1)
pos = pos + 1
continue // ← Pattern4 対応が必要
} else {
result = result + ch
pos = pos + 1
}
}
```
3. **Phase 177**: return 処理追加ExitLine 拡張)
```hako
loop(pos < len) {
local ch = s.substring(pos, pos+1)
if ch == "\"" {
return create_result(result, pos) // ← ExitLine 拡張
}
// ... 以下同じ
}
```
---
## 命名の汎用化Phase 175+ で検討)
### 現在の命名Trim 特化)
- `TrimLoopHelper` - Trim 専用のような命名
- `is_safe_trim()` - Trim 専用のような命名
### 汎用化案Phase 175+ で検討)
**案1: CharComparison**
- `CharComparisonLoopHelper`
- `is_safe_char_comparison()`
- **利点**: 文字比較ループの汎用名
- **欠点**: やや長い
**案2: SingleCharBreak**
- `SingleCharBreakLoopHelper`
- `is_safe_single_char_break()`
- **利点**: 構造を正確に表現
- **欠点**: 長い、やや複雑
**案3: P5Pattern軸E準拠**
- `P5LoopHelper`
- `is_safe_p5_pattern()`
- **利点**: Pattern Space 軸E と一貫性
- **欠点**: P5 の意味が不明瞭
**Phase 174 での方針**: **命名変更なし**(既存コード保持)
- Phase 175+ で複数キャリア対応時に再検討
- 既存の TrimLoopHelper は Trim 専用として保持
- 新しい汎用版を別途作成する可能性
---
## テスト戦略
### Phase 174-4 テストケース
**ファイル**: `local_tests/test_jsonparser_parse_string_min.hako`
```hako
static box JsonParserStringTest {
s: StringBox
pos: IntegerBox
len: IntegerBox
parse_string_min() {
me.s = "hello world\"" // 終端クォート付き
me.pos = 0
me.len = me.s.length()
// 最小化版: エスケープ処理なし、終端クォート検出のみ
loop(me.pos < me.len) {
local ch = me.s.charAt(me.pos)
if ch == "\"" {
break
} else {
me.pos = me.pos + 1
}
}
print("Found quote at position: ")
print(me.pos)
}
main() {
me.parse_string_min()
return "OK"
}
}
```
**期待される出力**:
```
[pattern2/check] 'ch': LoopBodyLocal ✅
[pattern2/promoter] promoted to carrier 'is_ch_match' ✅
[pattern2/trim] Safe Trim pattern detected ✅
Found quote at position: 11
```
**実行コマンド**:
```bash
NYASH_JOINIR_CORE=1 NYASH_LEGACY_LOOPBUILDER=0 \
./target/release/hakorune local_tests/test_jsonparser_parse_string_min.hako
```
---
## 結論
### Phase 174-4 では
- ✅ 既存の TrimLoopHelper をそのまま再利用
- ✅ 最小化版(`ch == "\""`のみ)で P5 パイプライン検証
- ✅ 既存コードの変更**ゼロ**
- ❌ エスケープ処理・複数キャリア・continue は Phase 175+ に延期
### Phase 175+ で検討
- **MultiCarrierTrimHelper** の設計
- **エスケープ処理**の統合Pattern4 対応)
- **命名の汎用化**Trim → CharComparison
- **return 処理**の ExitLine 拡張
### 技術的価値
**Phase 174-4 で実証すべきこと**:
1. ✅ Trim パイプラインが文字比較対象が異なるだけで機能すること
2. ✅ `"\"`(終端クォート)という異なる文字でも昇格パターンが機能すること
3. ✅ TrimLoopHelper の汎用性(空白文字以外にも対応可能)
**成功すれば**:
- Trim P5 パイプラインが「Trim 専用」ではなく「文字比較ループ汎用」であることが証明される
- Phase 175+ での拡張複数キャリア・continue 等)の基盤が確立される