如何使用ANTLR 4转义转义字符?

时间:2015-04-22 14:05:42

标签: escaping antlr quotes antlr4

许多语言使用某种引号绑定字符串,如下所示:

"Rob Malda is smart."

ANTLR 4可以将这样的字符串与词法分析器规则匹配,如下所示:

QuotedString : '"' .*? '"';

要使用字符串中的某些字符,必须对它们进行转义,可能是这样的:

"Rob \"Commander Taco\" Malda is smart."

ANTLR 4也可以匹配此字符串;

EscapedString : '"' ('\\"|.)*? '"';

(取自最终ANTLR 4参考文献的第96页)

这是我的问题:假设转义的字符与字符串分隔符是相同的字符。例如:

"Rob ""Commander Taco"" Malda is smart."

(这在Powershell中完全合法。)

什么词法规则会匹配这个?我认为这会奏效:

EscapedString : '"' ('""'|.)*? '"';

但事实并非如此。词法分析器将转义字符"标记为字符串分隔符的结尾。

2 个答案:

答案 0 :(得分:11)

使用~运算符否定某些字符:

EscapedString : '"' ( '""' | ~["] )* '"';

或者,如果字符串中没有换行符,请执行:

EscapedString : '"' ( '""' | ~["\r\n] )* '"';

您不想使用非贪婪的运算符,否则永远不会使用"",而"a""b"将被标记为"a""b"而不是$stmt = $db->prepare("INSERT INTO list(title, topicDesc,date,kod,country) VALUES (?, ?, ?, ?, ?)"); $stmt->bind_param('sssis', 'yo','yo desc','1 may 2015,','123','US'); 单一令牌。

答案 1 :(得分:2)

(不要投票给这个答案;投票给@Bart Kiers'回答。)

我提供完整性,因为它是Powershell语法的一小部分。将最终的ANTLR 4参考中的p76的转义逻辑与Bart的答案结合起来,以下是在Powershell中lexing转义字符串所需的规则:

EscapedString
    : '"'      (Escape | '""'   | ~["])* '"'
    | '\''     (Escape | '\'\'' | ~['])* '\''
    | '\u201C' (Escape | .)*? ('\u201D' | '\u2033')   // smart quotes
    ;

fragment Escape
    : '\u0060\''    // backtick single-quote
    | '\u0060"'     // backtick double-quote
    ;

这些规则在Powershell中处理以下四种转义字符串的方法:

'Rob ''Commander Taco'' Malda is smart.'
"Rob ""Commander Taco"" Malda is smart."
'Rob `'Commander Taco`' Malda is smart.'
"Rob `"Commander Taco`" Malda is smart."