1

私はpythonとpyparsingでファイルを解析しています(これはMatlabのPSATのレポートファイルですが、それは重要ではありません)。これが私がこれまでに持っているものです。混乱していると思いますので、改善方法についてアドバイスをお願いします。具体的には、文法定義をpyparsingでどのように整理する必要がありますか?

すべての文法定義を1つの関数に含める必要がありますか?もしそうなら、それは一つの巨大な機能になるでしょう。そうでない場合は、どうすれば分割できますか。現時点では、ファイルのセクションで分割しています。1つの場所から一度だけ呼び出される関数をたくさん作成する価値はありますか。どちらも私には本当に正しいとは感じません。

すべての入力コードと出力コードを他のクラス関数とは別のファイルに配置する必要がありますか?それはクラスの目的をより明確にするでしょう。

また、ファイルを解析し、健全性チェックを実行してデータをクラスに格納する簡単な方法があるかどうかを知りたいと思います。私はこれをするのに多くの時間を費やしているようです。

(私はそれで十分だという答えを受け入れるか、人々が同意する場合はpyparsingではなくXを使用します)

4

1 に答える 1

2

単一の大きな方法を使用してパーサーを作成する方法と、現在の方法で段階的に使用する方法のどちらでも構いません。

スリット (「サプレス リテラル」だと思います)、stringtolits、decimaltable などの便利なヘルパー ユーティリティがいくつか定義されていることがわかります。これは私には良さそうです。

結果名を使用していることが気に入っています。これにより、解析後のコードの堅牢性が大幅に向上します。pyparsing 1.4.7 で追加されたショートカット フォームを使用することをお勧めします。

busname.setResultsName("bus1")

busname("bus1")

これにより、コードがかなり整理されます。

解析アクションを振り返って、個々のトークンにアクセスするために数値インデックスを使用している場所を確認し、戻って代わりに結果の名前を割り当てます。GetStats が を返す 1 つのケースを次に示します(ngroup + sgroup).setParseAction(self.process_stats)。process_stats には次のような参照があります。

self.num_load = tokens[0]["loads"]
self.num_generator = tokens[0]["generators"]
self.num_transformer = tokens[0]["transformers"]
self.num_line = tokens[0]["lines"]
self.num_bus = tokens[0]["buses"]
self.power_rate = tokens[1]["rate"]

値と統計がグループ化されていることを気に入っていますが、「network」や「soln」などの名前を付けてください。次に、この解析アクション コードを次のように記述できます (dict 要素表記の代わりに、読みやすいオブジェクト属性表記にも変換しました)。

self.num_load = tokens.network.loads
self.num_generator = tokens.network.generators
self.num_transformer = tokens.network.transformers
self.num_line = tokens.network.lines
self.num_bus = tokens.network.buses
self.power_rate = tokens.soln.rate

また、スタイルに関する質問: 「+」演算子を使用する代わりに明示的な And コンストラクターを使用することがあるのはなぜですか?

busdef = And([busname.setResultsName("bus1"),
            busname.setResultsName("bus2"),
            integer.setResultsName("linenum"),
            decimaltable("pf qf pl ql".split())])

これは簡単に書かれています:

busdef = (busname("bus1") + busname("bus2") + 
            integer("linenum") + 
            decimaltable("pf qf pl ql".split()))

全体として、これはこの複雑さのファイルとほぼ同等だと思います。私はあなたが持っているのと同じようにコードを断片的に構築した同様のフォーマットを持っています(残念ながら独自のものなので共有できません)が、1つの大きなメソッドでは、次のようなものです:

def parser():
    header = Group(...)
    inputsummary = Group(...)
    jobstats = Group(...)
    measurements = Group(...)
    return header("hdr") + inputsummary("inputs") + jobstats("stats") + measurements("meas")

Group コンストラクトは、解析されたデータの各セクション内で結果名の一種の名前空間を確立するために、このような大規模なパーサーで特に役立ちます。

于 2009-12-08T14:29:02.827 に答える