Java 非参数化和参数化语句的不同令牌名称,或如何使用Rulexer跳转到上一个令牌

Java 非参数化和参数化语句的不同令牌名称,或如何使用Rulexer跳转到上一个令牌,java,antlr4,Java,Antlr4,如何为以下示例实现不同的令牌名称: #someNameAttribute //where #someNameAttribute should be assigned to IDENTIFIER lexer rule #someNameAttribute("2a3a796e-9870-4b88-9f2d-383eb9566613", 10) // where #someNameAttribute should be assigned to PARAMETERIZED_IDENTIFIER sinc

如何为以下示例实现不同的令牌名称:

#someNameAttribute //where #someNameAttribute should be assigned to IDENTIFIER lexer rule
#someNameAttribute("2a3a796e-9870-4b88-9f2d-383eb9566613", 10) // where #someNameAttribute should be assigned to PARAMETERIZED_IDENTIFIER since we faced with parenthesis 
我现在有语法(但它总是分配给标识符):

或者,如果可以通过某种方式检查Java代码中#someNameAttribute之后括号中的下一个标记,我们将很高兴听到如何做到这一点。我也尝试过这种方法,但是rulexer.nextToken()允许我检查下一个标记,但我无法再次跳到上一个标记以继续执行整个语句(因此开始丢失一些标记)

如何使用RuleLexer从Java代码中预测要分配的令牌名称或如何跳转到上一个令牌?

尝试类似的方法(仅适用于Java):

如果标识符和
)之间允许有空格,请执行以下操作:

grammar Rule;

@lexer::members {
  boolean spacesAndOpenParenAhead() {
    for (int i = 1; ; i++) {
      char ch = (char)_input.LA(i);
      if (ch == '(') {
        return true;
      }
      else if (ch != ' ' && ch != '\t' && ch != '\r' && ch != '\n') {
        return false;
      }
    }
  }
}

...

PIDENTIFIER         : IDENTIFIER {spacesAndOpenParenAhead()}?;
IDENTIFIER          : '#' [a-zA-Z$_] [a-zA-Z$_0-9]*;
当我在两个示例语法上运行下面的代码时:

import org.antlr.v4.runtime.*;
公共班机{
公共静态void main(字符串[]args)引发异常{
String source=“#someNameAttribute\n”+
“#someNameAttribute(\“2a3a796e-9870-4b88-9f2d-383eb9566613\”,10)”;
RuleLexer lexer=新的rulexer(CharStreams.fromString(source));
CommonTokenStream=新的CommonTokenStream(lexer);
stream.fill();
for(令牌t:stream.getTokens()){
System.out.printf(“%-20s`%s`%n”,
rulexer.词汇表.getDisplayName(t.getType()),
t、 getText().replace(“\n”,“\\n”);
}
}
}
以下内容打印在我的控制台上:

IDENTIFIER           `#someNameAttribute`
PIDENTIFIER          `#someNameAttribute`
'('                  `(`
UUID                 `"2a3a796e-9870-4b88-9f2d-383eb9566613"`
OTHER                `,`
NUMERIC              `10`
')'                  `)`

#someNameAttribute(“2a3a796e-9870-4b88-9f2d-383eb9566613”,10)-工作,但#someNameAttribute-不工作,仍分配给PIDENTIFIER我得到了预期的结果(首先是
标识符
,然后是
PIDENTIFIER
)。检查我编辑的答案。属性名称和括号之间不允许有空格。我复制粘贴了您的第一个选项,并出于某种原因获得了PIDENTIFIER-Pidentier-LPAREN-UUID-DELIMETER-NUMERIC-RPARE。添加了我使用的语法。看起来我的Intellij ANTLR v4插件不理解语义谓词。我从代码中看到了正确的赋值谢谢
grammar Rule;

@lexer::members {
  boolean spacesAndOpenParenAhead() {
    for (int i = 1; ; i++) {
      char ch = (char)_input.LA(i);
      if (ch == '(') {
        return true;
      }
      else if (ch != ' ' && ch != '\t' && ch != '\r' && ch != '\n') {
        return false;
      }
    }
  }
}

...

PIDENTIFIER         : IDENTIFIER {spacesAndOpenParenAhead()}?;
IDENTIFIER          : '#' [a-zA-Z$_] [a-zA-Z$_0-9]*;
IDENTIFIER           `#someNameAttribute`
PIDENTIFIER          `#someNameAttribute`
'('                  `(`
UUID                 `"2a3a796e-9870-4b88-9f2d-383eb9566613"`
OTHER                `,`
NUMERIC              `10`
')'                  `)`