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



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

syntax ChangeOperator
    = entityOperator: EntityOperation op
    | attributeOperator : AttributesOperations op
    | relationOperator: RelationOperations op
    | databaseOperator: DatabaseOperations op
    ;

我尝试根据更改运算符的类型(实体操作、属性操作等(执行不同的操作。我像这样遍历我的更改运算符:

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;

不幸的是,唯一被调用的"转换"版本是默认版本。

如何调整循环或签名以使它们根据替代方案的类型匹配?

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

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

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

transform的前两个备选方案失败,因为 for 循环主体中op参数的类型既不是实体操作也不是属性操作:它是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)) {...}

PS:这个定义中有一个错误:

syntax ChangeOperator
    = entityOperator: EntityOperation op
    | attributeOperator : AttributesOperations op
    | relationOperator: RelationOperations op
    | databaseOperator: DatabaseOperations op
    ;

每个op标签都应该不同,因为它们产生不同的类型:

syntax ChangeOperator
    = entityOperator: EntityOperation eop
    | attributeOperator : AttributesOperations aop
    | relationOperator: RelationOperations rop
    | databaseOperator: DatabaseOperations dop
    ;

最新更新