函数签名中的模式匹配语法替代项

问题描述 投票:0回答:2

我有一个包含各种类型的更改运算符的无赖语法:

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'的版本是默认版本。

我如何适应循环或签名,以便根据替代的种类使它们匹配?

rascal
2个回答
1
投票

似乎在形式参数中的模式与循环中的实际参数之间存在类型不匹配(现在是ChangeOperator,而不是某些操作)。将对transform函数的调用更改为transform(evo, op.op),可能会得到预期的结果。

此外,可以将两个for循环组合为一个循环,如下所示:

for (ChangeOperator op <- operators, EvoQuery evo <- evoQueries) {  
  transform(evo, op);
};

0
投票

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) {...}
© www.soinside.com 2019 - 2024. All rights reserved.