Files
stgsharp/future/ngra-regex-sourcegen-goldens.md
T
2026-07-21 18:02:46 +08:00

135 lines
4.5 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.
# NGRA Regex 源生成手写样本
这个文件用于记录源生成器实现前需要手写的正则匹配样本。
流程:
1. 选一个表达式。
2. 手写理想匹配代码。
3. 生成优化后 IR。
4. 对照手写代码和 IR 段。
5. 标注每段 IR 应该生成的代码形状。
6. 抽取生成器规则。
选样原则:
1. 表达式必须是典型正则写法。
2. 全部样本合起来应覆盖计划支持的大部分 regex 语法。
3. 样本不以表达式结构优化为目标,避免依赖公共前缀提取、分支树重排等 AST 优化。
4. `TRY`/`CONDITION` 前缀化改写属于 IR 执行形态整理,不算表达式优化。
## 记录模板
```text
Regex:
覆盖形态:
期望代码形状:
Optimized IR:
IR -> Code 规则:
备注:
```
## 第一批:基础线性匹配与转义
| Regex | 覆盖形态 | 手写重点 |
| --- | --- | --- |
| `abc` | 单个 `MATCH_SEQ` | 最小长度检查、序列匹配、活动指针推进 |
| `a[abc]d` | `MATCH_SEQ` + `MATCH_SET` + `MATCH_SEQ` | set 后端展开前的调用边界 |
| `[abc]` | 单个 `MATCH_SET` | 字符集单字符匹配 |
| `[.]` | set 中的字面点号 | 确认 `[.]` 和 `.` 语义分离 |
| `.` | 任意字符匹配 | `MATCH_SET "."` 的特殊后端语义 |
| `\.` | 转义字面点号 | 确认 `\.` 进入 seq 系 IR |
| `a\*b` | 转义操作符字面量 | tokenizer 已消解转义语义 |
## 第二批:计数
| Regex | 覆盖形态 | 手写重点 |
| --- | --- | --- |
| `a*` | `COUNT_SEQ`,`MIN:0 MAX:-1` | 贪婪计数、允许空匹配 |
| `a+` | `COUNT_SEQ`,`MIN:1 MAX:-1` | 至少一次的计数 |
| `a?` | `COUNT_SEQ`,`MIN:0 MAX:1` | 可选单元 |
| `a{3,5}` | 固定下限 + 可选上限 | 下限展开与剩余计数 |
| `[abc]*` | `COUNT_SET` | 字符集循环 |
| `.{11,13}` | 任意字符计数 | set 语义在后端展开 |
## 第三批:ALT 与前缀化
| Regex | 覆盖形态 | 手写重点 |
| --- | --- | --- |
| `a|b` | 最小 ALT | region 缓冲、失败切换、成功短路 |
| `ab|cd|ef` | 多分支 ALT | 多个 case 的失败链 |
| `a|bc|def` | 不同长度 ALT | case 间活动指针恢复 |
| `(ab|[cd]|.)x` | 混合 case ALT | seq、set、任意字符分支后接公共后缀 |
## 第四批:复杂计数块
| Regex | 覆盖形态 | 手写重点 |
| --- | --- | --- |
| `(ab){2,3}` | `COUNT` complex body | complex body 调用域、计数退出 |
| `(123(4|5)67){3,4}114514` | complex count + ALT + 后缀 | `CommandCount` 重算、region 复用、后续线性匹配 |
## 第五批:FIND 与 `.*`
| Regex | 覆盖形态 | 手写重点 |
| --- | --- | --- |
| `.*abc` | 最远/最近搜索前缀 | `FIND_SEQ` 或 `FIND_COMPLEX` 到后续锚点 |
| `abc.*` | 后缀任意吞吐 | 尾部 `.*` 的快速成功策略 |
| `[.]*` | 字面点号计数 | 不应被当成原装 `.*` 优化 |
## 第六批:字符集语义
| Regex | 覆盖形态 | 手写重点 |
| --- | --- | --- |
| `[123abc]` | 离散字符集 | set 后端展开为离散匹配 |
| `[1-9]` | 连续字符集 | set 后端展开为范围匹配 |
| `\w` | 转义字符集 | escape-set 后端语义 |
| `\w+` | 转义字符集计数 | set 计数循环 |
## 第七批:捕获组
| Regex | 覆盖形态 | 手写重点 |
| --- | --- | --- |
| `(abc)` | 普通捕获组 | 默认序号 group |
| `(?<name>abc)` | 简单命名组 | group 起止范围、`PACK` |
| `(?<name>.*)234` | group 内 `.*` + 后续锚点 | `FIND_COMPLEX FURTHEST -1` 与后续 `MATCH_SEQ` |
| `(?<name>.*)a` | group 内 `.*` + 单字符锚点 | 最远搜索回退到后缀匹配 |
| `(?<a>abcd|a(bc)c)` | group 内 ALT | group success 依赖 region |
| `a*.[abc]*(?<a>abcd|a(bc)c)(?<name>.*)234` | 综合样本 | count、set、ALT、group、find、后缀匹配 |
## 当前优先级
第一阶段只要求源生成器能稳定处理:
1. `MATCH_SEQ`
2. `MATCH_SET`
3. `COUNT_SEQ`
4. `COUNT_SET`
5. 简单 `ALT`
6. `PACK`
7. `FIND_SEQ`
8. `FIND_COMPLEX COUNT:-1`
低优先级:
1. 逐 region 最短长度断言。
2. 复杂字符集完全内联。
3. 公共前缀提取和代码树生成。
4. 对所有正则语义做完整兼容。
## 手写代码关注点
每个样本的手写代码都应尽量确认这些点:
1. 活动指针如何推进。
2. 失败时是否需要恢复活动指针。
3. region result 和 single-line result 是否必须分配。
4. `Observe_Line` 是否只读取目标行结果。
5. `Observe_Region` 是否只读取目标 region 结果。
6. `PACK` 使用哪一个成功结果作为捕获区间。
7. 最小长度检查是否值得在当前样本中生成。