我需要根据解析树中的结构和信息做出一些决定,这是我现在生成的树的一个例子:
生成代码的决定取决于两个工作流之间的运算符(“;”,“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) ;
答案 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.");
}
}
}
}