ANTLR解析器,需要匹配哪个解析器规则

ANTLR解析器,需要匹配哪个解析器规则,antlr,Antlr,在ANTLR中,对于给定的令牌,有没有一种方法可以判断匹配了哪个解析器规则 例如,根据ANTLR语法: tokens { ADD='Add'; SUB='Sub'; } fragment ANYDIGIT : '0'..'9'; fragment UCASECHAR : 'A'..'Z'; fragment LCASECHAR : 'a'..'z'; fragment DATEPART : ('0'..'1') (ANYDIGIT) '

在ANTLR中,对于给定的令牌,有没有一种方法可以判断匹配了哪个解析器规则

例如,根据ANTLR语法:

tokens
{
    ADD='Add';
    SUB='Sub';
}

fragment
ANYDIGIT    :   '0'..'9';

fragment
UCASECHAR   :   'A'..'Z';

fragment
LCASECHAR   :   'a'..'z';

fragment
DATEPART    :   ('0'..'1') (ANYDIGIT) '/' ('0'..'3') (ANYDIGIT) '/' (ANYDIGIT) (ANYDIGIT) (ANYDIGIT) (ANYDIGIT);

fragment
TIMEPART    :   ('0'..'2') (ANYDIGIT) ':' ('0'..'5') (ANYDIGIT) ':' ('0'..'5') (ANYDIGIT);

SPACE       :   ' ';

NEWLINE     :   '\r'? '\n';

TAB         :   '\t';

FORMFEED    :   '\f';

WS          :   (SPACE|NEWLINE|TAB|FORMFEED)+ {$channel=HIDDEN;};

IDENTIFIER  :   (LCASECHAR|UCASECHAR|'_') (LCASECHAR|UCASECHAR|ANYDIGIT|'_')*;

TIME        :   '\'' (TIMEPART) '\'';

DATE        :   '\'' (DATEPART) (' ' (TIMEPART))? '\'';

STRING      :   '\''! (.)* '\''!;

DOUBLE      :   (ANYDIGIT)+ '.' (ANYDIGIT)+;

INT         :   (ANYDIGIT)+;

literal     :   INT|DOUBLE|STRING|DATE|TIME;

var         :   IDENTIFIER;

param       :   literal|fcn_call|var;

fcn_name    :   ADD | 
                SUB | 
                DIVIDE | 
                MOD | 
                DTSECONDSBETWEEN | 
                DTGETCURRENTDATETIME |
                APPEND |
                STRINGTOFLOAT;

fcn_call    :   fcn_name WS? '('! WS? ( param WS? ( ','! WS? param)*)* ')'!;

expr        :   fcn_call WS? EOF;
在Java中:

  CommonTreeNodeStream nodes = new CommonTreeNodeStream(tree);
  nodes.reset();
  Object obj;
  while((obj = nodes.nextElement()) != null)
  {
      if(nodes.isEOF(obj))
      {
          break;
      }
      System.out.println(obj);
  }
那么,我想知道的是,在
System.out.println(obj)
中,节点是否匹配
fcn\u name
规则,还是匹配
var
规则


原因是,我试图以不同于
fcn\u names

的方式处理vars。不,您无法获取解析器规则的名称(至少,如果没有一个难看的破解,就不能)➊).

但是如果
tree
CommonTree
的一个实例,这意味着您已经调用了解析器的
expr
规则,这意味着您已经知道
expr
首先匹配(反过来匹配
fcn\u name


➊ 请参阅相关说明:

否,您无法获取语法分析器规则的名称(至少,如果没有一个难看的破解程序,就无法获取)➊).

但是如果
tree
CommonTree
的一个实例,这意味着您已经调用了解析器的
expr
规则,这意味着您已经知道
expr
首先匹配(反过来匹配
fcn\u name


➊ 有关相关说明,请参见:

将此添加到您的听众/访问者:

String[] ruleNames;
public void loadParser(gramParser parser) {  //get parser
    ruleNames = parser.getRuleNames(); //load parser rules from parser
}
从创建侦听器/访问者的任何位置调用loadParser(),例如:

MyParser parser = new MyParser(tokens);
MyListener listener = new MyListener(); 
listener.loadParser(parser);  //so we can access rule names
然后在每个规则中,您可以获得如下规则名称:

ruleName = ruleNames[ctx.getRuleIndex()];

将此添加到您的侦听器/访问者:

String[] ruleNames;
public void loadParser(gramParser parser) {  //get parser
    ruleNames = parser.getRuleNames(); //load parser rules from parser
}
从创建侦听器/访问者的任何位置调用loadParser(),例如:

MyParser parser = new MyParser(tokens);
MyListener listener = new MyListener(); 
listener.loadParser(parser);  //so we can access rule names
然后在每个规则中,您可以获得如下规则名称:

ruleName = ruleNames[ctx.getRuleIndex()];

只需将解析器规则名传递到您的侦听器中。有一个用于所有名称的函数。这几乎不是一个hack。在Python antlr4中,这将是
ast_node.parser.ruleNames[ast_node.getRuleIndex()]
。只需将解析器规则名传递给您的侦听器。有一个用于所有名称的函数。这几乎不是一个黑客。在Python antlr4中,这将是
ast\u node.parser.ruleNames[ast\u node.getRuleIndex()]