ANTLR:如果后面有某个字符则不匹配

ANTLR: not match if a certain character follows

以下代码在 V 编程语言中完全有效:

fn main() {
    a := 1.
    b := .1
    println("$a $b")
    
    for i in 0..10 {
        println(i)
    }
}

我想编写一个 Lexer 来对这些文件进行语法着色。 1..1 应该匹配 FloatNumber 片段,而 for 循环中的 .. 应该匹配标点符号规则。我遇到的问题是我的 FloatNumber 实现已经与 0..10 中的 0..10 匹配,我不知道如何告诉它不匹配 [=21] =] 跟随(或在它前面)。有点简化(留下可能的下划线)我的语法看起来像这样:

fragment FloatNumber
    : ( Digit+   ('.' Digit*)?  ([eE]  [+-]?  Digit+)?
      | Digit*    '.' Digit+    ([eE]  [+-]?  Digit+)?
      )
    ;

fragment Digit
    : [0-9]
    ;

然后你将不得不引入一个谓词来检查在匹配像1.这样的浮点数时前面是否没有.

以下规则:

Plus
 : '+'
 ;

FloatLiteral
 : Digit+ '.' {_input.LA(1) != '.'}?
 | Digit* '.' Digit+
 ;

Int
 : Digit+
 ;

Range
 : '..'
 ;

给定输入 "1.2 .3 4. 5 6..7 8.+9",将产生以下标记:

FloatLiteral              `1.2`
FloatLiteral              `.3`
FloatLiteral              `4.`
Int                       `5`
Int                       `6`
Range                     `..`
Int                       `7`
FloatLiteral              `8.`
Plus                      `+`
Int                       `9`

谓词中的代码是特定于目标的。上面的谓词 ({_input.LA(1) != '.'}?) 适用于 Java 目标。