gpt4 book ai didi

raku - 如何在perl6中访问语法的可选部分?

转载 作者:行者123 更新时间:2023-12-04 13:25:38 25 4
gpt4 key购买 nike

作为语法的一部分,我有:

        rule EX1        { <EX2> ( '/' <EX2>)*  }

在我的 Action 课中,我写了:
    method EX1($/) {
my @ex2s = map *.made, $/.<EX2>;
my $ex1 = @ex2s.join('|');
#say "EX1 making $ex1";
$/.make($ex1);
}

因此,基本上我只是想将所有 EX2以及它们之间的 '|'而不是 '/'结合在一起。但是我的代码有些不对劲,因为它只会拾取第一个 EX2,而不是后续的。我如何找出可选的是什么?

最佳答案

TL; DR 如果rule创建了该方法期望的数据结构,则该操作方法将起作用。因此,我们将修复rule并保留该方法。

主要问题

假设EX1规则放入了一个有效的语法中;字符串已成功解析;子串ex2/ex2/ex2EX1规则匹配;并且我们已经显示了语法分析树的相应部分(通过使用语法将say的结果仅添加为.parse):

EX1 => 「ex2/ex2/ex2」
EX2 => 「ex2」
0 => 「/ex2」
EX2 => 「ex2」
0 => 「/ex2」
EX2 => 「ex2」

请注意无关的 0 =>捕获以及第二个和第三个 EX2在它们下面的缩进以及相对于第一个 EX2缩进的方式。相对于方法的假设,这是错误的嵌套结构。

布拉德对主要问题的解决方案

正如Brad++在回应此答案的第一个版本的评论中指出的那样,您可以简单地从既分组又捕获的结构( (...))切换到仅分组( [...])的结构。
    rule EX1        { <EX2> [ '/' <EX2>]*  }

现在,与上述相同的输入字符串对应的解析树片段为:
EX1 => 「ex2/ex2/ex2」
EX2 => 「ex2」
EX2 => 「ex2」
EX2 => 「ex2」
0捕获已不存在,并且 EX2现在都是同级的。有关何时以及为什么P6嵌套捕获其方式的更多讨论,请参见 jnthn's answer to Why/how ... capture groups?

您的操作方法现在应该可以工作-对于某些输入...

Håkon解决另一个可能的问题的方法

如果布拉德(Brad)的解决方案适用于某些输入,但您希望并非所有输入都适用,则部分问题可能是您的 rule<EX2>/字符之间如何匹配。

正如Håkon++在他们的答案中指出的那样,您的 rule的间距可能无法满足您的要求。

如果您不希望模式中的间距很大,则不要使用 rule。在 tokenregex中,模式中的所有空格(忽略字符串,例如 ' '内)仅是使您的模式更具可读性,并且相对于匹配的任何输入字符串都没有意义。如有疑问,请使用 token(或 regex)而不是 rule:
token EX1 { <EX2> ( '/' <EX2>)* }
🡅 🡅 🡅 🡅 🡅 🡅
🡅指示的间距不重要。您可以忽略它或对其进行扩展,这对规则与输入的匹配方式没有影响。这只是为了提高可读性。

相反, rule构造的全部要点是模式中每个原子和每个量词后面的空格是 significant。这样的间隔在输入中的相应子字符串之后隐式地应用(用户可覆盖)边界匹配规则(默认情况下,该规则允许空格和/或“单词”和非“单词”字符之间的过渡)。

在您的 EX1规则中(为确保清晰起见,我在下面以夸大的间距重复此规则),其中一些间距并不重要,就像在 tokenregex中没有一样:
     rule EX1        {  <EX2>   (  '/'  <EX2>)*   }
🡅 🡅 🡅

像以前一样, 🡅表示间距并不重要-您可以省略或扩展它,并且不会有任何区别。要记住的是,模式(或子模式)开始处的空格只是为了提高可读性。 (使用经验表明,如果不将任何间距视为有效间距,效果会更好。)

但是原子或量词后面的间距或缺少间距很重要:
This spacing is significant: ⮟      ⮟        ⮟
rule EX1 { <EX2> ( '/' <EX2>)* }
This LACK of spacing is significant: ⮝⮝

通过按照您的方式编写 rule,您将告诉P6仅将输入与边界匹配(默认情况下允许空白)匹配:
  • 在第一个<EX2>之后(因此在第一个/之前);
  • /与后续 <EX2>匹配之间的
  • 最后 <EX2>匹配之后的

  • 因此,您的规则告诉P6,当 /<EX2>匹配时,该顺序应允许它们之间的空格- /,然后是 <EX2>

    但是它也告诉P6不允许在其他地方留空格-在 <EX2>匹配和 /匹配之间按此顺序!除了第一个 <EX2> '/'对! P6可以让您声明任意复杂度(包括空格)的匹配模式,但是我怀疑这是您的意思或想要的。

    有关“在原子之后”的含义的完整列表(即 rule中的空格很重要),请参阅 When is white space really important in Perl6 grammars?

    此重要的间距特征是:
  • Classic Perl DWIMery旨在使生活更轻松;
  • 惯用语-用于大多数语法,因为它确实确实使生活更轻松;
  • 存在rule声明符的唯一原因(这个重要的空白是ruletoken之间的唯一区别);
  • 完全可选,因为您可以只使用token

  • 如果阅读此内容的人认为他们不愿意利用此重要的空间功能,则可以使用 token代替。 (这反过来可能会导致他们了解为什么 rule作为选项存在,然后,或者也许以后,了解为什么它以这种方式工作,并重新欣赏其DWIMery。:))

    您要匹配的模式的内置构造

    最后,这是编写您要匹配的模式的惯用方式:
    rule EX1        { <EX2> + % '/' }

    这告诉P6匹配由 <EX2>字符分隔的一个或多个 /。请参阅 Modified quantifier: % , %% ,以获取有关此良好构造的说明。

    这仍然是 rule,因此其中的大部分间距仍然很重要。 The precise details for when it is and isn't最明显地适用于此构造,因为它最多包含三个有效的间隔符,而另一个不是:
    NOT significant:  ⮟                 ⮟
    rule EX1 { <EX2> + % '/' }
    Significant: ⮝ ⮝ ⮝

    +之前和之后包含空格是多余的:
         rule EX1   {   <EX2>    +    %    '/'   }
    rule EX1 { <EX2> +% '/' } # same match result
    rule EX1 { <EX2>+ % '/' } # same match result

    关于raku - 如何在perl6中访问语法的可选部分?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56996519/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com