Ссылки
Библиотека 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