ANTLR3词法分析器优先级

5

我想在ANTLR3词法分析器中从'..'创建一个标记,用于串联表达式,例如

a..b     // [1]
c .. x   // [2]
1..2     // [3] 
3 .. 4   // [4]

所以,我已经添加了,
DOTDOTSEP : '..' 
          ;

问题在于我已经有一个规则:
FLOAT : INT (('.' INT (('e'|'E') INT)? 'f'?) | (('e'|'E') INT)? ('f'))
      ;

在上面的示例[3]中,1..2被匹配为FLOAT(我不确定为什么,因为在第一个.之后是另一个.而不是INT,但确实如此)。
我想知道是否有一种方法可以更改词法分析器规则的优先级,以便首先匹配DOTDOTSEP,然后匹配FLOAT
这里看起来,似乎我正在输给“具有最大计数的规则是赢家”,但我想知道是否有一种方法可以解决这个问题。
附:INT的定义如下...
fragment DIGIT
    : '0'..'9'
    ;

INT : DIGIT+
    ;

编辑。 进一步的测试让我认为它并不像直接匹配到 FLOAT 规则那么简单。(我原本想改变问题,但既然我已经得到了答案,我就不会这么做了。)问题(我相信)仍然在词法分析器规则的优先级上,因此问题仍然保持不变。

1个回答

7
你看过http://sds.sourceforge.net/src/antlr/doc/lexer.html吗?
一个可能的解决方案是定义以下内容:
fragment
INT : DIGIT+
    ;

fragment
RANGE : INT DOTDOTSEP INT
      ;

fragment
FLOAT : INT (('.' INT (('e'|'E') INT)? 'f'?) | (('e'|'E') INT)? ('f'))
      ;

NUMBER
    : (INT '.') => FLOAT       { $type=FLOAT; }
    | (INT DOTDOTSEP) => RANGE { $type=RANGE; }
    | INT                      { $type=INT; }
    ;

这让我更接近目标了,只需要再微调一下。我之前没找到这个链接,但看起来很不错;正是我应该阅读的内容,所以我现在去看看。谢谢。 - tjm
现在我已经将其成功运行,这里有几个注意事项供其他可能遇到类似情况的人参考。在ANTLRWorks v1.4中,解释器无法处理断言,因此当实际上没有错误时,看起来会出现错误(这让我浪费了一些时间)。另外,我还必须将“$settype(TYPE);”更改为“$type=TYPE;”。 - tjm
@tjm,我稍微编辑了一下ANTLR示例。现在它是否兼容v3? - Bart Kiers
@Bart。我注意到了你的编辑,谢谢,它们很有帮助。据我所知,它现在是v3兼容的。至少我可以肯定地说,“它在这里运行正常!(TM)” :) - tjm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接