如何解决为什么我们需要指定标准的 Lark lexer 才能捕获注释终端?
我正在开发一个基于 Lark 的项目,我需要能够“捕捉”正在解析的代码中的注释。
但是,在没有明确指定标准词法分析器的情况下使用标准词法分析器时,它不起作用。
我从 the Lark recipes 中提取了第二个示例并将其修改为使用默认解析器并解析类似 C++ 的单行注释:
import lark
comments = []
grammar = r'''
start: INT*
COMMENT: "//" /[^\n]*/
%import common (INT,WS)
%ignore COMMENT
%ignore WS
'''
# This doesn't work,comments are not appended to the list
# parser = lark.Lark(grammar,lexer_callbacks={'COMMENT': comments.append})
# But this does work
parser = lark.Lark(grammar,lexer='standard',lexer_callbacks={'COMMENT': comments.append})
source = r'''
1 2 3 // hello
// world
4 5 6
'''
parser.parse(source)
print(comments)
如果我没有 lexer='standard'
,结果是一个空列表。
但是当没有明确指定时,它不应该已经使用了 'standard'
词法分析器吗?是我代码中的错误,还是 Lark 中可能存在的错误?
进一步的实验似乎表明它是在默认情况下使用的 'dynamic'
或 'dynamic_complete'
(未指定 lexer
)。
解决方法
Lark
支持 parser
和 lexer
的不同组合。有些支持lexer_callbacks
,有些不支持:
解析器 | 词法分析器 | lexer_callbacks |
---|---|---|
啦啦 | 标准 | 是 |
啦啦 | 上下文 | 是 |
早期 | 标准 | 是 |
早期 | 动态 | 没有 |
早期 | dynamic_complete | 没有 |
啦啦 | 自定义 | (也许) |
早期 | 自定义 | (也许) |
lexer="auto"
根据解析器选择词法分析器:对于 lalr
,它选择 contextual
,对于 earley
,它选择 dynamic
。默认解析器为 earley
,因此如果不选择 parser
或 lexer
,则不支持 lexer_callbacks
。
这方面的issue已经打开又关闭了。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。