當我拿到這些規則令牌如何在ANTLR擺脫「在我的字符串?
STRINGA : '"' (options {greedy=false;}: ESC | .)* '"';
STRINGB : '\'' (options {greedy=false;}: ESC | .)* '\'';
它最終抓住'text'
,而不是僅僅text
,我可以很容易地取出'
和'
自己,但想知道我怎麼能得到ANTLR刪除它?
當我拿到這些規則令牌如何在ANTLR擺脫「在我的字符串?
STRINGA : '"' (options {greedy=false;}: ESC | .)* '"';
STRINGB : '\'' (options {greedy=false;}: ESC | .)* '\'';
它最終抓住'text'
,而不是僅僅text
,我可以很容易地取出'
和'
自己,但想知道我怎麼能得到ANTLR刪除它?
您需要一些自定義代碼。此外,你不應該使用.
(點)的規則內:你應該明確地定義要匹配一切除了一個反斜槓(假設這就是你的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:\\"
,以下將被打印到控制檯:
tabs:' ' quote:" backslash:\
爲了保持語法乾淨,你可以當然在自定義方法中移動代碼:
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' | '"' | '\\')
;
一種方法是定義字符串的內容作爲一個單獨的類別,例如
STRINGA : '"' STRINGCONTENTS '"';
STRINGB : '\'' STRINGCONTENTS '\'';
然後捕獲STRINGCONTENTS值。