ANTLR 4从解析树中做出决定

时间:2014-07-24 13:42:04

标签: antlr antlr4

我需要根据解析树中的结构和信息做出一些决定,这是我现在生成的树的一个例​​子:

Parse Tree

生成代码的决定取决于两个工作流之间的运算符(“;”,“AND”,“OR”,“XOR”),例如我需要从这个树生成的代码

mustPrecede(T6,T4) AND mustPrecede(T6,T1) 
AND  mustPrecede(T4,T5) AND  mustPrecede(T1,T5)

为此,我需要发现T6和(T4 AND T1)之间的运算符是“;” (顺序组合算子)做出决定然后我需要发现在T4和T1之间操作符是“AND”然后我需要让T4和T1与T5建立关系。我的问题是如何在解析器中对此进行编码?。

这是我的语法定义

grammar Hello;      

execution: workflow EOF;

workflow : Task 
         | workflow OPERATOR workflow 
         |'(' workflow (OPERATOR workflow)+ ')' 
         ;

Task : 'T' ('0'..'9')+ 
     | 'WF' ('0'..'9')+
     ;

OPERATOR: 'AND' 
        | 'OR'  
        | 'XOR' 
        | ';' 
        ;

WS  :   [ \t\n\r]+ -> channel(HIDDEN) ; 

1 个答案:

答案 0 :(得分:4)

您创建了一个令牌OPERATOR,代表您的所有运营商。这使得很难区分不同的运营商。一组更简单的规则如下:

operator
  : AND
  | OR
  | XOR
  | SEMI
  ;

AND : 'AND';
OR  : 'OR';
XOR : 'XOR;
SEMI : ';';

您还可以使用OPERATOR的引用替换对operator的引用。然后,在您的侦听器或访问者的实现中,您可以创建类似以下的方法(使用侦听器中的示例)。

@Override
public void enterWorkflow(WorkflowContext ctx) {
  List<? extends OperatorContext> operatorContexts = ctx.operator();
  if (operatorContexts.isEmpty()) {
    // handle just a Task
  } else {
    for (OperatorContext operatorContext : ctx.operator()) {
      switch (operatorContext.getStart().getType()) {
      case HelloLexer.AND:
        // handle 'AND'
        break;
      case HelloLexer.OR:
        // handle 'OR'
        break;
      case HelloLexer.XOR:
        // handle 'XOR'
        break;
      case HelloLexer.SEMI:
        // handle ';'
        break;
      default:
        throw new IllegalStateException("Unrecognized operator.");
      }
    }
  }
}