2017-09-04 7 views
5

は、私はPythonのASTと、この式を再作成したいのですが1行に複数の式のためのPython ASTを生成は簡単

Module(
    body=[ 
     Expr(value=Compare(left=Num(n=1), ops=[Eq()], comparators=[Num(n=2)])), 
     Expr(value=Compare(left=Num(n=1), ops=[GtE()], comparators=[Num(n=2)])) 
    ] 
) 

しかし、上記のAST構造は、1行の2式と2行の式では、それぞれ別々の行で同じです。

私は手動計算することができ、それACシングルライン式にするためにノードのcol_offsetlineno属性を変更しますが、もっと簡単な方法があることを知っていますか?

+1

は、あなたは、ソースコードからAST、またはASTからソースコードを生成しようとしていますか?あなたが持っているASTについて何か不満はありますか? – user2357112

+0

私はコンパイルして実行できるAST構造体を生成しようとしています。 1および2行のバージョン間でコンパイルされたコードに差がある '1 == 2 1> = 2 'はなく1つのライナー – noamt

+0

:私はASTは、同等のものを生成するのだろうか? – rbanffy

答えて

1

コードを直接解析する以外の方法でASTを生成したと仮定します。一つの簡単な解決策は、新しい効果的に等価で取得するには、その文字列に

  • parse()結果
  • を操作するバックPythonコード

  • の文字列に

    1. 変換全部またはASTの部分にあるかもしれません新しいのAST、正確な行番号と列のオフセット。

      たとえば、完全なASTを歩いて、bodyごとに、それをPythonコードに変換し、すべての改行文字をセミコロン(parse())に置き換え、元の本文を結果に置き換えます。

      編集:ここastunparseモジュールを使用して簡単なデモです:

      from ast import * 
      from astunparse import * 
      
      a1 = parse("1 == 2\n1 >= 2") 
      print map(lambda x: (x.lineno, x.col_offset), a1.body) # [(1, 0), (2, 0)] 
      
      a2 = parse(unparse(a1).strip().replace('\n', ';')) 
      print map(lambda x: (x.lineno, x.col_offset), a2.body) # [(1, 0), (1, 9)]