277 lines
11 KiB
Plaintext
277 lines
11 KiB
Plaintext
// 簡単なNyashスクリプトJSON解析の「ずれ」問題分析
|
||
// yyjsonが必要になった理由と最小限の解決要件
|
||
|
||
using "apps/lib/json_native/core/node.hako" as JsonNode
|
||
|
||
static box ParsingErrorAnalysis {
|
||
|
||
// ===== 典型的な「ずれ」パターンテスト =====
|
||
|
||
test_parsing_errors() {
|
||
print("🔍 JSON解析「ずれ」問題の分析開始")
|
||
|
||
// 1. エスケープ処理の問題
|
||
print("\n1️⃣ エスケープ処理の「ずれ」")
|
||
this.test_escape_issues()
|
||
|
||
// 2. ネスト構造の問題
|
||
print("\n2️⃣ ネスト構造の「ずれ」")
|
||
this.test_nesting_issues()
|
||
|
||
// 3. 数値解析の問題
|
||
print("\n3️⃣ 数値解析の「ずれ」")
|
||
this.test_number_issues()
|
||
|
||
// 4. 境界判定の問題
|
||
print("\n4️⃣ 境界判定の「ずれ」")
|
||
this.test_boundary_issues()
|
||
|
||
// 5. 空白処理の問題
|
||
print("\n5️⃣ 空白処理の「ずれ」")
|
||
this.test_whitespace_issues()
|
||
}
|
||
|
||
// エスケープ処理問題
|
||
test_escape_issues() {
|
||
local problematic_cases = new ArrayBox()
|
||
|
||
// ❌ 簡単なsubstring解析だと失敗するケース
|
||
problematic_cases.push("{\"message\": \"say \\\"hello\\\"\"}") // 内部クォート
|
||
problematic_cases.push("{\"path\": \"C:\\\\Users\\\\name\"}") // バックスラッシュ
|
||
problematic_cases.push("{\"newline\": \"line1\\nline2\"}") // 改行エスケープ
|
||
problematic_cases.push("{\"unicode\": \"\\u0041\\u0042\"}") // Unicode
|
||
|
||
local i = 0
|
||
loop(i < problematic_cases.length()) {
|
||
local json_text = problematic_cases.get(i)
|
||
print("Test case: " + json_text)
|
||
|
||
// 簡単な解析(ずれやすい)
|
||
local simple_result = this.simple_parse(json_text)
|
||
print("Simple parse: " + simple_result)
|
||
|
||
// Nyash Native解析
|
||
local native_result = JsonNode.parse(json_text)
|
||
print("Native parse: " + native_result.stringify())
|
||
|
||
print("---")
|
||
i = i + 1
|
||
}
|
||
}
|
||
|
||
// ネスト構造問題
|
||
test_nesting_issues() {
|
||
local complex_cases = new ArrayBox()
|
||
|
||
// ❌ ネスト深度で混乱するケース
|
||
complex_cases.push("{\"a\": {\"b\": {\"c\": \"deep\"}}}") // 深いネスト
|
||
complex_cases.push("{\"arr\": [{\"x\": 1}, {\"y\": 2}]}") // 配列内オブジェクト
|
||
complex_cases.push("[{\"type\": \"A\"}, {\"type\": \"B\"}]") // オブジェクト配列
|
||
complex_cases.push("{\"mixed\": [1, \"str\", {\"nested\": true}]}") // 混合配列
|
||
|
||
local i = 0
|
||
loop(i < complex_cases.length()) {
|
||
local json_text = complex_cases.get(i)
|
||
print("Complex case: " + json_text)
|
||
|
||
// 簡単な解析の限界
|
||
local bracket_count = this.count_brackets(json_text)
|
||
print("Bracket analysis: " + bracket_count.open + " open, " + bracket_count.close + " close")
|
||
|
||
// TODO: 本格的なパーサーで正確に解析
|
||
print("✅ Requires proper parser for accuracy")
|
||
print("---")
|
||
i = i + 1
|
||
}
|
||
}
|
||
|
||
// 数値解析問題
|
||
test_number_issues() {
|
||
local number_cases = new ArrayBox()
|
||
|
||
// ❌ 数値の種類で混乱するケース
|
||
number_cases.push("{\"int\": 42}") // 整数
|
||
number_cases.push("{\"negative\": -123}") // 負数
|
||
number_cases.push("{\"float\": 3.14159}") // 小数
|
||
number_cases.push("{\"scientific\": 1.23e-4}") // 指数表記
|
||
number_cases.push("{\"zero\": 0}") // ゼロ
|
||
number_cases.push("{\"big\": 9223372036854775807}") // 大きな数
|
||
|
||
local i = 0
|
||
loop(i < number_cases.length()) {
|
||
local json_text = number_cases.get(i)
|
||
print("Number case: " + json_text)
|
||
|
||
// 現在のNyash Nativeでテスト
|
||
local result = JsonNode.parse(json_text)
|
||
print("Parse result: " + result.stringify())
|
||
|
||
print("---")
|
||
i = i + 1
|
||
}
|
||
}
|
||
|
||
// 境界判定問題
|
||
test_boundary_issues() {
|
||
local boundary_cases = new ArrayBox()
|
||
|
||
// ❌ 文字列境界で混乱するケース
|
||
boundary_cases.push("{\"key with spaces\": \"value\"}") // スペース付きキー
|
||
boundary_cases.push("{\"comma,inside\": \"value,with,commas\"}") // 内部カンマ
|
||
boundary_cases.push("{\"colon:inside\": \"value:with:colons\"}") // 内部コロン
|
||
boundary_cases.push("{\"}bracket{\": \"value}with}brackets\"}") // 内部ブラケット
|
||
|
||
local i = 0
|
||
loop(i < boundary_cases.length()) {
|
||
local json_text = boundary_cases.get(i)
|
||
print("Boundary case: " + json_text)
|
||
|
||
print("⚠️ Simple substring parsing would fail here")
|
||
print("✅ Needs proper tokenization")
|
||
print("---")
|
||
i = i + 1
|
||
}
|
||
}
|
||
|
||
// 空白処理問題
|
||
test_whitespace_issues() {
|
||
local whitespace_cases = new ArrayBox()
|
||
|
||
// ❌ 空白の扱いで混乱するケース
|
||
whitespace_cases.push("{ \"key\" : \"value\" }") // 通常の空白
|
||
whitespace_cases.push("{\n \"multiline\": \"value\"\n}") // 改行・インデント
|
||
whitespace_cases.push("{\"no\":\"spaces\"}") // 空白なし
|
||
whitespace_cases.push("{\t\"tab\":\t\"separated\"\t}") // タブ区切り
|
||
whitespace_cases.push("{ \"mixed\":\n\t \"whitespace\" }") // 混合空白
|
||
|
||
local i = 0
|
||
loop(i < whitespace_cases.length()) {
|
||
local json_text = whitespace_cases.get(i)
|
||
print("Whitespace case: '" + json_text + "'")
|
||
|
||
// 現在のNyash Nativeでテスト
|
||
local result = JsonNode.parse(json_text)
|
||
print("Parse result: " + result.stringify())
|
||
|
||
print("---")
|
||
i = i + 1
|
||
}
|
||
}
|
||
|
||
// ===== 簡単な解析の実装例(問題のあるパターン) =====
|
||
|
||
// ❌ 問題のある簡単な解析(参考用)
|
||
simple_parse(json_text) {
|
||
// これが「ずれ」の原因パターン
|
||
if json_text.substring(0, 1) == "{" and json_text.substring(json_text.length() - 1, json_text.length()) == "}" {
|
||
return "object(simple)"
|
||
} else {
|
||
if json_text.substring(0, 1) == "[" and json_text.substring(json_text.length() - 1, json_text.length()) == "]" {
|
||
return "array(simple)"
|
||
} else {
|
||
return "unknown(simple)"
|
||
}
|
||
}
|
||
}
|
||
|
||
// 括弧の数を数える(不正確な方法の例)
|
||
count_brackets(s) {
|
||
local open = 0
|
||
local close = 0
|
||
local i = 0
|
||
|
||
loop(i < s.length()) {
|
||
local ch = s.substring(i, i + 1)
|
||
if ch == "{" or ch == "[" {
|
||
open = open + 1
|
||
} else {
|
||
if ch == "}" or ch == "]" {
|
||
close = close + 1
|
||
}
|
||
}
|
||
i = i + 1
|
||
}
|
||
|
||
return { open: open, close: close }
|
||
}
|
||
}
|
||
|
||
// ===== yyjson相当の精度要件定義 =====
|
||
|
||
static box AccuracyRequirements {
|
||
|
||
// 最小限で確実な要件
|
||
get_minimum_requirements() {
|
||
local req = new MapBox()
|
||
|
||
// 必須機能(yyjson相当の精度)
|
||
req.set("essential", new ArrayBox())
|
||
req.get("essential").push("正確なエスケープ処理(\\n, \\\", \\\\, \\u0000)")
|
||
req.get("essential").push("ネスト構造の正確な解析(無制限深度)")
|
||
req.get("essential").push("文字列境界の正確な判定(クォート内外)")
|
||
req.get("essential").push("基本数値の正確な解析(int, float)")
|
||
req.get("essential").push("空白の正確な処理(有意/無意の区別)")
|
||
req.get("essential").push("構文エラーの確実な検出")
|
||
|
||
// 推奨機能(必要に応じて)
|
||
req.set("recommended", new ArrayBox())
|
||
req.get("recommended").push("指数表記の数値サポート(1.23e-4)")
|
||
req.get("recommended").push("Unicode エスケープ(\\u0041)")
|
||
req.get("recommended").push("詳細なエラー位置情報")
|
||
req.get("recommended").push("ストリーミング解析(大きなJSON)")
|
||
|
||
// 不要機能(yyjsonにあるが省略可能)
|
||
req.set("optional", new ArrayBox())
|
||
req.get("optional").push("JSON Pointer(RFC 6901)")
|
||
req.get("optional").push("JSON Patch(RFC 6902)")
|
||
req.get("optional").push("超高速浮動小数点変換")
|
||
req.get("optional").push("インクリメンタル読み込み")
|
||
req.get("optional").push("カスタムアロケーター")
|
||
|
||
return req
|
||
}
|
||
|
||
// 最小実装スコープ決定
|
||
get_minimal_scope() {
|
||
print("🎯 Nyash JSON Native最小実装スコープ")
|
||
print("目標: yyjsonの確実性、でも機能は最小限")
|
||
|
||
local scope = new MapBox()
|
||
|
||
// Phase 1: 基本精度(現在80%完成)
|
||
scope.set("phase1", new ArrayBox())
|
||
scope.get("phase1").push("✅ 基本JSON型(null, bool, int, string, array, object)")
|
||
scope.get("phase1").push("✅ JSON文字列生成(エスケープ処理)")
|
||
scope.get("phase1").push("✅ 美しいモジュラー設計")
|
||
scope.get("phase1").push("🔄 基本的なエスケープ解析(現在部分実装)")
|
||
|
||
// Phase 2: yyjson相当の精度(残り20%)
|
||
scope.set("phase2", new ArrayBox())
|
||
scope.get("phase2").push("🎯 正確なLexer(トークン分割)")
|
||
scope.get("phase2").push("🎯 正確なParser(構文解析)")
|
||
scope.get("phase2").push("🎯 エラー検出・報告")
|
||
scope.get("phase2").push("🎯 複雑なネスト構造対応")
|
||
|
||
return scope
|
||
}
|
||
}
|
||
|
||
// テスト実行用
|
||
static box Main {
|
||
main() {
|
||
ParsingErrorAnalysis.test_parsing_errors()
|
||
|
||
print("\n📋 精度要件分析")
|
||
local requirements = AccuracyRequirements.get_minimum_requirements()
|
||
local scope = AccuracyRequirements.get_minimal_scope()
|
||
|
||
print("\n💡 結論:「どこまで作ればいいか」")
|
||
print("✅ Phase 1完了(基本機能・美しい設計)")
|
||
print("🎯 Phase 2必要(yyjson相当の精度達成)")
|
||
print("❌ Phase 3不要(JSON Pointer等の高度機能)")
|
||
print("\n🚀 次のステップ:正確なLexer実装で精度向上")
|
||
|
||
return 0
|
||
}
|
||
}
|