与Perl 6分隔注释匹配的Perl 6正则表达式

时间:2019-03-01 04:12:40

标签: regex perl6

有人有一个与Perl 6分隔注释匹配的Perl 6正则表达式吗?我更喜欢简短而不是完整的语法,但我不排除任何限制。

作为我要寻找的内容的示例,我想要一些可以在此处解析注释的内容:

#`{ foo {} bar }
#`« woo woo »
say #`(
This is a (
long )
multiliner()) "You rock!"
#`{{ { And don't forget the tricky repeating delimiters }}

我的总体目标是能够获取源文件并删除pod和注释,然后使用剩下的代码来做有趣的事情。删除行注释和pod很容易,但是分隔注释需要额外的技巧。我还希望该解决方案较小,并且仅使用Perl 6内核,因此我可以将其粘贴到我的dotfiles存储库中,而无需外部依赖。

1 个答案:

答案 0 :(得分:4)

匹配您的示例

my %openers-closers = < { } « » ( ) >;        # (many more in reality)
my @openers         = %openers-closers.keys;  # { « ( ...
my ($open, $close);                           # possibly multiple chars

my token comment { '#`' <&open> <&middle> <&close> }

my token open {
  # Store first delimiter char:   Slurp as many as are repeated:
  ( ( @openers )                  $0* )

  # Store the full (possibly multiple character) delimiters:
  { $open = ~$0; $close = %openers-closers{$0[0]} x $0.chars }
}

my token middle {
  :my $nest-level; # for tracking nesting
  [
    # Continue if nested:  or if not at unnested end delimiter:
    [ <?{$nest-level}>     ||    <!&close> ]

    # Match either a nested delimiter:  or a single character: 
    ( $open || $close                   || . )

    # Keep track of nesting:
    { $_ = ~$0.tail; # set topic to latest match in list 
      $nest-level++ when $open; $nest-level-- when $close } 
  ]*
}

my token close { $close }

.say for $your-examples ~~ m:g / <.&comment> /

显示:

「{ foo {} bar }」
「« woo woo »」
「(
This is a (
long )
multiliner())」
「{{ { And don't forget the tricky repeating delimiters }}」

如果您知道P6正则表达式,则代码是不言自明的。如果您想对任何注释进行澄清,请使用注释。

查看相关的Rakudo源代码

我在上面编写时没有提到Rakudo的源代码。 (我想看看我没有想到的是什么。)

但是我现在看了一下源代码,对于任何想做自己想做的事情的人来说,imo或多或少都是必做的事情,并且认真地理解它在一般情况下的工作情况情况。

从我的出发点开始,我对是否能弄清楚为什么将此代码提供给rakudo(2018.12)特别感兴趣:

#`{{ {{ And don't forget the tricky repeating delimiters  } }}

产生相当的LTA(小于真棒)编译器错误:

Starter {{ is immediately followed by a combining codepoint...

这看起来与您的问题没有直接关系,但是在尝试了解嵌套的定界符规则时遇到了它。

因此,当我到达答案的这一部分时,我首先在Rakudo存储库中搜索“立即关注”。这导致了P6语法中的fail-terminator method。 (也许您不感兴趣,但对我来说却如此。)

这是我在标准语法中发现的其他内容,即imo与您要尝试执行的操作直接相关,或者至少准确地理解了代码中有关匹配注释的规则的内容:

  • 解析这些注释的comment:sym<#(...)>` token。这导致:

  • list of openers。此列表应替换我的代码中与您的示例相匹配的3个开门器/关闭器对。

  • quibble token。这似乎是一个通用的“解析”(加引号)(定界)的东西”。它导致:

  • babble token。这将使用以下代码建立“开始”和“停止”:

    $<B>=[<?before .>]
    {
        # Work out the delimiters.
        my $c := $/;
        my @delims := $c.peek_delimiters($c.target, $c.pos);
        my $start := @delims[0];
        my $stop  := @delims[1];
    

规则peek_delimiters不在P6语法文件中。

在Rakudo回购中的搜索显示它不在Rakudo或P6中的任何地方。

在NQP中进行搜索会在nqp的语法中产生a routine(Perl 6语法从中继承),这就是peek_delimiters调用起作用的原因,也是为什么我在NQP中找不到NQP的原因Rakudo / P6)。

我将在此处停止结论。

结论

您有一个正则表达式。它可能会按预期工作。我不知道。

如果您最终对上面的Rakudo / NQP代码进行了调查,并且对它的理解程度足够高,可以逐步了解如何进行古怪,ba不休,轻咬等操作,或者发现现有的良好写法(我没有搜索过)一个),请在此答案的链接上添加评论。我也会照做。 TIA!