如何获取指向语法标记或正则表达式的指针?

jjm*_*elo 8 grammar metaprogramming mop raku

这与类的问题类似,但相同的过程似乎不适用于语法。

grammar TestGrammar {
    token num { \d+ }
}


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

say "3" ~~ $token;
Run Code Online (Sandbox Code Playgroud)

这将返回:

Type check failed in binding to parameter '<anon>'; expected TestGrammar but got Match (Match.new(:orig("3")...)
  in regex num at pointer-to-token.raku line 2
  in block <unit> at pointer-to-token.raku line 9
Run Code Online (Sandbox Code Playgroud)

这似乎表明您需要绑定到类/语法,而不是“裸”令牌。但是,尚不清楚如何做到这一点。将语法或其实例作为参数传递会返回不同的错误:

Cannot look up attributes in a TestGrammar type object. Did you forget a '.new'?
Run Code Online (Sandbox Code Playgroud)

知道为什么这实际上不起作用吗?

更新按照上述问题中引用的^find_method方式使用也不起作用。同样的问题。使用也不能解决问题。assuming

更新 2:我似乎有所进展:

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

say "33" ~~ $token;
Run Code Online (Sandbox Code Playgroud)

不会产生任何语法错误,但False无论如何它都会返回。

rai*_*iph 2

您在代码末尾缺少一个参数:

grammar TestGrammar {
    token num { \d+ }
}

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

say "3" ~~ $token($test-grammar.new: orig => $_);
                 ^^ -- the missing/new bit -- ^^
Run Code Online (Sandbox Code Playgroud)

我相信你或多或少可以把这个论点收起来——但.assuming立即具体化/评估所假设的论点,这样就不会成功。相反,我们需要推迟该步骤,直到智能匹配调用(以获取$_智能匹配调用期间的状态)。


我们需要更改$token声明和调用。我能想到的有两种可能性:

  • 坚持$token

    更改其声明,并将其使用转变~~为方法调用:

    my $token = { $test-grammar.^lookup('num')($test-grammar.new: orig => $_) }
    
    say "3" ~~ .$token;
               ^ insert dot to make it a method call with `$_` as invocant
    
    Run Code Online (Sandbox Code Playgroud)
  • 切换到&token

    现在智能匹配线上不再需要点了。更好的是,你可以删除印记:

    my &token = { $test-grammar.^lookup('num')($test-grammar.new: orig => $_) }
    
    say "3" ~~ .&token; # Same as:
    say "3" ~~  &token; # Same as:
    say "3" ~~   token;
    
    Run Code Online (Sandbox Code Playgroud)

对您的问题的正确回答应该确实为这三个问题提供了一个不错的答案:

  • 为什么必须传递一个新的语法对象?

  • 这是什么orig生意?

  • 怎么会有人知道这一点?

我不会回答这些问题,至少今晚不会充分回答,也许永远不会。(我记得几年前进行过调查,并陷入了 Rakudo 代码的泥潭。)

根据记忆,我的工作假设可以归结为:

  • 正则表达式/语法机制有一个基本方面,其中它假定在开始时设置匹配/语法对象(然后在匹配发生时传递到子规则)。

  • 对于如何发生,使用my和 声明的方法/规则之间存在差异。has(大概self是绑定的。)

  • 这种差异意味着用户代码必须处理您的问题所涵盖的场景中的这种差异。