Готовый перевод The Python Language Reference / Справочник по языку Python: 2. Lexical analysis
2. Лексический анализ
Парсер (синтаксический анализатор) выполняет синтаксический анализ программы, написанной на языке программирования Python. В качестве исходных данных парсер получает последовательность лексем (токенов), полученную в результате лексического анализа программы. В этой главе описывается как в процессе лексического анализа происходит распознавание и выделение лексем из исходного текста программы.
Python воспринимает текст программы как набор символов Юникода. Кодировка по умолчанию - UTF-8 (см. PEP 3120), но также может быть выбрана и другая кодировка. Если исходный файл не может быть декодирован, то это приводит к возникновению синтаксической ошибки - SyntaxError.
2.1. Структура строк
Программа на Питоне состоит из условных (логических) строк.
2.1.1. Условные строки
Условные строки состоят из одной или нескольких физических строк, объединённых по правилам явного или неявного объединения (2.1.5. , 2.1.6.). Инструкции не могут пересекать границы условных строк, за исключением специальных случаев, предусмотренных синтаксисом (например, составные инструкции).
2.1.2. Физические строки
Физическая строка - это последовательность символов, которая оканчивается специальными символами, обозначающими конец данной строки. Можно использовать любые стандартные символы конца строки: ASCII LF (Unix-вариант), ASCII CR LF (Windows-вариант), ASCII CR (старый Macintosh-вариант). Все приведённые варианты символов конца строки равноправны для использования независимо от используемой платформы.
При встраивании Питона в другое приложение, строки исходного кода на Питоне следует передавать из этого приложения в API Питона, следуя стандартным соглашениям языка "C" для символов новой строки (тоесть, символ "\n" , обозначающий ASCII LF ).
2.1.3. Комментарии
Комментарий начинается с символа "решётки" (#), который не является строковым литералом, и продолжается до конца строки. Комментарий также обозначает конец логической последовательности, кроме тех случаев, когда происходит неявное объединение логических последовательностей. Комментарии игнорируются при анализе текста программы и не являются лексемами (токенами).
2.1.4. Объявление кодировки
Если комментарий, расположенный в первой или второй строке скрипта, соответствует регулярному выражению coding[=:]\s*([-\w.]+), то при анализе он имеет значение объявления кодировки. Первая часть этого выражения называет кодировку исходного файла. Рекоммендуемыми формами выражения являются:
# -*- coding: -*-
понимаемое также GNU Emacs, и
# vim:fileencoding=
используемое в VIM Брэма Мооленаара (Bram Moolenaar)
Если объявление кодировки отсутствует, кодировкой по умолчанию считается UTF-8. К тому же, если первые байты файла соответствуют отметке байтового порядка UTF-8 (b'\xef\xbb\xbf'), объявленной кодировкой является UTF-8 (поддерживается, например, в Microsoft notepad (блокнот)).
Если кодировка объявлена, ее имя должно быть понято Python. Кодировка используется для лексического анализа, включая строковые литералы, комментрии и идентификаторы. Объявление кодировки должно быть в отдельной строке.
2.1.5. Явное объединение строк
Две или более физических строк могут быть объединены в одну условную строку при помощи символа бэкслэш (\) следующим образом: когда строка заканчивается бэкслэшем, не являющимся частью текстовых данных или комментария, она объединяется со следующей, составляя единую условную строку, не включающую бэкслэш и следующий за ним символ окончания строки. Например:
if 1900 < year < 2100 and 1 <= month <= 12 \
and 1 <= day <= 31 and 0 <= hour < 24 \
and 0 <= minute < 60 and 0 <= second < 60: # похоже ли на дату
return 1
Строка, оканчивающаяся бэкслэшем, не может содержать комментарий. Комментарий или другую лексему кроме текстовых данных, начатые на одной строке, нельзя продолжить с помощью бэкслэша на другой строке. Кроме конца физической строки бэкслэш допустим только внутри текстовых данных.
2.1.6. Неявное объединение строк
Выражения в скобках - круглых, квадратных либо фигурных - могут быть разделены на несколько физических строк без использования бэкслэша. Например:
month_names = ['Januari', 'Februari', 'Maart', # Это голландские
'April', 'Mei', 'Juni', # названия
'Juli', 'Augustus', 'September', # месяцев
'Oktober', 'November', 'December'] # года
Неявно продолженные строки могут содержать комментарии. Отступы не играют роли в продолженных строках. При продолжении разрешены пустые строки. Токена NEWLINE нет в неявно продолженных строках. Строки в тройных скобках (см. ниже) также могут быть неявно продолженными, в этом случае они не могут содержать комментарий.
2.1.7. Пустые строки
Условные строки, содержащие только пробелы, знаки табуляции или перевода страницы и комментарии игнорируется (т.е. не создается лексемы NEWLINE). Во время интерактивного ввода операторов обработка пустой последовательности может отличаться в зависимости от реализации цикла чтение-вычисление-вывод. В стандартном интерактивном интерпретаторе полностью пустая условная строка (т.е. не содержащая даже пробел или комментарий) завершает многострочный оператор.
2.1.8. Отступы
Знаки пробела и табуляции начинающие логическую строку используются для вычисления уровня отступа строки, который, в свою очередь, определяет группировку операторов.
Знаки табуляции заменяются (слева напрво) по одному на восемь пробелов так, что общее число символов после замены кратно восьми (здесь использовано то же правило, что и в Unix). Общее число знаков перед первым непустым символом определяет отступ строки. Отступ не может быть разделен между многими физическими строками с помощью бэкслеша; знаки пробела и табуляции до первого бэкслеша определяют отступ.
Отступы не принимаются из-за противоречивости, если исходный файл смешивает табуляции и пробелы таким образом, что делает смысл зависящим от размера табуляции в пробелах; в таком случае генерируется «TabError» .
Замечание о кроссплатформенной совместимости: из-за особенностей текстовых редакторов на не-UNIX платформах - не следует использовать смесь пробелов и табуляций для отступов в одном исодном файле. Также следует отметить, что различные платформы могут явно ограничивать максимальный уровень отступов.
Символ перевода страницы может находится в начале строки, тогда он игнорируется при расчете отступов. В любом другом месте символ перевода страницы между пробелами в начале строки может обрабатываться неопределенным образом (например, может сбрасывать счетчик предыдущих пробелов до нуля).
Уровни отступа строк используются для создания токенов INDENT (отступ) и DEDENT (конец отступа) при помощи стека, как описано ниже.
Перед чтением первой строки файла в стек записывается значение «0», это значение никогда не будет извлечено. Числа, заносимые в стек, будут строго возрастать. В начале каждой условной строки уровень отступа сравнивается с максимальным значением на верху стека; если они равны, то ничего не происходит. Если уровень отступа больше, то он заносится в стек, и создается одна лексема «INDENT». Если уровень меньше, то это число уже должно быть в стеке; все числа, которые больше, удаляются, и для каждого удаленного числа создается лексема «DEDENT» . В конце файла лексемы «DEDENT» создаются для всех оставшихся в стеке чисел больше нуля.
Здесь приведен пример Python кода с правильно (но странновато) расставленными отступами:
def perm(l):
# Расчет списка всех перестановок l
if len(l) <= 1:
return [l]
r = []
for i in range(len(l)):
s = l[:i] + l[i+1:]
p = perm(s)
for x in p:
r.append(l[i:i+1] + x)
return r
Следующий пример показывает различные ошибки в отступах:
def perm(l): # Ошибка: отступ первой строки
for i in range(len(l)): # Ошибка: без отступа
s = l[:i] + l[i+1:]
p = perm(l[:i] + l[i+1:]) # Ошибка: неожиданный отступ
for x in p:
r.append(l[i:i+1] + x)
return r # Ошибка: несогласованный отступ
(Вообще-то, первые три ошибки найдены парсером, и только последняя - лексическим анализатором: уровень отступа return r не совпадает с уровнем в стеке.)
2.1.9. Пробелы между лексемами
Кроме начала логической строки или в записи текстовых данных символы пробела, табуляции и перевода страницы могут быть взаимозаменяемы при разделении лексем. Эти символы необходимы между двумя лексемами только, если результат их объединения может быть интерпретирован как другая лексема (например : «ab» - это одна лексема, но «a b» - две лексемы) .
2.2. Другие лексемы
Кроме «NEWLINE» , «INDENT» и «DEDENT» , существуют следующие категории лексем: идентификаторы, ключевые слова, литералы (непосредственная запись данных) , операторы и разделители. Символы пробелов (кроме знаков конца строки, описанных ранее) не являются лексемами, а служат для их разделения. Если появляется неопределенность, лексема включает самую длинную возможную последовательность, представляющую собой действительную лексему (чтение происходит слева направо) .
2.3. Идентификаторы и ключевые слова
Идентификаторы (имена) имеют следующее лексическое определение.
Синтаксис идентификаторов в Питоне основывается на приложении «UAX-31» к стандарту «Unicode» , с переработкой и изменениями описанными ниже. Также смотрите дополнительные детали в «PEP 3131» .
В ASCII диапазоне (U+0001..U+007F) в идентификаторах допустимы только те же символы, что и в Питоне 2.x : буквы от «A» до «Z» в верхнем и нижнем регистре, подчеркивание «_» и, кроме первого символа идентификатора, – цифры от «0» до «9» .
В Python 3.0 представлены дополнительные символы, не входящие в ASCII диапазон (см. PEP 3131). Для этих символов использована классификация из версии базы символов Unicode (Unicode Character Database), включенная в модуль unicodedata.
Идентификаторы не ограничены по длине и чувствительны к регистру.
identifier ::= id_start id_continue*
id_start ::= < все символы в общих категориях Lu, Ll, Lt, Lm, Lo, Nl, подчёркивание, и символы со свойством Other_ID_Start >
id_continue ::= < все символы в id_start, плюс символы в категориях Mn, Mc, Nd, Pc и другие символы со свойством Other_ID_Continue >
Использованные выше обозначения категорий Юникода :
* Lu - буквы в верхнем регистре
* Ll - буквы в нижнем регистре
* Lt - Заглавные буквы
* Lm - модифицирующие символы
* Lo - другие буквы
* Nl - буквенные числа
* Mn - непробельные знаки
* Mc - пробельные составные знаки
* Nd - десятичные цифры
* Pc - пунктуационные знаки
Все идентификаторы при лексическом разборе конвертируются в нормализованную форму NFC; и сравнение идентификаторов производится уже в форме NFC.
Ненормативный HTML файл со списком всех символов Юникода 4.1 , доступных для использования в идентификаторах, представлен здесь: http://www.dcl.hpi.uni-potsdam.de/home/loewis/table-3131.html.
2.3.1. Ключевые слова
Следующие идентификаторы являются зарезервированными или ключевыми словами языка и не могут быть использованы как обычные идентификаторы. Они должны быть написаны именно так, как здесь:
False class finally is return
None continue for lambda try
True def from nonlocal while
and del global not with
as elif if or yield
assert else import pass
break except in raise
2.3.2. Зарезервированные классы идентификаторов
Определенные классы идентификаторов (помимо ключевых слов) имеют особое значение. Эти классы определяются соответствующей комбинацией символов подчеркивания в начале и в конце.
_*
Не импортируются инструкцией «from module import *» . Специальный идентификатор «_» используется интерактивным интерпретатором для хранения результата последнего вычисления, хранится он в модуле «builtins» . Не в интерактивном режиме «_» не имеет специального значения, не определен. (Смотрите раздел «Объявление импорта» ) .
Примечание:
Имя «_» часто используется в связи с интернационализацией, смотрите документацию модуля «gettext» для получения информации по этой договоренности.
«__*__»
Определенные системой имена. Эти имена определяются интерпретатором и его реализацией (включая стандартную библиотеку). Приложения не должны определять дополнительные имена используя эту форму. Набор имен этого класса, определенных в Питоне, может быть расширен в будущих версиях. Смотрите раздел «Имена специальных методов» .
«__*»
Частные имена класса. Имена этой категории, при использовании в рамках определения класса, автоматически модифицируются, чтобы избежать конфликтов имен между «частными» атрибутами базовых и производных классов. Смотрите в разделе «Идентификаторы (Имена)».
2.4. «Литералы»
«Литералы» - это непосредственная запись постоянных значений некоторых встроенных типов данных.
2.4.1. Текстовые («String») и байтовые («Bytes») «литералы»
Непосредственная запись текстовых данных имеет следующее лексическое определение:
stringliteral ::= [stringprefix](shortstring | longstring)
stringprefix ::= "r" | "R"
shortstring ::= "'" shortstringitem* "'" | '"' shortstringitem* '"'
longstring ::= "'''" longstringitem* "'''" | '"""' longstringitem* '"""'
shortstringitem ::= shortstringchar | stringescapeseq
longstringitem ::= longstringchar | stringescapeseq
shortstringchar ::= <любой символ программы, кроме "\" или newline или закрывающей кавычки>
longstringchar ::= <любой символ программы, кроме "\">
stringescapeseq ::= "\" <любой символ программы>
bytesliteral ::= bytesprefix(shortbytes | longbytes)
bytesprefix ::= "b" | "B" | "br" | "Br" | "bR" | "BR"
shortbytes ::= "'" shortbytesitem* "'" | '"' shortbytesitem* '"'
longbytes ::= "'''" longbytesitem* "'''" | '"""' longbytesitem* '"""'
shortbytesitem ::= shortbyteschar | bytesescapeseq
longbytesitem ::= longbyteschar | bytesescapeseq
shortbyteschar ::= <любой символ ASCII, кроме "\" или newline или закрывающей кавычки>
longbyteschar ::= <любой символ ASCII, кроме "\">
bytesescapeseq ::= "\" <любой символ ASCII>
Есть также одно синтаксическое ограничение, не отмеченное в этих определениях: знаки пробелов (пробела, табуляции, перевода страницы) не могут находится между строковым или байтовым префиксом и остальной частью «литерала» . Набор символов кода программы определяется объявлением кодировки, по умолчанию: UTF-8, смотрите раздел «Объявление кодировки» .
Говоря проще : оба типа «литералов» обрамляются с двух сторон одинаковыми кавычками : или по одной одинарной «'» , или по одной двойной «"» , или по три одинарных «'''» , или по три двойных «"""» (утроенные кавычки) . Символ бэкслэш «\» используется для «экранирования» (вставки в качестве простых печатных) символов, которые в других случаях имеют особое значение, такие как знак новой строки, сам бэкслэш или кавычки.
Строковые литералы могут опционально начинаться с букв «r» или «R» ; такие строки называются «сырыми» («raw»), и считают бэкслэш обычным символом.
В результате последовательности «\U» и «\u» специального значения в «сырых» строках не имеют.
Байтовым «литералам» должен предшествовать префикс «b» или «B» . Они создают экземпляр типа «bytes» вместо типа «str» . Этот тип может содержать только символы ASCII; байты с численным значением больше 127 записываются с помощью особых последовательностей символов.
В текстовых данных в утроенных кавычках – могут присутствовать (и сохраняются как есть) «неэкранированные» знаки новой строки и кавычки (не в виде специальных последовательностей) , кроме трех «неэкранированных» кавычек подряд (того же вида, как и открывавшие), которые завершают запись текста.
Если нет префикса «r» или «R» , специальные последовательности в строках интерпретируются согласно правилам стандартного «C» . Опознаются следующие специальные последовательности:
Escape Sequence Meaning Notes
\newline Игнорируется бэкслеш и newline
\\ Бэкслеш (\)
\' Одинарная кавычка (')
\" Двойная кавычка (")
\a ASCII Bell (BEL)
\b ASCII Backspace (BS)
\f ASCII Formfeed (FF)
\n ASCII Linefeed (LF)
\r ASCII Carriage Return (CR)
\t ASCII Horizontal Tab (TAB)
\v ASCII Vertical Tab (VT)
\ooo Символ с восьмиричным значением ooo (1,3)
\xhh Символ с 16-ричным значением hh (2,3)
Последовательности экранирования для строковых литералов:
Escape Sequence Meaning Notes
\N{name} Символ с именем name в базе Unicode
\uxxxx Символ с 16-битным hex значением xxxx (4)
\Uxxxxxxxx Символ с 32-битным hex значением xxxxxxxx (5)
Примечания:
1. Как и в стандартном «C» , принимается до трех восьмеричных знаков.
2. В отличие от стандартного «C» , принимается строго два 16-ричных знака.
3. В байтовых данных 16- и 8-ричные специальные последовательности обозначают байт с данным значением. В текстовых данных они обозначают символ Юникода с данным кодом.
4. Отдельные коды, составляющие части суррогатной пары, могут быть закодированы при помощи специальных последовательностей. В отличие от стандартного «C» , требуется строго два 16-ричных знака.
5. Этим способом могут быть закодированы любые символы Юникода, но символы вне «Basic Multilingual Plane» (BMP) будут закодированы с помощью суррогатной пары, если Питон скомпилирован под использование 16-битных элементов кода Юникод (по умолчанию). Отдельные коды, составляющие части суррогатной пары, могут быть закодированы при помощи специальных последовательностей.
В отличие от стандартного «C», все неопознанные последовательности символов оставляются в тексте неизменными, т. е. бэкслэш остается в тексте. (Такое поведение полезно при отладке: если особая последовательность символов написана неправильно, то в том, что появляется на выходе легче заметить ошибку.) Кроме того, важно отметить, что управляющие последовательности опознающиеся только в записи текста попадают в категорию неопознанных последовательностей в записи байтовых данных.
Даже в «сыром» тексте кавычки могут быть вставлены через бэкслэш, но бэкслэш остается в строке, например, «r"\""»является верной текстовой записью, состоящей из двух символов: бэкслэш и двойные кавычки; «r"\"» не является допустимой записью (даже «сырой» текст не может заканчиваться нечётным количеством бэкслэшей). В частности, «сырой» текст не может оканчиваться одним бэкслэшем (поскольку бэкслэш превращает следующую за ним кавычку в текст). Отметьте также, что один бэкслэш подряд, за которым сразу следует переход на новую строку интерпретируется как эти два символа, являющиеся частью строки, а не как продолжение строки.
2.4.2. Соединение текстовых записей (литералов)
Допустимы несколько идущих подряд текстовых записей, разделённых пробелами (возможно, с использованием разных типов пар кавычек) - их значение эквивалентно значению одной текстовой записи, являющейся их соединением. Таким образом, "hello" 'world' эквивалентно "helloworld". Эта особенность позволяет уменьшать количество необходимых бэкслэшей, удобно разделять длинные тексты на много физических строк, или даже добавлять комментарии к отдельным фрагментам текста, например:
re.compile("[A-Za-z_]" # буква или подчёркивание
"[A-Za-z0-9_]*" # буква, цифра или подчёркивание
)
Обратите внимание, что это свойство определено на синтаксическом уровне, но реализуется во время компиляции. Для соединения фрагментов текста во время исполнения – должен использоваться оператор «+» . Заметьте также, что при соединении текста могут использоваться различные стили оформления для каждого фрагмента (даже смешивание «сырого» текста и в тройных кавычках) .
2.4.3. Непосредственная запись чисел
Существуют три формы непосредственной записи для чисел: целых, чисел с плавающей точкой, и мнимых чисел. Не существует непосредственной записи для комплексных чисел (они могут быть сформированы через операцию сложения действительного числа с мнимым).
Заметьте, что знак не является частью записи числа - такая формулировка, как «-1» , на самом деле является выражением, состоящим из унарного оператора «-» и числа «1» .
2.4.4. Запись целых чисел
Запись целых чисел имеет следующее лексическое определение:
integer ::= decimalinteger | octinteger | hexinteger | bininteger
decimalinteger ::= nonzerodigit digit* | "0"+
nonzerodigit ::= "1"..."9"
digit ::= "0"..."9"
octinteger ::= "0" ("o" | "O") octdigit+
hexinteger ::= "0" ("x" | "X") hexdigit+
bininteger ::= "0" ("b" | "B") bindigit+
octdigit ::= "0"..."7"
hexdigit ::= digit | "a"..."f" | "A"..."F"
bindigit ::= "0" | "1"
Нет ограничения длины записи числа, кроме размера доступной памяти.
Обратите внимание, что нули в начале ненулевого десятичного числа не допускаются. Это сделано для отличения их от восьмеричной записи в стиле «C» , которая использовалась в Питоне до версии 3.0 .
Некоторые примеры записи целых чисел:
7 2147483647 0o177 0b100110111
3 79228162514264337593543950336 0o377 0x100000000
79228162514264337593543950336 0xdeadbeef
2.4.5. Запись дробных чисел (с плавающей запятой)
Запись дробных чисел имеет следующее лексическое определение:
floatnumber ::= pointfloat | exponentfloat
pointfloat ::= [intpart] fraction | intpart "."
exponentfloat ::= (intpart | pointfloat) exponent
intpart ::= digit+
fraction ::= "." digit+
exponent ::= ("e" | "E") ["+" | "-"] digit+
Заметьте, что в целой и экспонентной частях всегда подразумевается основание 10 . Например, 077e010 является допустимым и значит то же, что и 77e10 . Допустимый диапазон дробных чисел может различаться в разных реализациях. Примеры записи дробных чисел:
3.14 10. .001 1e100 3.14e-10 0e0
Заметьте, что знак не является частью записи числа - такая формулировка, как «-1» , на самом деле является выражением, состоящим из унарного оператора «-» и числа «1» .
2.4.6. Запись мнимых чисел
Запись мнимых чисел имеет следующее лексическое определение:
imagnumber ::= (floatnumber | intpart) ("j" | "J")
Под мнимое число отводится комплексное число с действительной частью «0» . Комплексные числа представлены в виде пары чисел с плавающей точкой, которые имеют обычные ограничения диапазона их значений. Чтобы создать комплексное число с ненулевой действительной частью, нужно сложить обычное дробное число с мнимым числом, например, «(3 + 4j)» . Некоторые примеры записи мнимых чисел:
3.14j 10.j 10j .001j 1e100j 3.14e-10j
2.5. Операторы
Следующие лексемы являются операторами:
+ - * ** / // %
<< >> & | ^ ~
< > <= >= == !=
2.6. Разделители
Следующие лексемы выполняют роль грамматических разделителей:
( ) [ ] { }
, : . ; @ =
+= -= *= /= //= %=
&= |= ^= >>= <<= **=
Точка также встречается в записи дробных и мнимых чисел. Последовательность из трех точек имеет особое значение - обозначение пропуска («ellipsis»), вторая половина списка, расширенная операция присваивания, служит в качестве лексического разделителя, и кроме этого выполняет операцию.
Следующие печатные символы ASCII имеют особое значение как часть других лексем, и, таким образом, важны для лексического анализатора:
' " # \
Следующие печатные символы ASCII не используются в Питоне. Их появление за пределами записи текстовых данных или комментариев безусловно является ошибкой:
$ ?
Внимание! Этот перевод, возможно, ещё не готов.
Его статус: перевод редактируется
Переведено на Нотабеноиде
http://notabenoid.org/book/5672/17126
Переводчики: Hittih, vanderloos, simba87
Настройки
Готово:
