×
Traktatov.net » Язык программирования Python » Читать онлайн
Страница 131 из 141 Настройки

Ссылки

Библиотека Boost Python для C++ http://www.boost.org

14. Лекция: Устройство интерпретатора языка Python.

В этой лекции сделана попытка пролить свет на внутреннее устройство интерпретатора Python. Для иллюстрации работы интерпретатора рассматриваются отладчик, профайлер и «дизассемблер».

Лексический анализ

Лексический анализатор языка программирования разбивает исходный текст программы (состоящий из одиночных символов) на лексемы — неделимые «слова» языка.

Основные категории лексем Python: идентификаторы и ключевые слова (NAME), литералы (STRING, NUMBER и т.п.), операции (OP), разделители, специальные лексемы для обозначения (изменения) отступов (INDENT, DEDENT) и концов строк (NEWLINE), а также комментарии (COMMENT). Лексический анализатор доступен через модуль >tokenize, а определения кодов лексем содержатся в модуле >token стандартной библиотеки Python. Следующий пример показывает лексический анализатор в действии:

>import StringIO, token, tokenize


>prog_example = """

>for i in range(100): # comment

> if i % 1 == 0: \

> print ":", t**2

>""".strip()


>rl = StringIO.StringIO(prog_example).readline


>for t_type, t_str, (br,bc), (er,ec), logl in tokenize.generate_tokens(rl):

> print "%3i %10s : %20r" % (t_type, token.tok_name[t_type], t_str)

А вот что выведет эта программа, разбив на лексемы исходный код примера:

>prog_example:

> 1      NAME :       'for'

> 1      NAME :         'i'

> 1      NAME :        'in'

> 1      NAME :     'range'

>50        OP :         '('

> 2    NUMBER :       '100'

>50        OP :         ')'

>50        OP :         ':'

>52   COMMENT : '# comment'

> 4   NEWLINE :        '\n'

> 5    INDENT :         ' '

> 1      NAME :        'if'

> 1      NAME :         'i'

>50        OP :         '%'

> 2    NUMBER :         '1'

>50        OP :        '=='

> 2    NUMBER :         '0'

>50        OP :         ':'

> 1      NAME :     'print'

> 3    STRING :       '":"'

>50        OP :         ','

> 1      NAME :         't'

>50        OP :        '**'

> 2    NUMBER :         '2'

> 6    DEDENT :          ''

> 0 ENDMARKER :          ''

Фактически получен поток лексем, который может использоваться для различных целей. Например, для синтаксического «окрашивания» кода на языке Python. Словарь >token.tok_name позволяет получить мнемонические имена для типа лексемы по номеру.

Синтаксический анализ

Вторая стадия преобразования исходного текста программы в байт-код интерпретатора состоит в синтаксическом анализе исходного текста. Модуль >parser содержит функции >suite() и >expr() для построения деревьев синтаксического разбора соответственно для кода программ и выражений Python. Модуль >symbol содержит номера символов грамматики Python, словарь для получения названия символа из грамматики Python.

Следующая программа анализирует достаточно простой код Python (>prg) и порождает дерево синтаксического разбора (AST–объект), который тут же можно превращать в кортеж и красиво выводить функцией >pprint.pprint(). Далее определяется функция для превращения номеров символов в их мнемонические обозначения (имена) в грамматике:

>import pprint, token, parser, symbol