私は、テンプレート言語を解析するantlr文法を構築しようとしています。その言語は任意のテキストに埋め込むことができ、境界は開閉タグ({{
/}}
)でマークされます。antlr3文法でのレクサー状態の切り替え
foo {{ someVariable }} bar
foo
とbar
が無視されるべきである、と{{
と}}
タグ内部の一部を解析する必要がある場合は:だから有効なテンプレートは次のようになります。私は、{
と}
というタグを除いて、基本的に問題の答えがあるthis questionを見つけました。私は2つの開閉文字にマッチするように文法を修正しようとしましたが、すぐにこれを行うと、BUFFER
ルールはすべての文字、開閉括弧も消費します。 LD
ルールが呼び出されることはありません。
区切り文字に2文字が含まれていて、文字が1文字しかないときに区切り文字を消費しない場合、antlrレクサーがBuffer
ルールですべてのトークンを消費している理由は誰にもありますか?
grammar Test;
options {
output=AST;
ASTLabelType=CommonTree;
}
@lexer::members {
private boolean insideTag = false;
}
start
: (tag | BUFFER)*
;
tag
: LD IDENT^ RD
;
LD @after {
// flip lexer the state
insideTag=true;
System.err.println("FLIPPING TAG");
} : '{{';
RD @after {
// flip the state back
insideTag=false;
} : '}}';
SPACE : (' ' | '\t' | '\r' | '\n') {$channel=HIDDEN;};
IDENT : (LETTER)*;
BUFFER : { !insideTag }?=> ~(LD | RD)+;
fragment LETTER : ('a'..'z' | 'A'..'Z');
「IDENT :(LETTER)*;」(おそらく)レクサーが無限ループになることに注意してください。レクサールール_must_は常に少なくとも1文字と一致します。 –