aardio 文档

JSON.strict:严格 JSON 解析

显式导入 JSON.strict 后,使用独立入口解析 JSON。普通 JSON.parse、JSON.tryParse、JSON.stringify 及其默认行为均不改变;普通调用不增加自动校验。

JSON.strict 库采用非递归、显式容器栈的单遍语法解析,直接生成 aardio 数据,不先宽松解析再检查结果。没有序列化器、JSON Schema、文件加载器或项目验证框架。

JSON.strict 仅用于严格校验 JSON 语法,如果无此需求建议改用 JSON 库。

快速使用

import JSON.strict;

var data,err,detail = JSON.strict.tryParse(`{
    "name": "示例",
    "items": [1, null, 3, null],
    "optional": null
}`);

if(err){
    print(err);
    print(detail.code, detail.byte, detail.line, detail.column);
    return;
}

print(data.name);
print(table.len(data.items)); // 4,包含末尾的 null
for i,value in table.eachIndex(data.items){
    print(i,value); // 包括 null 元素
}

print(JSON.stringify(data)); // 继续使用现有序列化器

三个入口

函数 成功 失败
JSON.strict.parse(text[,options]) 解析值 抛出错误
JSON.strict.tryParse(text[,options]) 解析值,第二返回值为 null null, message, detail
JSON.strict.validate(text[,options]) true null, message, detail

validate 不构造完整结果树,但仍需要临时保存对象的已解码键以判断重复。它使用与解析相同的 Unicode、重复键、数值范围和资源策略,不是仅检查 RFC 语法。

输入可以是 UTF-8 字符串或 buffer。buffer 会先复制为不可变字符串;不会改动输入或选项。不猜测代码页、不自动转码;拒绝带 UTF-16 标记的字符串。读取文件时,先自行检查读文件是否成功,再把原始内容传给解析器。

不要用首返回值是否为真判断成功:合法的 null、false、0 都是假值。

import JSON.strict;

var value,err = JSON.strict.tryParse("null");
assert(err === null);  // 成功
assert(value === null);

var ok,message,detail = JSON.strict.validate("[1,]");
assert(ok === null);   // 尾逗号不合法
print(message);

语法与策略分层

JSON 语法

支持顶层对象、数组、字符串、数字、true、false 和 null,不要求根值为对象。

注释、JSONP、单引号、未引用键、十六进制数、前导加号、前导零、NaN、Infinity、undefined、True 等扩展均被拒绝。

重复键策略

默认 duplicateKeys="reject"。在同一个对象内,按解码后的字符串、区分大小写判重。因此 "a" 与 "\u0061" 重复,"A" 与 "a" 不重复。支持含 NUL 的键;不进行 Unicode 规范化。

可以显式指定 duplicateKeys="last",保留最后出现的值(包括 null),元表 _defined 中每个键只记录一次。

重复键拒绝是本库的默认互操作策略,不是声称 RFC 的 JSON 语法绝对禁止重复键。

Unicode 与 BOM

本库要求字符串为有效的 Unicode scalar UTF-8:拒绝过长编码、孤立续字节、截断编码、UTF-8 编码的代理项及大于 U+10FFFF 的码点。转义中的高代理项必须紧跟低代理项,孤立代理项被拒绝;合法代理对合成为 UTF-8。