ANTLR解析器,需要匹配哪个解析器规则
在ANTLR中,对于给定的令牌,有没有一种方法可以判断匹配了哪个解析器规则 例如,根据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) '
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()]
。