discuss regex ir opt
This commit is contained in:
+56
-9
@@ -14,15 +14,62 @@
|
||||
|
||||
使用DEFINE指令定义的符号定义在符号区中,符号的类型通过第一次赋值确定,源生成模式下,可以通过第一个赋值指令推导其类型
|
||||
|
||||
## 算子
|
||||
## HIR算子
|
||||
|
||||
1. 搜索算子(SEARCH %str; SEARCH %unicode),向后搜索确定长度序列或者满足规则的字符集,更新活动指针,不更新锚点指针,搜索结果保存在全局上下文中
|
||||
2. 搜索算子(SEARCH %set_expression),向后匹配一个满足字符集要求的字符,更新活动指针,不更新锚点指针,搜索结果保存在全局上下文中
|
||||
3. 失败配置指令(CINFIG_FAIL %fail),指定当前匹配栈后续如何处理一条指令的失败,可选为:FAST,立刻终止当前层级;CONTINUE,记录这个fail,但是继续操作;REVERSE,反过来,成功了才终止
|
||||
4. 条件指令(CONDITION %cmd_true %cmd_fail),比较前一条SEARCH指令是否成功,并指定跳转到指定的位置,如果某种条件不需要跳转,可以写1。如果想要将fail向上级继续抛出,可以%cmd_fail写0.
|
||||
5. 跳转执行指令(TRY %begin %end),尝试idx指向的IR块,并记住执行结果数据
|
||||
6. 计数指令(COUNT %min %max %is_greedy %cmd),重复执行指令cmd,直到满足参数配置的数量为止
|
||||
7. 快速序列计数指令(COUNT_SEQ %min %max %is_greedy %seq),快速搜索一个确定性序列,直到满足参数配置的数量为止
|
||||
8. 快速字符集计数指令(COUNT_SET %min %max %is_greedy %set),快速搜索一个字符集,直到满足参数配置的数量为止
|
||||
9. 尝试(TRY %count),对自身向后的一段内容在新的匹配栈层级中进行运行,被分层的指令数量由COUNT指令确定
|
||||
10. 弹出(POP %is_success),提前终止一个try块,并用is_success表示弹出行为视为匹配成功还是失败
|
||||
3. 条件指令(CONDITION %cmd_true %cmd_fail),比较前一条SEARCH指令是否成功,并指定跳转到指定的位置,如果某种条件不需要跳转,可以写1。如果想要将fail向上级继续抛出,可以%cmd_fail写0.
|
||||
4. 计数指令(COUNT %min %max %is_greedy %cmd),重复执行指令cmd,直到满足参数配置的数量为止
|
||||
5. 快速序列计数指令(COUNT_SEQ %min %max %is_greedy %seq),快速搜索一个确定性序列,直到满足参数配置的数量为止
|
||||
6. 快速字符集计数指令(COUNT_SET %min %max %is_greedy %set),快速搜索一个字符集,直到满足参数配置的数量为止
|
||||
7. 尝试(TRY %count),对自身向后的一段内容在新的匹配栈层级中进行运行,被分层的指令数量由COUNT指令确定
|
||||
8. 弹出(POP %is_success),提前终止一个try块,并用is_success表示弹出行为视为匹配成功还是失败
|
||||
9. 打包指令(PACK %is_success %name),检查上一条语句的结果,将匹配结果打包并记录为指定的名字。如果名字为空,则使用默认的序号进行索引
|
||||
|
||||
## 优化策略
|
||||
|
||||
应当注意的是,将HIT进行进一步优化或者展开的目的:
|
||||
|
||||
1. 尽可能降低源生成或者运行时执行中,对多指令上下文的依赖,尽可能保证每一个IR可以单独输出最佳的代码
|
||||
2. 减少多余的结构,使得一行指令尽可能处理多的数据
|
||||
|
||||
### 语义改写优化
|
||||
|
||||
1. 计数器展开
|
||||
建议在lower做
|
||||
对于形如a+b或者a{2,4}b的正则表达式,可以优化为a*(ab|b)和a{2,3}(ab|b)的写法
|
||||
|
||||
2. 确定性计数展开
|
||||
建议在lower做
|
||||
对于形如a{m,n}的正则表达式,将其展开为a{m}a{0,n-m}的形式
|
||||
|
||||
3. charset合并
|
||||
建议在ast-opt做
|
||||
对于形如[ abc ]|[ def ]的表达式,将其合并为[ abcdef ]
|
||||
|
||||
4. charset展开
|
||||
在lower做
|
||||
对于形如abc[ de ]的表达式,如果字符集容量不超过4,可以站卡为(abcd|abce)形式
|
||||
|
||||
### 匹配策略改变
|
||||
|
||||
1. 长度预测
|
||||
在source-gen阶段做
|
||||
对于一个正则表达式,可以计算其所需的最小长度,可以在开始的时候提前进行比较
|
||||
|
||||
2. .*优化
|
||||
在lower阶段做
|
||||
对于COUNT_SET min=0 max=-1 "."指令,也就是.*操作,将后续指令从match转为find
|
||||
|
||||
3. [ set ]*优化
|
||||
在source-gen阶段做
|
||||
对于其他的COUNT_SET min=0 max=-1 "???"指令,使用IndexOf,IndexOfAnyExcept等进行优化
|
||||
|
||||
4. 首字母检查
|
||||
**这个不好做,因为IR直接把ALT打碎成if-else串了**
|
||||
对于(abc|defg|xyz)表达式,可以检查其首字母
|
||||
|
||||
### C# span opt trick
|
||||
|
||||
1. Span.StartWith
|
||||
2. [ 0-9 ]展开为IndexOf("0123456789")
|
||||
Reference in New Issue
Block a user