refactor: define lexical rules in a separate PEG grammar
Verify databases and deploy Aster VM / verify-and-deploy (push) Successful in 6m57s
Verify databases and deploy Aster VM / verify-and-deploy (push) Successful in 6m57s
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
| [对象模型](objects.md) | EndorObject/ObjectHeader、代际句柄、操作协议、托管引用与循环回收 |
|
||||
| [基本对象与 Number](builtins.md) | 函数、原生函数、字典、Cell、异常数据、字符串与无损数字 |
|
||||
| [Endor 阅读器](reader.md) | SourceUnit、来源/修订标签、字符串/流/文件和宿主 URI provider |
|
||||
| [源码前端](frontend.md) | 手写 lexer、token PEG parser、AST、基础函数/表达式语法与诊断 |
|
||||
| [源码前端](frontend.md) | 字符 PEG lexer、token PEG parser、AST、基础函数/表达式语法与诊断 |
|
||||
| [字节码 VM](bytecode.md) | 指令编码、代码校验、局部槽、执行帧、函数创建、调用/返回与边界 |
|
||||
| [文本编码](text-encoding.md) | UTF-8、日文、外部 Shift_JIS/CP932 与宿主解码边界 |
|
||||
| [数据库特殊类](database-objects.md) | 显式连接、调用方数据模型、未来类接入与资源生命周期 |
|
||||
|
||||
@@ -1,14 +1,23 @@
|
||||
# 源码词法与 PEG 语法前端
|
||||
|
||||
frontend 包提供 [Endor 阅读器](reader.md)、手写 Rust lexer 和 rust-peg 生成的 token parser。宿主通过 SourceUnit 调用带来源的词法/语法入口,原有 lex、parse、parse_expression 保留;CLI 提供 parse 文件/stdin 命令;结果是 AST,尚未实现 AST 到字节码生成、类型检查、名称解析或源码执行。Core 仅依赖本地 Objects,不依赖 frontend 或 peg;Objects 保持零依赖。
|
||||
frontend 包提供 [Endor 阅读器](reader.md)、rust-peg 生成的字符 lexer 与 token parser。宿主通过 SourceUnit 调用带来源的词法/语法入口,原有 lex、parse、parse_expression 保留;CLI 提供 parse 文件/stdin 命令;结果是 AST,尚未实现 AST 到字节码生成、类型检查、名称解析或源码执行。Core 仅依赖本地 Objects,不依赖 frontend 或 peg;Objects 保持零依赖。
|
||||
|
||||
首版以 Endorphin-Language 设计稿的基础词法、表达式与函数章节为起点,语法可以继续修改;设计稿中的未完成部分不作为阻塞前端实现的前置条件,也不被整体视作已经实现的语言能力。这里维护当前解析契约;源码位置见 [frontend](../../crates/frontend/README.md)。
|
||||
|
||||
## 语法文件
|
||||
## 词法与语法文件
|
||||
|
||||
实际 PEG 规则集中在 [grammar.peg](../../crates/frontend/src/grammar.peg),包含 token 匹配、函数/绑定/return、表达式优先级与 AST 构造动作。[parser.rs](../../crates/frontend/src/parser.rs) 保留解析入口、诊断转换和 AST 辅助函数,通过 include!("grammar.peg") 在编译期引入规则。
|
||||
两份规则复用现有 peg 0.8.6 依赖,分别处理字符和 Token:
|
||||
|
||||
grammar.peg 保留 rust-peg 0.8 的 peg::parser! 外层声明,因此是直接参与编译的语法源文件;不另存一份说明性文法,也不新增生成脚本或 build-dependencies。修改规则后随 frontend 重新编译。远端检查脚本单独用 rustfmt 检查该扩展名文件的格式。
|
||||
| 文件 | 输入与职责 | Rust 接口 |
|
||||
| --- | --- | --- |
|
||||
| [lexer.peg](../../crates/frontend/src/lexer.peg) | str 字符输入,识别名称、数字、字符串/转义、标点、空白/注释及词法错误,生成 Token | [lexer.rs](../../crates/frontend/src/lexer.rs) 保留 lex/lex_source、游标、位置换算和字符串解码 |
|
||||
| [grammar.peg](../../crates/frontend/src/grammar.peg) | [Token] 输入,匹配函数/绑定/return、表达式优先级并构造 AST | [parser.rs](../../crates/frontend/src/parser.rs) 保留解析入口、诊断转换和 AST 辅助函数 |
|
||||
|
||||
lexer.rs 与 parser.rs 分别通过 include! 在编译期引入对应规则;两份 .peg 文件保留 peg::parser! 外层声明,直接参与编译,不新增 build.rs、生成脚本或依赖。远端检查脚本单独对两份规则执行 rustfmt。
|
||||
|
||||
字符 PEG 的内部 next 规则使用 #[no_eof] 每次识别一个前缀,跳过空白/注释并返回一个 Token 或输入结束。Lexer 保存 source/offset,循环调用该规则,直到全输入结束或首个错误;公开 lex 仍扫描整份输入,不是增量/可恢复输入接口。规则中的 position! 相对本次输入切片,lexer.rs 将 Token 和诊断位置统一换算为原始源码 UTF-8 字节范围。
|
||||
|
||||
已识别的非法数字后缀、字符串转义、裸换行/NUL、未闭合字符串和未知字符,以规则返回的 Diagnostic 值传递,不作为允许 PEG 改试其他 Token 种类的匹配失败。识别到词法错误即停止;词法规则不修改外部游标或 Token 容器,避免回溯副作用。前缀规则及动作约定见 [peg 官方文档](https://docs.rs/peg/0.8.6/peg/#end-of-file-handling)。
|
||||
|
||||
## 入口和所有权
|
||||
|
||||
@@ -23,7 +32,7 @@ grammar.peg 保留 rust-peg 0.8 的 peg::parser! 外层声明,因此是直接
|
||||
|
||||
AST 的名称、数字原文和解码后的字符串均由 AST 自己持有,可以在释放输入后继续使用。Token/AST 的 Span 均为原始 UTF-8 源码的半开字节区间 start..end;节点跨度包含首尾 token 之间的空白及注释,不包含外侧 trivia。分组表达式的范围包括括号,Program 范围从第一个函数到最后一个函数。
|
||||
|
||||
语法动作只构造 AST,不做 I/O、VM 分配或其他外部写入。PEG 回溯不会执行语言函数或产生宿主业务副作用。
|
||||
词法动作只返回 Token/诊断,语法动作只构造 AST;两者均不做 I/O、VM 分配或其他外部写入。PEG 回溯不会执行语言函数或产生宿主业务副作用。
|
||||
|
||||
## 词法规则
|
||||
|
||||
|
||||
Reference in New Issue
Block a user