我有一个包含各种类型的更改运算符的无赖语法:
syntax ChangeOperator
= entityOperator: EntityOperation op
| attributeOperator : AttributesOperations op
| relationOperator: RelationOperations op
| databaseOperator: DatabaseOperations op
;
并且我尝试根据更改操作符的类型(EntityOperation,AttributeOperation等)执行不同的操作。我像这样循环遍历我的变更运算符:
for ( ChangeOperator op <- operators){
for(EvoQuery evo <- evoQueries){
transform(evo, op);
}
};
并且我定义了各种转换方法:
EvoQuery transform(EvoQuery q, EntityOperation op){ ... }
EvoQuery transform(EvoQuery q, AttributesOperations op) {...}
default EvoQuery transform(EvoQuery q, _) = q;
不幸的是,唯一被称为'transform'的版本是默认版本。
我如何适应循环或签名,以便根据替代的种类使它们匹配?
似乎在形式参数中的模式与循环中的实际参数之间存在类型不匹配(现在是ChangeOperator
,而不是某些操作)。将对transform
函数的调用更改为transform(evo, op.op)
,可能会得到预期的结果。
此外,可以将两个for
循环组合为一个循环,如下所示:
for (ChangeOperator op <- operators, EvoQuery evo <- evoQueries) {
transform(evo, op);
};
transform
的前两个替代方法失败,因为for循环主体中的参数op
的类型既不是EntityOperation也不是AttributusOperations:它是ChangeOperator
。换句话说:具体的语法类型不是子类型,即使定义它们的规则只是一个“链式规则”。
要在树的深处匹配一个级别,可以使用具体匹配或抽象匹配,如下所示:
具体而言,我们解析一个ChangeOperator片段,其中有一个单孔,并使用该模式与您作为第二个参数给出的解析树进行匹配:
EvoQuery transform(EvoQuery q, (ChangeOperator) `<EntityOperation op>`) { ... }
EvoQuery transform(EvoQuery q, (ChangeOperator) `<AttributesOperations op>`) {...}
用抽象表示法,我们可以使用ChangeOperator的每个替代语法规则的名称标签来替代替代。因此,在此示例中,我们使用抽象符号来匹配具体的解析树:
EvoQuery transform(EvoQuery q, entityOperator(EntityOperation op)) { ... }
EvoQuery transform(EvoQuery q, attributeOperator(AttributesOperations op) {...}