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

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

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

import pprint, token, parser, symbol

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 ''