【问题标题】:ANTLR Parser, need to which parser rule is matchedANTLR Parser,需要匹配哪个解析器规则
【发布时间】:2018-02-07 09:18:54
【问题描述】:

在 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_name 规则,或者它是否匹配var 规则。

原因是,我试图以不同于 fcn_names 的方式处理变量。

【问题讨论】:

    标签: antlr


    【解决方案1】:

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

    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()];
    

    【讨论】:

      【解决方案2】:

      不,您无法获取解析器规则的名称(至少,如果没有丑陋的 hack )。

      但如果treeCommonTree 的一个实例,则意味着您已经调用了解析器的expr 规则,这意味着您已经知道expr 首先匹配(反过来匹配@987654326 @)。

      在相关说明中,请参阅:Get active Antlr rule

      【讨论】:

      • 只需将解析器规则名称传递给您的侦听器。所有名称都有一个功能。几乎没有破解。
      • 在 Python antlr4 中,这将是 ast_node.parser.ruleNames[ast_node.getRuleIndex()]
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-04
      相关资源
      最近更新 更多