是否可以在 Antlr4 中将令牌拆分为 2?

Is it possible to split a token into 2 in Antlr4?

为了突出显示,我需要能够将一个令牌分成 2 个,我有一个看起来像这样的令牌:

ID_INTERP: '$' IDEN;

但我想突出显示美元符号与标识符不同,那么是否可以将此令牌拆分为两个,一个带有美元符号,另一个带有标识符?我知道我可以在某些条件下将整个令牌更改为不同的类型,但我希望能够添加和更改它包含的文本,基本上是更改令牌流,而不是说

ID_INTERP["$foo"]

它会看到这样的东西:

DOLLAR_SIGN["$"] IDEN["foo"]

可以通过扩展您的令牌源来为给定匹配发出多个令牌。我已经使用这个想法为词法分析器规则 DOT_IDENTIFIER (see the MySQL grammar in the MySQL Workbench parser) 生成了 2 个标记。在匹配时,它会推送一个点标记并将结果设置为 IDENTIFIER,有效地为单个规则创建 2 个单独的标记。

Sam Harwell 描述了使用一些 Java 代码为这种方法 in his answer 扩展词法分析器的技术。这是我正在使用的可能的 C++ 实现:

std::unique_ptr<antlr4::Token> MySQLBaseLexer::nextToken() {
  // First respond with pending tokens to the next token request, if there are any.
  if (!_pendingTokens.empty()) {
    auto pending = std::move(_pendingTokens.front());
    _pendingTokens.pop_front();
    return pending;
  }

  // Let the main lexer class run the next token recognition.
  // This might create additional tokens again.
  auto next = Lexer::nextToken();
  if (!_pendingTokens.empty()) {
    auto pending = std::move(_pendingTokens.front());
    _pendingTokens.pop_front();
    _pendingTokens.push_back(std::move(next));
    return pending;
  }
  return next;
}