Perl 6 Regex匹配Perl 6分隔注释

问题描述 投票:7回答:1

任何人都有一个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 repo中而不需要外部依赖。

regex perl6
1个回答
4
投票

Matching your examples

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正则表达式,希望代码是不言自明的。如果您想要澄清任何一条,请使用评论。

Looking at related Rakudo source code

我在没有参考Rakudo的源代码的情况下编写了上述内容。 (我想看看我没有这么做的想法。)

但是我现在已经看过了源代码,对于那些试图做你正在尝试做的事情的人来说,这对于任何人来说都是一个或多或少的强制性事情,并且认真地理解它在一般情况下的效果。

作为我的起点,我特别感兴趣的是,如果我能弄清楚为什么要将此代码提供给rakudo(2018.12):

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

产生相当LTA(Less Than Awesome)编译器错误:

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调用有效以及为什么我在Rakudo / P6中没有找到它时查看NQP的原因)。

我将在此时停下来得出结论。

Conclusion

你有一个正则表达式。它可能会按你的意愿运作。我不知道。

如果你最终调查上面的Rakudo / NQP代码并理解它足以写出狡辩,唠叨,蚕食等等,或发现一个好的现有写作(我还没有搜索过) ,请在链接到它的答案中添加评论。我也会这样做。 TIA!

© www.soinside.com 2019 - 2024. All rights reserved.