Files
endorphin-aster-vm/docs/runtime/reader.md
T
codex-bot 483d9d1717
Verify databases and deploy Aster VM / verify-and-deploy (push) Successful in 6m53s
Add Endor source reader before lexing with provenance and URI provider
2026-10-19 03:23:38 +08:00

50 lines
5.4 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.
# Endor 阅读器与源码来源
EndorReader 位于 lexer 之前,把宿主输入转换为 SourceUnit,再交给 lex_source、parse_source 或 parse_source_expression。它负责读取、严格 UTF-8 解码和来源记录,不解析 token、不解析 namespace 依赖、不执行代码。源码在 [reader.rs](../../crates/frontend/src/reader.rs),来源与诊断结构在 [source.rs](../../crates/frontend/src/source.rs),词法和语法见 [前端](frontend.md)。
```text
字符串/字节流/文件/宿主 URI provider
→ EndorReader → SourceUnit → lexer → PEG parser → AST
```
## 输入适配
| 入口 | 行为 |
| --- | --- |
| EndorReader::from_text(name, text) | 接收已经解码的 Unicode 字符串,复制或接管其 String 所有权,记录文本来源名称 |
| EndorReader::from_stream(name, reader) | 接收实现 std::io::Read 的流,读到 EOF 后统一严格解码,记录流名称 |
| EndorReader::from_file(path) | 按原生 Path 打开文件,读到 EOF 并严格解码,保留 PathBuf 来源 |
| EndorReader::from_endor(uri, provider) | 调用宿主 EndorSourceProvider 取得一次解析结果,严格解码并保存请求 URI 与已选修订标签 |
Reader 不修改 locale,不猜测 Shift_JIS/CP932 或其他编码,不以替换字符修复非法 UTF-8。其他编码由宿主先明确解码后通过字符串或 UTF-8 输入交付。流可以在任意字节处分块,包括拆开一个 Unicode 字符;所有字节收齐后才进行 UTF-8 校验。
文本原样保留:不转换 CRLF/CR,不移除 BOM,也不规范化 Unicode。Span 继续指向这份原始 UTF-8 文本;Reader 不提前处理注释、转义或缩进。BOM 等字符是否构成合法语法由 lexer 决定,当前 lexer 不接受开头 BOM。
SourceUnit 拥有源码和 SourceOrigin,只公开只读访问,不依赖仍打开的文件、流或平台连接。一次读取完成后,重新读取同一 URI 或修改源文件不会改写已有单元的内容;这保证输入缓冲区固定,不表示对可变文件读取过程实现了文件系统事务快照。
## 来源与诊断
SourceOrigin 区分 Text、Stream、File 和 Endor。文本/流名称由宿主指定,例如 `<editor>`、`<stdin>` 或会话输入编号;文件保留操作系统路径;Endor 来源额外记录 provider 给出的修订标签。
lex_source、parse_source 和 parse_source_expression 将原有 Diagnostic 包装为 SourceDiagnostic,保存来源、行列和完整诊断(包括 Span 与 expected 列表)。行列根据读取到的原文计算,使用一基 Unicode 标量列,CRLF 算一次换行。包装后的错误可以在源码缓冲区释放后继续报告;错误不会保存整份源码文本。
Read 阶段的 SourceReadError 与词法/语法 Diagnostic 分开:Io 保留原始 I/O/provider 错误,InvalidUtf8 报告第一个无效字节位置,InvalidEndorUri 表示入口不属于可接受的 Endor URI,MissingRevision 表示宿主没有提供已选修订。读取中途失败不返回部分源码,不继续解析部分内容;URI 失败不会改从本地文件读取。I/O 和 UTF-8 的底层错误可通过 Error::source 取得。
原有 lex(&str)、parse(&str)、parse_expression(&str) 保留为不带来源的低层便捷接口。需要文件名、URI、修订或会话标签时,宿主应使用 SourceUnit 入口;这些标签不是 VM 的 ObjectRef,也不充当持久资源身份。
## 平台 URI 边界
EndorSourceProvider::load(&str) 返回 io::Result<ResolvedEndorSource>。ResolvedEndorSource 包含 bytes 和非空 revision;宿主负责名称解析、权限检查、版本选择与实际存储访问,失败直接返回相应错误。例如权限不足可使用 PermissionDenied,不存在可使用 NotFound。
Reader 只校验 scheme 为不区分大小写的 endor、冒号后非空,且 URI 不含原始空白/控制字符。它不固定 workspace/namespace 的 URI 路径形式,不解码百分号、不实现相对 URI,也不规定修订选择器或 hash 算法。scheme 以外的协议校验由宿主执行,原 URI 不重写。每次读取只调用一次 provider,之后词法和语法处理不再解析 URI。
revision 是宿主返回的原样标签;Reader 只拒绝全空白标签,不验证标签是否为内容 hash、不验证内容与 hash 的对应关系,也不实现资源历史、依赖锁、发布快照或签名。当前没有内置平台 provider、网络客户端、数据库存储或 CLI URI 执行入口。具体版本模型仍需另行设计。
## CLI 与交互输入
CLI parse 文件通过 from_file → parse_source 输出 AST;`cli parse -` 通过 from_stream 读取 stdin 到 EOF,来源为 `<stdin>`。错误保留文件或流名及行列;文件读取与非法 UTF-8 错误在进入 lexer 前返回。命令仍不执行源码。
stdin 入口不是 REPL,不打印提示符、不保持求值环境,也不区分“需要继续输入”和“真正语法错误”。未来 REPL 宿主先收集一次提交的输入单元,再使用 from_text 并指定会话来源;reader 不承担交互调度。包与 namespace 的成员查找和依赖解析也不由 reader 自动完成。
运行方式见 [运行指南](../operations/README.md),编码边界见 [文本编码](text-encoding.md),检查范围见 [验证](../operations/validation.md)。本地不编译、不执行测试;流、文件与 provider 检查由指定远端环境执行。