Lark语法解析中文件末尾换行符缺失导致解析结果异常的解决方法咨询
Lark语法解析中文件末尾换行符缺失导致解析结果异常的解决方法咨询
我完全懂你现在的困惑——明明只是少了个末尾换行符,Lark的解析结果却多出来一个莫名其妙的map节点,好好的两组数据被拆成了三组,确实挺闹心的。咱们来一步步捋清楚问题出在哪,怎么解决。
问题根源
先看你定义的map规则:
map : [coord coord*] NEWLINE?
这里有两个关键的问题:
- 方括号
[]把整个坐标序列变成了可选的,意味着理论上一个map可以是空的(连一个coord都没有),这就给解析器留下了错误拆分的空间; NEWLINE?表示换行是可选的,当文件末尾没有换行时,解析器会尝试尽可能多地匹配map规则,于是就把中间的单个__误判成了一个独立的map——毕竟单个coord满足[coord coord*](coord*可以是空),而且后面没有换行也符合NEWLINE?的要求。
解决方法
我们需要调整语法规则,明确两个核心要求:
- 每个
map必须包含至少一个坐标元素; map的结束条件要么是换行,要么是整个文件的结尾(处理无末尾换行的情况)。
修改后的语法如下:
grammar = """ start : NEWLINE? map+ map : coord+ (NEWLINE | $) # $ 表示文件结束标记 coord : HEX | FILL HEX : ("A".."F" | DIGIT)+ FILL : "__" %import common.DIGIT %import common.NEWLINE %import common.WS_INLINE %ignore WS_INLINE """
规则解释
map: coord+ (NEWLINE | $):coord+强制每个map至少有一个坐标,彻底杜绝空map或者单个coord被误拆的情况;(NEWLINE | $)明确map的结束信号:要么是换行(分隔不同map),要么是文件直接结束(对应无末尾换行的场景)。
start: NEWLINE? map+:保留你原来的开头可选换行逻辑,同时确保整个输入是一个或多个合法的map。
测试验证
不管你的FILE末尾有没有换行符,用这个语法解析都会得到预期的两个map树:
- 有末尾换行时:第一个map匹配到换行,第二个map也匹配到换行(或者文件结束,不影响);
- 无末尾换行时:第二个map直接匹配文件结束标记
$,不会被拆分。
你的MyParser转换器代码不需要改动,它的逻辑是正常的,只需要替换掉grammar部分即可。
内容来源于stack exchange
相关产品推荐
相关产品推荐

