Lark语法终端冲突警告原因不明,寻求技术解答
问题根本原因解析
1. 无限量词触发的正则扩展导致终端副本生成
你遇到的冲突本质是:当使用+/*这类无限量词时,interegular会对正则表达式做内部的扩展处理。这个过程中,Lark没有正确复用通过%import导入的命名空间终端——具体来说,b.lark里导入的CHARSTR,在被无限量词修饰后,会被生成一个新的终端实例(命名为b__CHARSTR),而不是直接复用a.lark里的a__CHARSTR。当c.lark同时导入a和b的内容时,两个完全相同的正则终端就会共存,触发冲突警告。
2. 有限量词无警告的核心逻辑
当使用?或~2..5这类有限量词时,interegular不需要对正则做复杂的无限循环扩展,Lark会直接复用原导入的a__CHARSTR终端,不会生成新的副本,自然避免了冲突。
3. 版本1无警告的原因
版本1里expression规则直接写在c.lark中,所有对CHARSTR的引用都直接指向a__CHARSTR,没有中间文件(b.lark)的二次导入环节,也就不会触发终端副本的生成逻辑,因此没有警告。
额外验证小技巧
你可以在b.lark里给导入的CHARSTR重命名试试:
%import a.CHARSTR as B_CHARSTR expression: B_CHARSTR+
此时c.lark导入后,警告会变成Collision between Terminals a__CHARSTR and b__B_CHARSTR——这能更直观地看到,同一个正则被生成了两个独立终端,根源还是无限量词触发的正则扩展逻辑导致的终端实例复制。
内容的提问来源于stack exchange,提问作者xylophone
相关产品推荐
相关产品推荐

