2012-09-28 23 views
6

私はPythonの卵としてパッケージ化したコマンドラインアプリケーションでPLYを使用しています。これはpip経由でインストールされます。PLYのテーブル再生成を防ぐ方法

"Generating LALR tables" 

はさらに、parser.outとparsetab.pyファイルはスクリプトが起動されたディレクトリに書き込まれます。毎回私は、私は、次のメッセージが表示され、コマンドラインから私のスクリプトを実行します。これらのファイルをアプリケーションと共に出荷して、いつでもテーブルを再生成しないようにする方法はありますか?

+0

「ply」でこれを実行できるかどうかわかりません。使用するファイル名やディレクトリを変更することも、テーブルを常に再生成することもできます(文法のサイズによってはオプションではない可能性があります)。しかし、生成されたパーサーテーブルを出荷する...知らない。 :/ – elias

答えて

0

私が最終的に巻き終わったのは、最適化を止めることでした。私はPLY 3.4のソースを通過して、私は、字句解析コードでは、この小さなナゲットが見つかりました:

self.lexer = lex.lex(module=self, optimize=False, debug=False, **kwargs)

:へのレクサーとパーサを構築するコードを変更することにより

# If in optimize mode, we write the lextab 
if lextab and optimize: 
    lexobj.writetab(lextab,outputdir) 

return lexobj 

self.lexer = lex.lex(module=self, optimize=False, debug=False, **kwargs)

私はすべてのファイルの書き込みを避けました。デバッガは.outファイルをディレクトリに書き込み、Pythonファイルはoptimizeフラグの結果です。

これは当分の間は機能しますが、私はこのアプローチに完全に満足しているとは言えません。おそらく、最適化を維持し、同時に作業ディレクトリをきれいに保つための何らかの方法があれば、パフォーマンスが向上するという優れた解決策になるでしょう。他の誰かがより良い方法論を持っているならば、私はそれ以上にオープンです。

-1

はどうやら、このための引数はply.yaccにあります

def yacc(method='LALR', debug=yaccdebug, module=None, tabmodule=tab_module, start=None, 
    check_recursion=1, optimize=0, write_tables=1, debugfile=debug_file,outputdir='', 
    debuglog=None, errorlog = None, picklefile=None): 

ので、あなただけの標準出力/標準エラー出力に印刷されませんデバッグ()などのメソッドで別のエラーログとDEBUGLOGを(渡します)。そして、あなたは固定された出力ディレクトリを指定します。それだけであなたがする必要があります。

UPDATE:私はちょうどチェックして、これが正しい設定です:

yacc.yacc(
    debug=False,       # do not create parser.out 
    outputdir=r"c:\temp\aaa" # instruct to place parsetab here 
) 

実はすでにparsetab.pyが含まれているoutputDirのを使用する必要があります。これにより、メッセージだけでなく、プログラムがparsetab.pyを書き出すこともなくなります。それはちょうどそれを使用します。

+1

OPは単にメッセージを表示しないように要求するのではなく、一時的なパーサーテーブルファイルを常に再生成しません。 – elias

+0

私は、あなたが固定ディレクトリを使用し、すでにそこにファイルを置くと、それらは再生成されないと思います。しかし、私はその結果をあなたに知らせるようにします。 – nagylzs

+0

'debug = False'は実際にはエラーメッセージを抑制しますが、ファイルの生成を抑制しません。展開場所(ファイルが既に存在する場所)と組み合わせて使用​​すると、ファイルを上書きしようとします。 – Michael

2

あなたはとしてのlexを呼び出すことにより、optimized modeを使用したい:

lexer = lex.lex(optimize=1) 

それは(from the same link)強調する価値がある:以降の実行で

、lextab.pyは単にレクサーを構築するためにインポートされます。このアプローチは、レクサーの起動時間を大幅に改善し、Pythonの最適化モードで動作します。

最適化モードで実行する場合、lexはほとんどのエラーチェックを無効にすることに注意することが重要です。したがって、実際にはは、すべてが正しく動作し、プロダクションコードのリリースを開始する準備ができている場合にのみ推奨されます。

これはプロダクションコードなので、これはまさにあなたが望むように思えます。

。この問題に探して

は、私がmiscellaneous Yacc notes出くわし:

LALRテーブルの生成は比較的高価であるため、以前に生成されたテーブルがキャッシュされると、可能な場合に再利用します。テーブルを再生成する決定は、すべての文法ルールと優先ルールのMD5チェックサムを取ることによって決定されます。不一致の場合にのみ、テーブルが再生成されます。

そしてyacc.pyyacc機能に深く見て、私たちは、その最適化には、次のスニペットで、この不一致を無視参照:signatureは(_lr_signatureなど)parsetab.pyに保存されたチェックサムと比較され

if optimize or (read_signature == signature): 
    try: 
     lr.bind_callables(pinfo.pdict) 
     parser = LRParser(lr,pinfo.error_func) 
     parse = parser.parse 
     return parser 

+0

パーサとレクサーでoptimize = 1を設定する以外に何か必要なことはありますか?それを行うと、ファイルを再生成してメッセージを出力します – Michael

11

使用

yacc.yacc(debug=0, write_tables=0) 
+0

注:実際には 'debug = False、 write_tables = False'。 '0'はうまく動作しますが、' True'/'False'を使用する方が明示的で、ドキュメントも' bool'を使用します。 – Bakuriu

0

は、これは古い質問ですが、私は私のプロジェクト内の特定のディレクトリに生成されたパーサテーブルを配置するoutputdirのyaccキーワード引数を使用しようとしたとき、私はプライと同様の問題に遭遇しました - - それはそこに置かれますが、毎回それを再生成します。私は目に見える悪影響がない再生問題を解決したgithubのthisパッチを見つけました。基本的には、yaccクラスのread_tableメソッドを変更して、追加のパラメータ(outputdir)を取得し、そこにあるディレクトリを再生成します。その作業を行うには、read_table(方法yacc)の唯一の呼び出しサイトも、outputdirキーワード引数を渡すように変更する必要があります。

関連する問題