1

プレーンテキスト内のHTMLブロックレベルの要素を認識するためにANTLR文法を書いています。divタグに限定された関連スニペットは次のとおりです。

grammar Test;

blockElement
  : div
  ;

div
  : '<' D I V HTML_ATTRIBUTES? '>' (blockElement | TEXT)* '</' D I V '>'
  ;

D : ('d' | 'D') ;
I : ('i' | 'I') ;
V : ('v' | 'V') ;

HTML_ATTRIBUTES
  : WS (~( '<' | '\n' | '\r' | '"' | '>' ))+
  ;

TEXT
  : (. | '\r' | '\n')
  ;

fragment WS
  : (' ' | '\t')
  ;

TEXTトークンは、プレーンテキストやインラインタグ(例)など、ブロックレベルの要素ではないものを表すことになっています<b><\b>。ネストされたブロック要素でテストすると、次のようになります。

<div level_0><div level_1></div></div>

それらを正しく解析します。ただし、ランダムなテキストを追加するとすぐに、最初のTEXTトークンを消費した直後にMismatchedTokenException(0!= 0)がスローされます(例:大文字のT )。

<div level_0>This is some random text</div>

助言がありますか?私は概念的に間違ったことをしていますか?私はANTLRv。3.2を使用しており、ANTLRWorksv。1.4でテストを行っています。

ありがとうございました

4

1 に答える 1

3

ANTLRWorksを使用して文法をテストしないことをお勧めします。コンソールではエラーメッセージが見落とされがちであるため、テスト入力が期待どおりに解釈されない可能性があります。次のようなカスタム作成されたクラスでそれを行います。

import org.antlr.runtime.*;

public class Main {
    public static void main(String[] args) throws Exception {
        ANTLRStringStream in = new ANTLRStringStream("<div level_0>This is some random text</div>");
        TestLexer lexer = new TestLexer(in);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        TestParser parser = new TestParser(tokens);
        Sparser.parse());
    }
}

現在、次のルールは正しくありません。

TEXT
  :  (. | '\r' | '\n')
  ;

はすでにとの両方に.一致しているため、次のようになります。\r\n

TEXT
  :  .
  ;

これを変更する場合は、パーサーとレクスターを作成し、すべての.javaファイルをコンパイルして、Mainクラスを実行できます。

java -cp antlr-3.2.jar org.antlr.Tool Test.g
javac -cp antlr-3.2.jar * .java
java -cp。:antlr-3.2.jarメイン

これにより、次のエラーが発生します。

line 1:15 mismatched input 'i' expecting '</'

ifromThisはルールによってトークン化されているためI : ('i' | 'I') ;です。

現在のアプローチにはさらに問題があります。

  • HTML_ATTRIBUTESやりすぎです。代わりにATTRIBUTE、ルールを設定してから、複数形(html属性)をパーサーに移動する必要が=あります。VALUE
  • これで、属性に含めることができず<>これが正しくありません(推奨されていませんが、属性を含めることができます)。

もし私があなただったら、最初からやり直します。あなたが望むなら、私はスタートを提案するつもりです:ちょうどそう言います。

于 2010-06-23T08:30:59.903 に答える