使用Lark与LALR解析行尾注释的技术问题求助
嘿,我来帮你搞定这个Lark语法的问题~
问题出在哪?
你的核心问题是TEXT终端的正则表达式太“贪心”了——/[^\n]+/会匹配换行前的所有字符,包括行尾的//注释。Lark的词法分析是按「最长匹配优先」来的,TEXT把整行内容都吃掉了,COMMENT根本没机会捕获那些行尾注释。
两种解决办法任你选
办法1:精准限制TEXT,不让它碰//
修改TEXT的正则,让它只匹配不包含连续双斜杠的内容。这样当遇到//时,TEXT会立刻停止匹配,把这部分留给COMMENT处理,最后通过%ignore忽略掉注释。
修改后的语法:
start: (TEXT _NEWLINE)+ # 正则逻辑:要么匹配非/、非换行的字符,要么匹配单个/(后面不能跟/) TEXT: /(?:[^/\n]|/(?!/))+/ COMMENT: /\/\/[^\n]*/ %ignore COMMENT # 全局忽略所有注释 _NEWLINE: (" "* "\n")+
办法2:重构语法结构,让COMMENT优先匹配
换个思路,直接定义「行」的组成,把COMMENT放在TEXT前面定义(Lark会优先匹配先定义的终端),再用%ignore全局忽略注释,这样不管注释在什么位置,都会被先捕获并忽略,剩下的内容才会交给TEXT。
修改后的语法:
start: line+ line: (TEXT)? _NEWLINE TEXT: /[^\n]+/ COMMENT: /\/\/[^\n]*/ %ignore COMMENT # 所有COMMENT都会被忽略 _NEWLINE: (" "* "\n")+
测试一下效果
用你原来的Python代码测试修改后的语法,不管选哪种办法,解析出来的语法树里都只会保留Lorem ipsum和Text with这两个TEXT节点,行尾的注释完全被忽略,完美解决问题~
from lark import Lark parser = Lark.open("grammar.lark", parser='lalr') result = parser.parse("""Lorem ipsum // line comment Text with // trailing comment """) print(result.pretty())
小提示
- 办法1更严谨,能确保TEXT里绝对不会出现
//,适合对TEXT内容有严格要求的场景; - 办法2更简洁,利用Lark的特性简化语法,适合不需要限制TEXT内容的情况。
内容的提问来源于stack exchange,提问作者Scriptim
相关产品推荐
相关产品推荐

