2017-12-07 22 views
-2

グローバル変数の存在を確認するロジックを含むbashスクリプトに対して一連のPythonソースコードを実行する必要があります。awk、sed、またはgrepを使ってソースコード内のグローバル変数をチェックする方法は?

read file line by line 
if there is an '=' (assignment sign) in the line AND no '#' in beginning of line (it is not commented out), check: 
    is there a 'def' string anywhere in the text above this assignment line, e.g. def function_name()? 
     if yes, variable within a function and hence not global 
     else, possible global variable 

どのように私はgrepawk、またはsedを使用して、この擬似コードを実装するのですか。私は、変数がグローバルであるかどうかを確認するために使用できる2つの基準はありますか?私は、bashスクリプトでグローバル変数を見つけるためのより良い戦略に関する提案にも触れています。

コード例:このコードは、私たちのテストに失敗した

int a = 23 

def func_name(): 
    ...body... 

コード例2:

def function_name(): 
    int a = 4 
    ... 

このコードは、試験に合格します。

+0

質問をより具体的にする2つの例を追加しました。 – learnerX

+4

Pythonのソースコードを解析するために、行指向のツールを使用すると、Pythonで書かれた良いPythonのソースコードアナライザがあると、誤って指示されているようです。 – tripleee

+2

可能な複製https://stackoverflow.com/questions/33160744/detect-all-global-variables-within-a-python-function – tripleee

答えて

0

私はこれは良いアイデアだと思いますが、ここではあなたのロジックの文字通りの実装ですありません。

awk -F= ' 
    /^[^#]/ && NF > 1 && saw_def { print "not global:", $0; next } 
    NF > 1 { print "possibly global:", $0 } 
    { saw_def = /def/ } 
' file.py 

これは4 pattern {action}ペアのフィールドセパレータとして=を使用するためにはawkに指示します:

  1. 行は非#で始まり、2番目のフィールド(したがって、=)を持ち、saw_def変数が設定されます。
    行をグローバル割り当てとして出力します。おそらくグローバル割り当て
  2. (#1にマッチしない任意の行)として
    印刷ライン:
    セットsaw_def "か否かを示すブール値のラインが他=を有する
  3. 次のライン(ストップパターンマッチング)に移動DEF」ここの行に

が存在するテストを失敗する例です。

def function_name(): 
    int a = 4 
    int b = 8 

あなたが要求したロジックがaがnであることに注意しますグローバルであり、bはおそらくグローバルです。


これは良いはずです:

awk ' 
    NF == 0 { next } 
    { 
    indent = match ($0, /[^ \t]/) - 1 # count of leading whitespace 
    has_assign = /^[^#]*=/ 
    } 
    $1 == "def" && !in_def { in_def = indent; next } 
    indent > in_def && has_assign { print "not global:", $0; next } 
    indent <= in_def { in_def = 0 } 
    has_assign { print "possibly global:", $0 } 
' file.py 

これは、あなたが関数定義にいるときを追跡するために、言語の必須インデントを利用して、Pythonのコードを解析しようとします。5 pattern {action}ペアは次のとおりです:

  1. ませフィールド(空白行):最初の
    を設定する前に先頭のスペースとタブの数に
    設定indent
    は、次の行
  2. (他のラインと一致)にスキップ
    ind_defを使用して、現在のインデントレベルを追跡し、ためにマッチング停止:変数の代入(=がどの#前に存在している)
  3. 最初のフィールドは「DEF」であり、我々はすでに機能を追跡していないがあるかどうかにhas_assignこのライン
  4. 私たちは、関数内であることが十分にインデントしていると我々は割り当てがあります。
    レポート
  5. インデントレベルが最後の関数以下である非グローバル変数の代入:
    を私たちはしていませんよ、任意のより多くの機能私たちは、変数の代入を持っている(そしてnextはまだトリガされていない)ゼロ
  6. に戻す機能のインデントレベルを設定します。
    レポートおそらく、グローバル変数の代入

注、私はないんだけどawkのすべてのバージョンが01を理解していることを確認してくださいですので、その場所にリテラルタブが必要な場合があります。これをコマンドラインでのCtrl + v,タブと入力することができます。


⚠私はまだ自家製Pythonのパーサは良いアイデアだとは思いません。あなたが実際に有効な(そして既知の安全な)Pythonコードを解析しているのであれば、this similar questionは実際にはのロードのコードを返答しています。潜在的に安全でないコードやPythonのようなコードを扱っている場合や、使用しているシステムでPythonインタプリタが不足している場合、私の解決策はコードの素早い確認に役立つかもしれません。

関連する問題