0

こんにちは、

バックグラウンド:

私は Checkstyle 4.4.2 と RegExp チェッカー モジュールを使用して、Java ソース ヘッダーのファイル名が、それらが存在するクラスまたはインターフェイスのファイル名と一致しないことを検出しています。これは、開発者があるクラスから別のクラスにヘッダーをコピーし、「File:」タグを変更しない場合に発生する可能性があります。

RexExp チェッカーでの正規表現の使用は、多くの具体化を経ており、(現時点ではやり過ぎかもしれませんが) 次のようになります。

File: (\w+)\.java\n(?:.*\n)*?(?:[\w|\s]*?(?: class | interface )\1)

私がチェックしているファイルの基本的な形式は(非常に単純化されていますが)、次のようになります

/*
 *
 *  Copyright 2009
 *  ...
 *  File: Bar.java
 *  ... 
 */
package foo
... 
import ..
...
/**
 * ...
 */
public class Bar
{...} 

問題:

一致が見つからない場合(つまり、「File: Bar.java」を含むヘッダーがファイル Bat.java にコピーされた場合)、非常に長いファイルで StackOverflowError を受け取ります (私のテストケースは @1300 行です)。

私はいくつかの視覚的な正規表現テスターで実験しましたが、正規表現エンジンがクラスまたはインターフェース名を含む行を通過すると、一致しない場合に、次の行で再び検索を開始し、おそらく StackOverflowError を引き起こすバックトラッキングを行うことがわかります。

質問:

正規表現を変更して StackOverflowError を防ぐ方法

一致しない場合 (つまり、 "File: Bar.java" を含むヘッダーがファイル Bat.java にコピーされた場合) を含む行を調べると、一致が停止するように正規表現を変更する方法はありますか?インターフェイスまたはクラス名を調べて、「\1」が最初のグループと一致しないことを確認します。

あるいは、それが可能な場合、インターフェイスまたはクラスを含む行を調べた後に行われる検索とマッチングを最小限に抑えて、処理と (できれば) StackOverflow エラーを最小限に抑えることは可能ですか?

4

2 に答える 2

0

ファローアップ:

上記のTimPietzcherの提案をプラグインしましたが、一致するものが見つからなかった場合、彼の貪欲なソリューションは実際に速く失敗し、StackOverflowErrorは発生しませんでした。ただし、肯定的なケースでは、StackOverflowErrorが引き続き発生しました。

ソースコードRegexpCheck.javaを見てみました。クラスパターンは、式^と$がそれぞれ行末記号または入力シーケンスの終わりの直後または直前に一致するように、複数行モードで構築されます。次に、クラスファイル全体を文字列に読み込み、パターンを再帰的に検索します(findMatch()を参照)。それは間違いなくStackOverflowExceptionの原因です。

結局、私はそれを動作させることができませんでした(そしてあきらめました)Maven2が約6週間前にmaven-checkstyle-plugin-2.4/ Checkstyle 5.0をリリースして以来、ツールをアップグレードすることにしました。これはStackOverflowErrorの問題を解決しないかもしれませんが、誰かがこれをもう一度追求する必要があると判断するまで、私に何か他の作業を与えるでしょう。

于 2009-12-30T20:33:27.253 に答える
0

試す

File: (\w+)\.java\n.*^[\w \t]+(?:class|interface) \1

ドットマッチオールモード。根拠:

[\w\s]( | はそこに属しません) は、改行を含むすべてに一致します。これにより、正規表現の前の部分が一致した行に戻る多くのバックトラックが発生します。

貪欲なドットがファイルの最後まですべてを飲み込み (クイック)、単語またはスペース/タブ (ただし改行はありません) で始まり、次にclassまたinterfaceはと \1 で始まる行が見つかるまでバックトラックすると、それは機能しません。多くのスタックスペースを必要としません。

別の、そしておそらくより良い解決策は、問題を部分に分割することです。

まずはFile: (\w+)\.javaパーツ合わせ。次に、同じファイルで最初の検索からの一致に^[\w \t]+(?:class|interface)加えて、2 番目の検索を実行します。\1

于 2009-11-25T22:16:11.373 に答える