Как обнаружить блоки кода для языка, подобного Python

#python #split

#python #разделение

Вопрос:

У меня проблема, которую я не могу обдумать. Я хочу иметь возможность обнаруживать (т. Е. получать начальную и конечную строки) закодированные блоки, определенные так, как они определены в 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
  

но я не получаю ожидаемого результата. Я застрял на этой проблеме уже несколько дней.

Комментарии:

1. подсказка, устраните отступы и : , а не ключевые слова. Это с регулярным выражением, вероятно, будет намного более болезненным, чем должно быть.

2. Спасибо. Я уже думал об отступах (как вы можете видеть в моей попытке), но я не подумал о : пунктуации.

3. docs.python.org/3/library/tokenize.html и найдите маркеры ОТСТУПА / выделения.

4. Есть проверка: из dis импортировать dis; распечатать(dis(main))?

5. dis здесь не помогает, потому что я хочу разобрать текст. Не получить информацию об обратном отслеживании, поскольку код не выполняется