« 日記 |Main| Just Another Python Hacker, その3 »

« Pythonでワンライナーを作成する際のノウハウ集 | Python | Just Another Python Hacker, その3 »

Pythonの構文木を見る

ワンライナーから不要な空白文字を取り除くスクリプトを作ったのですが、「取り除いてパースに成功するなら取り除いてOK」とやってしまったので文字列の中の空白まで取り除かれてしまいました。そこできちんと構文木を眺めてみることにしました。love unstable: Pythonの構文木を見るを参考に。

import parser, symbol, pprint, token
def change(ast):
    if type(ast) is list:
        return map(change, ast)
    else:
        leaf = symbol.sym_name.get(ast, ast)
        return token.tok_name.get(leaf, leaf)
parse = lambda s: change(parser.ast2list(parser.expr(s)))

pprint.pprint(parse("('1 1'       * 2)   + (3 - 4)"))

これで出力は

['eval_input',
 ['testlist',
  ['test',
   ['and_test',
    ['not_test',
     ['comparison',
      ['expr',
       ['xor_expr',
        ['and_expr',
         ['shift_expr',
          ['arith_expr',
           ['term',
            ['factor',
             ['power',
              ['atom',
               ['LPAR', '('],
               ['testlist_gexp',
                ['test',
                 ['and_test',
                  ['not_test',
                   ['comparison',
                    ['expr',
                     ['xor_expr',
                      ['and_expr',
                       ['shift_expr',
                        ['arith_expr',
                         ['term',
                          ['factor',
                           ['power',
                            ['atom',
                             ['STRING', "'1 1'"]]]],
                          ['STAR', '*'],
                          ['factor',
                           ['power',
                            ['atom',
                             ['NUMBER', '2']]]]]]]]]]]]]]],
               ['RPAR', ')']]]],
            ['STAR', '*'],
            ['factor', ['power', ['atom', ['NAME', 'x']]]]],
           ['PLUS', '+'],
           ['term',
            ['factor',
             ['power',
              ['atom',
               ['LPAR', '('],
               ['testlist_gexp',
                ['test',
                 ['and_test',
                  ['not_test',
                   ['comparison',
                    ['expr',
                     ['xor_expr',
                      ['and_expr',
                       ['shift_expr',
                        ['arith_expr',
                         ['term',
                          ['factor',
                           ['power',
                            ['atom',
                             ['NUMBER', '3']]]]],
                         ['MINUS', '-'],
                         ['term',
                          ['factor',
                           ['power',
                            ['atom',
                             ['NUMBER', '4']]]]]]]]]]]]]]],
               ['RPAR', ')']]]]]]]]]]]]]]],
 ['NEWLINE', ''],
 ['ENDMARKER', '']]

当たり前ですが、文字列の中の空白は残って、トークンの間の空白は消えていますね。後はNAME、NUMBERなどが隣接するときには空白を挟み、RPAR(括弧)などは空白を挟まないでトークンを結合してやれば目的は果たせるでしょうかね…?

トラックバック(Trackback)

Trackback URL: http://www.nishiohirokazu.org/mt/mt-tb.cgi/241

ご意見・ご感想をお送りください(フィードバック)

(フィードバックはメールで送信され、基本的に表示されませんが、内容によっては公開させていただくこともございます。ご了承ください。Your comment doesn't appear the page immediately. If the comment has value to other people, it will be put on the page or subsequent entries. Thank you.)

上の情報は、いずれも未記入でかまいません。 All of above questions are optional.