У меня есть проблема, я не могу обернуть голову вокруг.Я хочу иметь возможность обнаруживать (то есть получать начальную и конечную строку) кодированные блоки, определенные как они в Python.
Например, следующий код:
def main():
foo = "bar"
if foo != "baz":
foo = "tab"
else:
foo = "wow"
for character in foo:
print(character)
return 1
выдастследующий результат [(0, 8), (2, 3), (4, 5), (6, 7)]
.Кроме того, мне нужно, чтобы это было оптимизировано для скорости, потому что действительно, мне нужно, чтобы обнаружение блоков выполнялось каждый раз, когда изменяется содержимое кода.Я думаю, что древовидная структура для организации блоков кажется идеальной (с блоками if
, else
и for
в примере, являющимися потомками блока def
).
Я пыталсяэтот код:
def detect_block(text):
import re
tabs = re.compile(r'( {4})')
start_re = re.compile(r' *(elif|else|except|finally|for|if|try|while|with|label|screen|transform|init|layeredimage|menu|style|# *region|def)\b')
end_re = re.compile(r' *(\n|break|continue|return|yield|yield from|pass|# *endregion)\b')
start_indices = []
end_indices = []
rv = []
for line_nb, line in enumerate(text.split("\n")):
indent = len(tabs.findall(line))
if start_re.match(line):
start_indices.append((line_nb, indent))
elif end_re.match(line):
end_indices.append((line_nb, indent))
for i, (idx, idx_indent) in enumerate(start_indices):
for jdx, jdx_indent in end_indices:
if jdx_indent == idx_indent and jdx > idx:
rv.append((idx, jdx))
break
return rv
но я не получаю ожидаемого результата.Я застрял на этой проблеме в течение нескольких дней.