许多语言使用某种引号绑定字符串,如下所示:
"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 : '"' ('""'|.)*? '"';
但事实并非如此。词法分析器将转义字符"
标记为字符串分隔符的结尾。
答案 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."