Подтвердить что ты не робот

Как обработчики Python обрабатывают отступы?

При синтаксическом анализе языка произвольной формы, такого как C, анализатору легко определить, связаны ли несколько выражений друг с другом, просто взглянув на символы, испускаемые синтаксическим анализатором. Например, в коде

if (x == 5) {
    a = b;
    c = d;
}

Парсер может сказать, что a = b; и c = d; являются частью одного и того же оператора блока, потому что они окружены фигурными скобками. Это может быть легко закодировано как CFG, используя что-то вроде этого:

STMT        ::=  IF_STMT | EXPR; | BLOCK_STMT | STMT STMT
IF_STMT     ::=  if ( EXPR ) STMT
BLOCK_STMT  ::=  { STMT }

В Python и других языках, чувствительных к пробелам, сделать это не так просто, потому что структура операторов может быть выведена только из их абсолютной позиции, которую, я не думаю, можно легко закодировать в CFG. Например, приведенный выше код в Python будет выглядеть так:

if x == 5:
    a = b
    c = d

Как ни старайся, я не могу найти способ написать CFG, который бы принял это, потому что я не могу понять, как закодировать "два оператора с одинаковым уровнем вложенности" в CFG.

Как парсеры Python группируют операторы так, как они это делают? Они полагаются на сканер, который автоматически вставляет дополнительные токены, обозначающие начало и конец операторов? Производят ли они грубый AST для программы, затем имеют дополнительный проход, который собирает операторы на основе их отступа? Есть ли хитрый CFG для этой проблемы, который мне не хватает? Или они используют более мощный анализатор, чем стандартный анализатор LL (1) или LALR (1), который способен учитывать уровень пробелов?

4b9b3361

Ответ 1

Отступы обрабатываются двумя "псевдотонами" - INDENT и DEDENT. Здесь представлены некоторые подробности здесь. Для получения дополнительной информации вы должны посмотреть на источник для токенизатора и парсера python.