Ниже приведен синтаксический анализ выражения lisp (выполняя как можно больше за один раз). Как это выглядит и что можно улучшить?
# goal: capture the next token then get the rest of the line
# to be used in a while-loop/yield
tokenizer = re.compile(r"""
s* # any amount of whitespace...
# 1. capture group one: token
(
,@ # special token ,@ ...
|[(),`'] # or ) ( , ' ` ...
|"(?:[^\"]*(?:\.)*)*" # or match on string (unrolling the loop)...
|;.* # or comment-anything...
|[^s('"`,;)]* # or non-special...
)
# 2. capture group two: rest-of-line
(.*)
""", re.VERBOSE)
Пример запуска (python):
line="(define (square x) (* x x))"
while line:
token, line = tokenizer.match(line).groups()
print (token)
1 ответ
Мне сложно сказать, хорошо это написано или нет, поскольку тестов нет, и это, по сути, ваша самая большая проблема. Подобное сложное регулярное выражение не может быть лучшим объектом для модульного тестирования. Он уже хорошо изолирован, он важен, в некоторой степени внутренне сложен, и было бы полезно указать, какие именно входы и выходы вы ожидаете. Включите в свои тесты столько граничных случаев, сколько вы можете придумать, а также «хорошие» (входные данные, которые вы ожидаете успешно проанализировать), а также «плохие» (входные данные, которые, как вы ожидаете, не должны анализироваться ожидаемым образом).
Само регулярное выражение не кажется сумасшедшим. Я нахожу отсутствие ^ и $ подозрительный. Если вы случайно отправите это через search вместо match, вы оставляете себя уязвимым для ложных срабатываний.
