ANTLR:匹配未转义字符?
我有一条规则,比如ANTLR:匹配未转义字符?,antlr,Antlr,我有一条规则,比如 charGroup : '[' .+ ']'; 但我猜这会匹配类似于[abc\]的东西。假设我想让它只匹配unscaped]s,我该怎么做?在正则表达式中,我会在后面使用负数 编辑:如果可能的话,我还希望它是不灵活/懒惰的。以便只匹配[a][b]中的[a] 我会用负面的眼光看后面 这不是不必要的复杂吗?那么: charGroup : '[' ('\\]' | .)+ ']'; 您可能想做以下事情: charGroup : '[' ('\\' . |
charGroup
: '[' .+ ']';
但我猜这会匹配类似于[abc\]
的东西。假设我想让它只匹配unscaped]
s,我该怎么做?在正则表达式中,我会在后面使用负数
编辑:如果可能的话,我还希望它是不灵活/懒惰的。以便只匹配[a][b]
中的[a]
我会用负面的眼光看后面
这不是不必要的复杂吗?那么:
charGroup
: '[' ('\\]' | .)+ ']';
您可能想做以下事情:
charGroup
: '[' ('\\' . | ~('\\' | ']'))+ ']'
;
其中~('\\'\'']')
与\
和]
以外的单个字符匹配。请注意,您只能对单个字符求反!没有所谓的~('ab')
。另一个经常犯的错误是,在解析器规则中求反并不会求反字符,而是求反标记。例如:
foo : ~(A | D);
A : 'a';
B : 'b';
C : 'c';
D : ~A;
现在解析器规则
foo
匹配令牌B
或令牌C
(因此只有字符'B'
和'C'
),而lexer规则D
匹配除'a'之外的任何字符。。。把\\]
放在那里,这样它就可以在匹配]
之前吃掉它。ANTLR中的+
运算符贪婪吗?如果我有类似于[a][b]
的东西,字符组就是全部,还是仅仅是[a]
?另外,如果可能的话,我仍然想使用某种形式的否定,然后我可以把它放入一个单独的规则,RBRACKET
,我也可以在其他地方使用。@Ralph,+
和*
在ANTLR中是贪婪的,除非前面有一个
(有些人可能会对此争论,但他们错了!这是特伦斯·帕尔的ANTLR参考资料)因此,*
和+
是不贪婪的,所有其他的+
和*
都是贪婪的。@Ralph,是的,我可以想象你会感到好奇。Terence在第4章,扩展BNF子规则,第86页解释了这个决定背后的动机。@Ralph,我强烈反对在那里使用
。因为你不想匹配一个]
和一个反斜杠,我会用~('\\'\'\''']]
来代替。而且,由于您希望匹配像\w
,\d
等这样的速记字符类,而不仅仅是\\[
,我也会选择使用\.
或定义一个单独的lexer规则,称为EscapeSequence
,它捕获所有转义字符。@Ralph,同样,这个建议不会正确解析输入,如:[\\\]
。这将被解释为:[
,“单反斜杠”,“单反斜杠+右括号”和]
,这是错误的。它应该是:[
,“转义反斜杠”,“转义反斜杠”,]
和]
。这看起来应该是可行的。但是没有零宽度断言这样的东西吗?如果我能找出一个未转义的]
用于重复使用。另外,谢谢你的提示,我会尽量记住这些。对不起,我不太明白你所说的“排除一个未替换的]以供重复使用”是什么意思(现在还早!:)…我的意思是,是否可以定义一个规则RBracket:']
以便它只匹配一个未替换的]
。然后我可以简单地将charGroup定义为charGroup:LBracket.+RBracket
,它在语法中的其他一些地方也很有用。从技术上讲,左括号也应该是不可替换的。也许使用那些你之前链接到我的谓词?“我不知道这些是否可以被否定。”“拉尔夫,是的,这是可能的,但我会犹豫到底。lexer IMO中不应该有太多的“智能”。我认为最好在RBracket
上面定义一个规则,比如说EscSeq
,它匹配一个反斜杠,后跟其他字符。因为它位于RBracket
上方,所以在]
之前不会有反斜杠:lexer规则在.g
语法文件中从上到下匹配。也可以考虑在字符串前面有一个反斜杠的字符串<代码> \\代码>,但是它并没有脱离括号,而是在它之前的反斜杠。