微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么我们需要指定标准的 Lark lexer 才能捕获注释终端?

如何解决为什么我们需要指定标准的 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 支持 parserlexer 的不同组合。有些支持lexer_callbacks,有些不支持:

解析器 词法分析器 lexer_callbacks
啦啦 标准
啦啦 上下文
早期 标准
早期 动态 没有
早期 dynamic_complete 没有
啦啦 自定义 (也许)
早期 自定义 (也许)

lexer="auto" 根据解析器选择词法分析器:对于 lalr,它选择 contextual,对于 earley,它选择 dynamic。默认解析器为 earley,因此如果不选择 parserlexer,则不支持 lexer_callbacks

这方面的issue已经打开又关闭了。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。