是否可以解析一个字符串,就好像它在 Raku 中被 << 和 >> 包围一样?

cow*_*moo 4 raku

我想重用<< ... >>字符串上的解析逻辑来返回一个列表。比如说,我已经在一个变量中拥有了字符串$input,如何在不使用的情况下解析它EVAL(例如,EVAL "<< $input >>")?

一个更普遍的问题可能是:我如何重用各种引用构造(例如,qqww:v:!c)使用的任何解析逻辑?

rai*_*iph 5

对于您的特定示例,您可以使用val

my $a = 42;
say << $a b c       >>.perl;       # (IntStr.new(42, "42"), "b", "c")
say ("$a", "b", "c")>>.&val.perl;  # same
say << "$a b" c     >>.perl;       # ("42 b", "c")
say ("$a b", "c"   )>>.&val.perl;  # same
Run Code Online (Sandbox Code Playgroud)

但你必须了解val.

我想重用<< ... >>字符串上的解析逻辑来返回一个列表。

您可以查看 Rakudo 编译器的源代码以放大正在调用的函数。因此,您可能会发现这val是与您的示例相关的函数。

语言结构的解析从Grammar.nqp开始。

页面内搜索会<<产生大量匹配项。我碰巧知道该 << ... >>构造是一个“circumfix”运算符。所以几秒钟后,我在 Grammar.nqp 中解析开始的那一行。重新格式化为几行,该行归结为

token circumfix:sym«<< >>» {

  :dba('shell-quote words')

  '<<' ~ '>>'

  <nibble(
    self.quote_lang(
      self.slang_grammar('Quote'),
      "<<", ">>", ['qq', 'ww', 'v']
    )
  )>

}
Run Code Online (Sandbox Code Playgroud)

然后小道立即变冷。quote_lang在同一个源文件中有一个方法,但它显然太高了。在哪里slang_grammar定义?

如果遇到这样的死胡同,接下来要看的地方就是NQP。果然,我们在那里找到了匹配项

但是现在呢?真的,这一切都太复杂了。

一个更普遍的问题可能是:我如何重用各种引用构造(例如,qqww:v:!c)使用的任何解析逻辑?

的确。

另一种通常比钻研源代码更好的途径是阅读文档。但在这种情况下,我没有找到从qq:ww:v到的明显路径val

这导致了第三条路线 - 发布一个 SO 问题。:)


这个答案是……不完整的。但无论如何我都会按原样发布它,希望它有帮助和/或今晚或明天我有时间改进它。或者,更好的是,也许有人有更好的答案。