如何为语法的动作类添加默认方法?

Håk*_*and 8 grammar perl6 raku

最近,我尝试了一些语法来修改文件的小部分.在那些测试用例中,我会保留大部分文件,只是在这里和那里修改小块,请参阅 评论问题的示例.

所以我需要一个(或几个)动作方法(即语法的动作类中的方法),我将使用其make方法将文件的修改部分附加到匹配对象.问题是语法本身会有更多令牌/规则/正则表达式与复杂的嵌套.因此,需要将(通过连续调用make())小变化(当前附加到令牌的匹配对象)传播 到TOP()动作类中的方法,使得文件中的所有其他(所有其他标记/规则/正则表达式)都是语法.parse()呼叫返回的结果保持不变.

因此,除了一个之外,action类中的所有方法都采用完全相同的形式:

method make-data ($match-data) {
    $match-data.make( [~] $match-data.chunks.map: {$_.value.?made // $_.value} );
}
Run Code Online (Sandbox Code Playgroud)

现在,对于所有动作方法,显式重复相同的代码在我看来非常冗长,并且还打破了DRY编程原则.

有没有办法告诉语法类,如果没有指定一个动作方法(对应于语法中的一个标记),它将默认为make-data上面的方法(或类似的方法)?

所以在这种情况下,我设想了DEFAULT()动作类中的一个方法:

method DEFAULT ($match-data) {
    $match-data.make( [~] $match-data.chunks.map: {$_.value.?made // $_.value} );
}
Run Code Online (Sandbox Code Playgroud)

如果语法类中的标记在动作类中没有相应的方法,则调用该方法.

dwa*_*ing 10

Perl 6的Type系统将调用FALLBACK方法,如果它存在于类中并且进行了未知的方法调用.

以下解决方案将默认构造方法添加到Calculationsactions类.

grammar Calculator {
    token TOP { [ <add> | <sub> ] }
    rule  add { <num> '+' <num> }
    rule  sub { <num> '-' <num> }
    token num { \d+ }
}

class Calculations {
    method ws($) {}
    method FALLBACK($token, $match-data) {
        $match-data.make( [~] $match-data.chunks.map: {
            $_.value.?made // $_.value;
        } );
    }
}

say Calculator.parse('2 + 3', actions => Calculations).made;
Run Code Online (Sandbox Code Playgroud)

  • 编辑了答案并删除了自己.^撰写.逻辑现在直接在FALLBACK方法中处理. (2认同)