2

オリジナル

スタックオーバーフローで質問するのはこれが初めてなので、解決策があまりにも明白ではないことを願っています. Antlr を使用して xml ファイルのデータを解析し、Eclipse で作成している Java プログラムで使用できるトークンを生成しようとしています。antlr-works IDE で antlr を使用して、組み込む必要のある Java コードを生成した経験しかありません。問題は、私の xml ファイルが非常に大きくて複雑であることです。そのため、最初は、一度にいくつかの属性を確認することにしか興味がありません。物事を簡単にするために、フィルター オプションを使用してふるいにかけ、トークンの定義に一致するデータのみを取得しようとしています。フィルター オプションは、パーサーとレクサーの文法を別々に定義している場合にのみ使用できることを理解していますが、組み合わせた文法を適応させようとすると、不足しているトークンや不要なトークンについて不平を言うエラーが発生した後、突然エラーが発生し始めました。なぜ一方が機能し、もう一方が機能しないのかを理解しようとしています。それらを同じファイルに保存しましたが、オプションステートメントを削除しても問題は解決しません。

これが私の結合された文法であり、その後に適応された文法が続きます。

組み合わせ:

grammar dataExtract;

prog    :    .*;

SOF     :      ('<posts>');

Tag_string :    ('<')(.~'>')+('>');

Tag :   ('Tags="')Tag_string+('"');

WS  :   ( ' '
        | '\t'
        | '\r'
        | '\n'
        ) {$channel=HIDDEN;}
    ;

EOF :   '</posts>';

別:

parser grammar dataExtract;

prog    :    .*;

lexer grammar dataExtract


SOF     :      ('<posts>');


options{filter=true};

Tag_string :    ('<')(.~'>')+('>');

Tag :   ('Tags="')Tag_string+('"');

WS  :   ( ' '
        | '\t'
        | '\r'
        | '\n'
        ) {$channel=HIDDEN;}
    ;

EOF :   '</posts>';

更新しました

回答ありがとうございます。今では意味があり、文法を機能させることに近づいています.1つだけ問題が残っているようです. パーサーの文法は問題なく動作しているようで、antlrworks は文句を言わずに Java クラスを生成しますが、レクサーの定義を独自の .g ファイルに保存すると、定義したルールが All だけであっても、レクサーのルールが壊れているようです。 : .*;、EarlyExitException が発生します。また、私の理解が正しければ、tokenVocab オプションはレクサー文法からトークン ファイルを検索しますが、エラーが発生し、コードを生成していないため、まだトークン ファイルが作成されていないため、これがないとパーサーは正しく生成されません。何が起こっているのですか?同様の問題を検索してみましたが、ルールに一致するトークンが入力に見つからない場合にこのエラーが発生すると多くの資料が主張しているようですが、これを入力するところまで到達していないためですそうはなりません。

4

2 に答える 2

3

レクサー文法とパーサー文法を分離する場合、ANTLR は、生成された .java ソース ファイルの名前"Lexer"または名前の後に追加しません。"Parser"したがって、この場合は一意の名前を使用する必要があります。

パーサー

parser grammar DataExtractParser;

options {
  tokenVocab=DataExtractLexer; 
}

...

レクサー

lexer grammar DataExtractLexer;

...

また、前に述べたように、tokenVocab=LEXER_GRAMMAR_NAME;オプションを介してパーサーが使用する必要があるトークン (レクサー ルール) を明示的に示します。

于 2012-11-15T08:18:22.750 に答える
2

どのトークンセットを使用するかをパーサーに指示する必要があります。

parser grammar dataExtract;

options
{
  tokenVocab=dataExtract; // Looks for dataExtract.tokens file
}

prog : .*;
于 2012-11-15T05:51:57.450 に答える