2013-05-08 15 views
5

ファイル全体をメモリにロードしないようにANTLRに指示することはできますか? 1つずつルールを適用し、ファイルの読み込みと同時にノードの最上位リストを生成できますか?また、分析されたノードを何らかの形で削除することも可能でしょうか?大きなファイルをANTLRで解析することはできますか?

+0

なぜこれが必要ですか?おそらくあなたは十分なメモリのために、メモリに巨大な木を構築することができます。 –

+3

明らかに私のファイルはメモリよりも大きい –

+0

はい?ファイルの大きさはどれくらいですか?それが本当に巨大であれば、それを処理するにはどれだけの価値がありますか?十分な価値がない場合、問題の解決にはほとんど問題がありません。十分な価値がある場合、大きなリソース(時間、スペース、カスタムツール)がオプションとしてテーブルに存在する必要があります。 –

答えて

10

はい、あなたが使用することができます。

  • UnbufferedCharStreamあなたの文字ストリーム(レクサーに渡された)
  • UnbufferedTokenStreamのためにあなたのトークンストリーム(パーサーに渡される)
    • のためにこのトークンストリームの実装は」doesnのトークンチャネルで区別する必要があるので、パーサーに送信すべきでないレクサールールのコマンドとして->channel(HIDDEN)の代わりに->skipを必ず使用してください。
  • パーサーでsetBuildParseTree(false)に電話するか、ファイル全体に対して巨大な解析ツリーが作成されていることを確認してください。いくつかの追加の解説と

編集:

  • 私は、UnbufferedCharStreamUnbufferedTokenStreamは特にmarkに関連して、可能な限り最も「正気」のように動作することを確認することにreleaseを仕事のかなりを置きますseek、およびgetTextの方法が挙げられる。私の目標は、未使用のメモリを解放するストリームの能力を損なうことなく、可能な限りそれらのメソッドの機能の多くを保持することでした。
  • ANTLR 4は真の無制限先読みを可能にします。あなたの文法が決定を下すためにEOFの先読みを必要とするなら、あなたは入力全体をメモリにロードすることを避けることができません。あなたは、文法を書くときにこのような状況を避けるために、細心の注意を払わなければなりません。
+0

UnbufferedTokenStreamをサブクラス化して非表示のトークンをスキップする場合(fillメソッドで行った)、スキップを使用するように文法を修正する必要がなくなります。 UnbufferedTokenStreamがフィルタリングオプションを提供していればいいですね。 –

+0

生成されたパーサのメソッドを直接使用して最上位の構文をインクリメンタルに解析する場合は、setBuildParseTree(true)を使用しても問題ありません。 –

+0

最後に、この回答はJavaバックエンドにのみ適用されるようです。たとえばPython APIには匹敵するクラスはありません。 –

3

Antlr.orgのどこかにWikiのページが埋め込まれています。ちょうど今は見つからないようです。

実質的に、レクサーは、標準のInputStreamインターフェイス、特にANTLRInputStream.javaを使用してデータを読み取ります。一般的な実装は、入力データファイル全体をメモリに先取りして読み取るANTLRFileStream.javaです。あなたがする必要があるのは、必要に応じてソースファイルから読み込む独自のバッファ付きバージョン( "ANTLRBufferedFileStream.java")を書くことです。または、標準のBufferedInputStream/FileInputStreamをAntlrInputStreamのデータソースとして設定します。

Antlr4は無限の先読みを行う可能性があります。通常の操作では、合理的なサイズのバッファの問題ではありません。パーサーがエラー回復を試みる可能性が高くなります。 Antlr4は、エラー回復戦略の調整を可能にするため、問題は管理可能です。

追加詳細:実際に

、ANTLRはプルパーサーを実装しています。最初のパーサールールを呼び出すと、パーサーは、入力ストリームから文字データを要求するトークンをレクサーに要求します。パーサー/レクサー・インターフェースは、公称でBufferedTokenStreamというバッファ付きトークン・ストリームによって実装されます。

構文解析ツリーは、トークンのツリーデータ構造にすぎません。さて、もっと多くのデータサイズの面ではありません。各トークンは、通常、トークン定義に一致した入力データストリームのフラグメントによって裏付けされたINT値である。レクサー自体は、lexの入力文字ストリームの完全なコピーをメモリに保持する必要はありません。そして、トークンのテキスト断片はゼロにすることができます。レクサーの重要なメモリ要件は、バッファされたファイル入力ストリームが与えられた場合、入力文字ストリームの先読みスキャンです。

必要に応じて、100GB以上の入力ファイルを指定してもメモリ内の解析ツリーを小さくすることができます。

さらに、Antlrで何をしようとしているのか、そして最小限のクリティカルなメモリ要件を定義することについて、さらに説明する必要があります。それは、どのような追加戦略を推薦できるかを導くでしょう。たとえば、ソースデータを使用することができれば、複数のレクサー/パーサー実行を使用して、レクサー内でソースデータのさまざまな部分を処理するたびにサブセレクションすることができます。ファイルの読み込みやDBの書き込みと比較して、高速のディスクであっても、Antlrの実行はほとんど目立たないでしょう。

+1

ストリームの再実装がどのように役立つかはわかりません。 ANTLRはツリー全体をメモリ内に作成しませんか?これは私が思う問題です。 –

+0

上記で回答しました。 – GRosenberg

+1

ツリー全体がメモリに残っている間に、あなたのアプローチが文字ストリームからメモリを解放するのに役立つことを確認できますか? –

関連する問題