Как парсеры Python справляются с отступами? - PullRequest
22 голосов
/ 21 июня 2011

При синтаксическом анализе языка произвольной формы, такого как 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), который может учитывать уровень пробелов?

1 Ответ

21 голосов
/ 21 июня 2011

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

...