これらのルールでトークンを取得すると
STRINGA : '"' (options {greedy=false;}: ESC | .)* '"';
STRINGB : '\'' (options {greedy=false;}: ESC | .)* '\'';
'text'
ただの代わりにつかむことになりtext
ます。私は簡単に'
と'
自分自身を削除することができますが、ANTLRにそれを削除させる方法を考えていましたか?
1つのアプローチは、文字列の内容を別のカテゴリとして定義することです。たとえば、
STRINGA : '"' STRINGCONTENTS '"';
STRINGB : '\'' STRINGCONTENTS '\'';
次に、STRINGCONTENTS値をキャプチャします。
そのためのカスタムコードが必要になります。また、ルール内で(ドット)を使用しないでください。バックスラッシュ(最初はそれであると想定)、引用符、改行文字を除く.
すべてに一致させることを明示的に定義する必要があります。ESQ
このような何かがそれをするでしょう:
grammar T;
parse
: STRING EOF {System.out.println($STRING.text);}
;
STRING
: '"' (ESQ | ~('"' | '\\' | '\r' | '\n'))* '"'
{
String matched = getText();
StringBuilder builder = new StringBuilder();
for(int i = 1; i < matched.length() - 1; i++) {
char ch = matched.charAt(i);
if(ch == '\\') {
i++;
ch = matched.charAt(i);
switch(ch) {
case 'n': builder.append('\n'); break;
case 't': builder.append('\t'); break;
default: builder.append(ch); break;
}
}
else {
builder.append(ch);
}
}
setText(builder.toString());
}
;
fragment ESQ
: '\\' ('n' | 't' | '"' | '\\')
;
ここで入力を解析する"tabs:'\t\t\t'\nquote:\"\nbackslash:\\"
と、以下がコンソールに出力されます。
タブ:'' 引用:" バックスラッシュ:\
文法をきれいに保つために、もちろんカスタムメソッドでコードを移動することもできます。
grammar T;
@lexer::members {
private String fix(String str) {
...
}
}
parse
: STRING EOF {System.out.println($STRING.text);}
;
STRING
: '"' (ESQ | ~('"' | '\\' | '\r' | '\n'))* '"' {setText(fix(getText()));}
;
fragment ESQ
: '\\' ('n' | 't' | '"' | '\\')
;