Регулярное выражение Perl 6 для соответствия комментарию с Perl 6 - PullRequest
0 голосов
/ 01 марта 2019

У кого-нибудь есть регулярное выражение 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 довольно просто, но комментарии с разделителями требуют дополнительной утонченности.Я также хочу, чтобы это решение было небольшим и использовало только ядро ​​Perl 6, чтобы я мог вставить его в репозиторий dotfiles без внешних зависимостей.

1 Ответ

0 голосов
/ 02 марта 2019

Соответствие вашим примерам

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 (Less Than Awesome):

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

Это не выглядит напрямую относящимся к вашему вопросу, но я столкнулся с ним при попытке понятьправила вложенного разделителя.

Поэтому, когда я добрался до этой части своего ответа, я начал с поиска в репо Rakudo «сразу после».Это привело к fail-terminator методу в грамматике P6.(Возможно, не интересует вас, но это мне.)

Вот что еще я обнаружил в стандартной грамматике, что IMO напрямую связано с тем, что вы пытаетесь сделать, или, по крайней мере, точно понимаете, чтоВ коде говорится, что правила касаются соответствия комментариев:

  • comment:sym<# (...)> `token , который анализирует эти комментарии.Это приводит к:

  • Список открывающих .Этот список должен заменить в моем коде только три пары «открывающий / сближающий», которые просто соответствуют вашим примерам.

  • Маркер quibble .Похоже, это общая вещь "parse 'quoted' (delimited)".Это приводит к:

  • babble токен .Это устанавливает «старт» и «останов» с этим кодом:

    $<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 (от которой наследуется грамматика Perl 6, поэтому peek_delimiters Call работает и почему я посмотрел в NQP, когда я не нашел его в Rakudo / P6).

Я остановлюсь на этом этапе, чтобы сделать вывод.

Заключение

У вас есть регулярное выражение.Это может сработать так, как вы собираетесь.Я не знаю.

Если вы в конечном итоге исследуете приведенный выше код Rakudo / NQP и понимаете его достаточно хорошо, чтобы написать обзор того, что делают придирки, лепеты, клевы и т. Д., Или обнаружите хороший существующийнаписать (я еще не искал), пожалуйста, добавьте комментарий к этому ответу, ссылаясь на него.Я сделаю так же.ТИА!

...