2016-09-01 11 views
0

this question私は任意のテキストからタグを抽出することについて尋ねました。提供されたソリューションはうまくいきましたが、私が処理したい1つのエッジケースがあります。要約すると、ユーザが入力した任意のテキストを解析しており、有効なタグ構文に一致するように<または>が出現したいと考えています。角括弧が有効なタグの一部でない場合は、&lt;または&gt;のようにエスケープする必要があります。私が探している構文は<foo#123>です。ここで、fooは固定のエントリリストのテキストで、123は数字[0-9]+です。パーサ:antlr文法回避角括弧

parser grammar TagsParser; 

options { 
    tokenVocab = TagsLexer; 
} 

parse: (tag | text)* EOF; 
tag: LANGLE fixedlist GRIDLET ID RANGLE; 
text: NOANGLE; 
fixedlist: FOO | BAR | BAZ; 

レクサー:

lexer grammar TagsLexer; 

LANGLE: '<' -> pushMode(tag); 
NOANGLE: ~[<>]+; 

mode tag: 

RANGLE: '>' -> popMode; 
GRIDLET: '#'; 
FOO: 'foo'; 
BAR: 'bar'; 
BAZ: 'baz'; 
ID: [0-9]+; 
OTHERTEXT: . ; 

これがうまく機能し、正常のようなテキストを解析:

:私は BailErrorStrategyを使用する場合

<foo#123> 
Hi <bar#987>! 
<baz#1><foo#2>anythinghere<baz#3> 
if 1 &lt; 2 

また成功し、次の失敗

<foo123> 
<bar#a> 
<foo#123H> 
<unsupported#123> 
if 1 < 2 

<tagモードに入り、サポートされているタグ形式と一致しないため、最後の1つは正常に失敗します。しかし、私はまた、以下も同様に失敗する必要がありますので、同様にテキストで>のインスタンスを避けたい:

if 2 > 1 

テキストではなく、生のアングルブラケットを持つのif 2 &gt; 1として指定する必要があること。

有効なタグに含まれていない>の出現が解析できないように、どのように文法を変更できますか?

+1

あなたの文法は今や '> 'タグの外にあるので、'タグ 'モード以外のレクサー文法のどこにも現れないので、トークンの認識エラーが発生します。十分ではありませんか? –

答えて

1

>は、tagモード以外のレクサー文法には表示されないため、文法のままであると、>がトークン認識エラーのあるタグの外で失敗します。それはそのまま大丈夫です。あなたはパース時に失敗を主張するなら、そしてちょうどレクサーのデフォルトモードに直角を追加します。

lexer grammar TagsLexer; 

LANGLE: '<' -> pushMode(tag); 
NOANGLE: ~[<>]+; 
BADRANGLE: '>'; 

mode tag; 

RANGLE: '>' -> popMode; 
... 

そして、タグの>外は解析中に失敗します。

+0

ありがとう、それは信じられないほど簡単でした!このようなものについての私の知識が行く方法を持っているように見えます。 –