#python #lark-parser
Вопрос:
Я работаю над проектом на основе Жаворонка, в котором мне нужно уметь «улавливать» комментарии в анализируемом коде.
Однако это не работает при использовании стандартного лексера без явного указания стандартного лексера.
Я взял второй пример из рецептов Жаворонка и изменил его, чтобы использовать синтаксический анализатор по умолчанию и анализировать однострочные комментарии, похожие на 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'
лексер, когда он явно не указан? Это ошибка в моем коде или возможная ошибка в Жаворонке?
Дальнейшие эксперименты, по-видимому, указывают на то, что это либо 'dynamic'
или 'dynamic_complete'
используется в случае по умолчанию ( lexer
не указано).
Комментарии:
1. Из кода видно, что со
auto
значением по умолчанию для лексера и без указания синтаксического анализатора илиpostlex
вы действительно должны получить стандартный лексер… может быть, стоит войти вLark()
вызов и посмотреть, что там происходит
Ответ №1:
Lark
поддерживает различные комбинации parser
и lexer
. Кто-то поддерживает lexer_callbacks
, кто-то нет:
синтаксический анализатор | лексер | lexer_callbacks |
---|---|---|
лалр | стандарт | ДА |
лалр | контекстуальный | ДА |
эрли | стандарт | ДА |
эрли | динамический | НЕТ |
эрли | динамический_полный | НЕТ |
лалр | традиция | (Может быть) |
эрли | традиция | (Может быть) |
lexer="auto"
выбирает лексер в зависимости от синтаксического анализатора: для lalr
него выбирает contextual
, для earley
него выбирает dynamic
. Синтаксический анализатор по умолчанию earley
, поэтому без выбора parser
или lexer
, lexer_callbacks
не поддерживается.
Вопрос на этот счет уже открывался и снова закрывался.