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


>prg = """print 2*2"""


>pprint.pprint(parser.suite(prg).totuple())


>def pprint_ast(ast, level=0):

> if type(ast) == type(()):

>  for a in ast:

>   pprint_ast(a, level+1)

> elif type(ast) == type(""):

>  print repr(ast)

> else:

>  print " "*level,

>  try:

>   print symbol.sym_name[ast]

>  except:

>   print "token."+token.tok_name[ast],


>print

>pprint_ast(parser.suite(prg).totuple())

Эта программа выведет следующее (структура дерева отражена отступами):

>(257,

> (264,

>  (265,

>   (266,

>    (269,

>     (1, 'print'),

>      (292,

>       (293,

>        (294,

>         (295,

>          (297,

>           (298,

>            (299,

>             (300,

>              (301,

>               (302,

>                (303, (304, (305, (2, '2')))),

>                (16, '*'),

>                (303, (304, (305, (2, '2')))))))))))))))),

>  (4, ''))),

>  (0, ''))


>   file_input

>    stmt

>     simple_stmt

>      small_stmt

>       print_stmt

>        token.NAME 'print'

>         test

>          and_test

>           not_test

>            comparison

>             expr

>              xor_expr

>               and_expr

>                shift_expr

>                 arith_expr

>                  term

>                   factor

>                    power

>                     atom

>                      token.NUMBER '2'

>                  token.STAR '*'

>                  factor

>                   power

>                    atom

>                     token.NUMBER '2'

>      token.NEWLINE ''

>    token.ENDMARKER ''

Получение байт-кода

После того как получено дерево синтаксического разбора, компилятор должен превратить его в байт-код, подходящий для исполнения интерпретатором. В следующей программе проводятся отдельно синтаксический анализ, компиляция и выполнение (вычисление) кода (и выражения) в языке Python:

>import parser


>prg = """print 2*2"""

>ast = parser.suite(prg)

>code = ast.compile('filename.py')

>exec code


>prg = """2*2"""

>ast = parser.expr(prg)

>code = ast.compile('filename1.py')

>print eval(code)

Функция >parser.suite() (или >parser.expr()) возвращает AST–объект (дерево синтаксического анализа), которое методом >compile() компилируется в Python байт-код и сохраняется в кодовом объекте >code. Теперь этот код можно выполнить (или, в случае выражения — вычислить) с помощью оператора >exec (или функции >eval()).

Здесь необходимо заметить, что недавно в Python появился пакет >compiler, который объединяет модули для работы анализа исходного кода на Python и генерации кода. В данной лекции он не рассматривается, но те, кто хочет глубже изучить эти процессы, может обратиться к документации по Python.

Изучение байт-кода

Для изучения байт-кода Python–программы можно использовать модуль >dis (сокращение от «дизассемблер»), который содержит функции, позволяющие увидеть байт-код в мнемоническом виде. Следующий пример иллюстрирует эту возможность:

>>>> def f():

>... print 2*2

>...

>>>> dis.dis(f)

> 2  0 LOAD_CONST      1 (2)

>    3 LOAD_CONST      1 (2)

>    6 BINARY_MULTIPLY

>    7 PRINT_ITEM

>    8 PRINT_NEWLINE

>    9 LOAD_CONST      0 (None)

>   12 RETURN_VALUE

Определяется функция >f(), которая должна вычислить и напечатать значение выражения >2*2. Функция