在Antlr4 Lexer中标记科学记数法

时间:2013-11-20 16:52:34

标签: antlr antlr4

我的词法分析器规则的大大简化版本(在更大的语法中)如下所示:

fragment HEX_DIGIT : [0-9A-F] ;
fragment DIGIT : [0-9] ;
SCIENTIFIC : 'E' [+-] ;
INTEGER : DIGIT+ ;
HEX_INTEGER : HEX_DIGIT+ ;
FLOAT_ZERO : '0'* '.' '0'+ ;
FLOAT : DIGIT* '.' DIGIT+ ;

这里的问题来自00E+00等输入。我想要的代币是'00','E +','00'。然而,Antlr走贪婪路线并将'00E'解析为HEX_INTEGER,并在完整词法分析器中产生'+'和'00'令牌。

在词法分析器中处理此特殊情况的任何建议? _input.LA()技巧似乎不起作用,因为我们在角色级别操作,所以我不能总是确定我需要向前看多远才能在十六进制的末尾寻找特殊的'E +'序列号。

2 个答案:

答案 0 :(得分:3)

我的推荐是:

  1. 制作SCIENTIFIC片段规则,并更新您的INTEGER规则以包含对科学记数法的支持。

    INTEGER : DIGIT+ (SCIENTIFIC DIGIT+)?;
    
  2. 更新HEX_INTEGER规则,使其与INTEGER不明确。例如,777可以是INTEGERHEX_INTEGER。并非所有数字都以十六进制表示法包含数字af

答案 1 :(得分:1)

经过一些试验和错误后想出来,并希望它可以帮助其他任何想要做类似事情的人。事实证明,你可以使用语义谓词,而不仅仅是词法规则的开头,我没有意识到。

// Tricky, becuase of sci notation- can't catch something like 00E+00, as we
// need tokens like '00', 'E+', '00'. If our number ends in 'E', don't let it
// be followed by '+' or '-'.
HEX_INTEGER
    : HEX_DIGIT*
      {_input.LA(1) != 'E' && _input.LA(2) != '+' && _input.LA(2) != '-'}?
      HEX_DIGIT
    ;