lov*_*ato 10 grammar alias raku
我写了一个这样的语法:
grammar StatementFormat {
token TOP { (<plain> | '%' <placeholder>)* }
token plain { <-[%]> }
token placeholder {
| <verb>
| <noun>
| <adverb>
}
token verb {
'v'
{
# some actions
}
}
token noun {
'n'
{
# some actions
}
}
token adverb {
'a'
{
# some actions
}
}
}
Run Code Online (Sandbox Code Playgroud)
所以我可以用它来解析像“someone %v %n %a”这样的字符串。
但是,我发现有很多像“%v %n %a”这样的用法,我想给它一个别名,比如“%b”,这样解析“someone %b”就相当于解析“someone %” v %n %a”。
那么有没有办法做到这一点?
当然token alias { 'b' { ... } }可以做到。但是那样我需要重复那个动作代码。我想知道是否存在更简单的方法。
mor*_*itz 11
因此,有一种显而易见的方法,即简单地将操作的代码放入子例程中,然后在b别名中调用它们:
sub verb-action($/) { }
sub noun-action($/) { }
sub adverb-action($/) { }
grammar StatementFormat {
# rest goes here
token verb {
'v'
{ verb-action($/) }
}
token noun {
'n'
{ noun-action($/) }
}
token adverb {
'a'
{ adverb-action($/) }
}
token alias {
'b'
{
verb-action($/);
noun-action($/);
adverb-action($/);
}
}
}
Run Code Online (Sandbox Code Playgroud)
但那有什么乐趣呢?
相反,我建议你使用内置的一个ction对象语法的特点。
它是这样的:你有一个单独的类,将动作作为方法,与语法动作同名:
class StatementFormatActions {
method verb($/) { ... }
method noun($/) { ... }
method adverb($/) { ... }
}
Run Code Online (Sandbox Code Playgroud)
当您调用 时parse,您将传递该操作类的一个实例:
StatementFormat.parse($string, :actions(StatementFormatActions.new));
Run Code Online (Sandbox Code Playgroud)
那么在引入aliastoken的时候,也可以引入一个alias方法:
method alias($/) {
self.verb($/);
self.noun($/);
self.adverb($/);
}
Run Code Online (Sandbox Code Playgroud)
在操作中,您还可以调用make或$/.make(...)将操作的结果附加到匹配对象(然后在 中可用$/.made)以从解析树填充 AST。
(你可能也喜欢我的语法书,它有几个例子和更深入的解释。对不起,插件,无法抗拒)。