You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取Raku语言中Grammar的token或regex的指针?

Raku中调用Grammar实例的token方法失败的原因

这个问题和类方法调用的类似场景逻辑不同,直接用Grammar实例的^lookup获取token后调用会触发类型错误。

测试代码

grammar TestGrammar {
    token num { \d+ }
}

my $test-grammar = TestGrammar.new();
my $token = $test-grammar.^lookup('num');

say "3" ~~ $token;

运行错误信息

Type check failed in binding to parameter ''; expected TestGrammar but got Match (Match.new(:orig("3")...)
in regex num at pointer-to-token.raku line 2
in block at pointer-to-token.raku line 9

这个错误说明token需要绑定到Grammar实例上下文,而非直接调用“裸”token方法引用。但尝试传入Grammar类型对象或实例时,又会触发另一个错误:

Cannot look up attributes in a TestGrammar type object. Did you forget a '.new'?


更新记录

更新:尝试使用^find_method方法,报错情况和之前一致;用assuming绑定实例也无法解决问题。

更新2:调整代码后不再报语法错误,但无论输入什么内容都返回False:

my $token = $test-grammar.^lookup('num').assuming($test-grammar);

say "33" ~~ $token;

原因分析与解决方法

在Raku中,Grammar里的token本质是方法,但它的调用逻辑和普通方法存在差异:token在匹配时,Raku会自动处理Grammar实例、Match上下文等隐式参数的传递,而通过^lookup直接获取的方法引用没有正确绑定这些必要的上下文。

当使用~~操作符时,它期望右侧是一个可直接执行的匹配器,而非未绑定上下文的方法引用。正确的实现方式有两种:

写法1:直接调用实例的token

grammar TestGrammar {
    token num { \d+ }
}

my $test-grammar = TestGrammar.new();
say "3" ~~ $test-grammar.num; # 输出True

写法2:获取绑定实例的方法引用

如果需要先保存token的引用再调用,可以用&语法绑定实例上下文:

grammar TestGrammar {
    token num { \d+ }
}

my $test-grammar = TestGrammar.new();
my $token = &($test-grammar.num);

say "33" ~~ $token; # 输出True

为什么assuming无效?

assuming只能绑定显式定义的参数,但token的调用还依赖隐式的Match上下文参数。~~操作符会把左侧字符串包装成Match对象传递给token,而用assuming绑定实例后,参数顺序和token期望的上下文结构不匹配,最终导致匹配失败。

内容的提问来源于stack exchange,提问作者jjmerelo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 17:05:18