который соответствует нулю или более пробельных символов.

о, что я пытаюсь сделать.

>  my sub nplus1($n) {$n +1}
> my regex nnplus1 { ^ (\d+) &nplus1($0) $ }
> "123" ~~ &nnplus1
P6opaque: no such attribute '$!pos' in type Match...
 piojo10 нояб. 2017 г., 10:14
@EugeneBarsky Правильная версия делает, без необходимости каких-либо дополнительных изменений.
 piojo10 нояб. 2017 г., 10:02
Это забавное ведро, включая поведение, которое, я думаю, следует считать ошибкой (но это не так). Я экспериментирую с этим сейчас.
 Eugene Barsky10 нояб. 2017 г., 10:06
Я ожидаю, что это будет соответствовать «123124». Я добавил якоря в регулярное выражение.
 Håkon Hægland10 нояб. 2017 г., 10:01
Вы можете попробовать поставить саб в блок кодаmy regex nnplus1 { (\d+) { &nplus1($0)} } но это не изменит результат с 123 на 124 .. Я пока не уверен, как это сделать. Каков будет ваш ожидаемый результат / результат?
 piojo10 нояб. 2017 г., 10:18
@EugeneBarsky Я обнаружил, что YAMLish является отличным примером передовых методов грамматики / регулярных выражений. У самого исходного кода rakudo есть другой - есть один файл, который анализирует Perl 6. YAMLish находится в сети, но Леон прочитал об этом, и я нашел идеи, которые мне нужны для моего проекта. Вы можете найти его в Интернете, если вы ищете его.

Ответы на вопрос(3)

На основеРегулярная интерполяция документы, а также наответ пиоджо и комментарий Хокон Хагланда, кажется, мне удалось сделать то, что я хотел:

my sub nplus1($n) {
 $n+1;
}
my regex nnplus1 { (\d+) {} <nplus1=$(nplus1($0))> }
say "123124" ~~ &nnplus1;

Выход:

「123124」
 0 => 「123」
 nplus1 => 「124」

Или мы можем переместить{} заключить интерполированное сабвуфер:

my sub nplus1($n) {
 $n+1;
}
my regex nn,plus1 { (\d+)  <nplus1={nplus1($0)}> }
say "123124" ~~ &nnplus1;

(вывод будет таким же)

 piojo10 нояб. 2017 г., 13:15
Это интересно. С одной стороны, я не понимаю, почему ты так поступил. Это, вероятно, семантически очень похоже на мой ответ, хотя это синтаксис, который я бы не подумал попробовать. С другой стороны, я не вижу причин, чтобы не делать это таким образом. Я думаю, это зависит от содержанияnplus1, Эта функция выполняет реальные вычисления, устанавливает состояние и вызывает побочные эффекты? Если так, то да, имеет смысл называть этоsub, В моем случае, когда мне требовались средства сопоставления, которые принимали параметры, сопоставителю, как правило, просто нужно было принимать отступы различной длины, поэтому я назвал его вспомогательным.
 raiph10 нояб. 2017 г., 20:46
Вы серьезно неправильно понялиrule! В правилах, заявленных сregex или жеtoken объявления, пробелы (без кавычек) не имеют значения. Поместите их, выньте их, соответствие остается тем же. Такregex { foobar } а такжеtoken { fo ob ar } совпадать точно так же строки. Напротив, в правилах, объявленных сrule, пробел после атома является значительным. На самом деле это единственный способrule отличается отtoken, Пробел после атома вrule автоматически заменяется на<.ws> который соответствует нулю или более пробельных символов.
 Eugene Barsky10 нояб. 2017 г., 13:48
Другая цель - соответствие<pattern1> <pattern2>, гдеpattern2 зависит от точного соответствияpattern1, Эта зависимость может быть довольно сложной, поэтому было бы неудобно писать ее в регулярном выражении.
 piojo10 нояб. 2017 г., 13:26
думаю<nplus1={nplus1($0)}> дает тот же результат, что и<nplus1={$(nplus1($0))}>.
 piojo10 нояб. 2017 г., 13:15
Кстати, я думаю, у вас есть дополнительный слой$() в интерполяции, которая, кажется, ничего не делает.

что регулярные выражения являются подпрограммами. Так что не называй своего соперникаsub- быть более конкретным и назвать этоregex, Да, вы можете передать аргументыregex/token/rule, Это действительно важно делать, когда вы сопоставляете языки, которые меняют свое состояние при разборе. Например, в YAML вы можете проанализировать «data [0]: 17». После этого следующая строка может начинаться с «data [1]», но не с «data [2]». Поэтому передача дополнительной информации в качестве параметров полезна.

Также обратите внимание, что когда вы конвертируете это в регулярное выражение, некоторые вещи меняются.$n+1 примет новое значение (что неправильно). Тем не менее, простые переменные по-прежнему интерполируются, поэтому, если вы объявите это как новую переменную в теле регулярного выражения с:my $npp = ..., Но даже тогда вы обнаружите, что это все еще не работает. Когда вы добавляете вспомогательный оператор, как{say "n is $n"}вы увидите, что вы не получили допустимый параметр. Это связано с тем, что в кодоподобных контекстах без фигурных скобок (когда вы используете выражение в качестве аргумента для другого сопоставителя), rakudo не обновляет переменную сопоставления. При добавлении фигурных скобок текущая переменная соответствия пересчитывается или повторно кэшируется. Этот хак выглядит как опечатка, поэтому я предлагаю вам добавить комментарий, который объясняет пустые скобки. Окончательный код таков:

my regex nplus1($n) {
 :my $npp=$n+1;
 $npp
}
my regex nnplus1 { (\d+) {} <nplus1($0)> }
say "123124" ~~ &nnplus1;

В этом случае (который в основном является рекурсией), мне нравится держать вещи более аккуратными, изменяя данные в аргументах вместо изменения данных в теле функции:<nplus1($0+1)> вместо определения:my $npp = $n+1;.

 Eugene Barsky10 нояб. 2017 г., 11:24
Я только что проверил это, и это, кажется, не работает (или, скорее, я не понимаю что-то важное). В обоих матчах первый захват занимает всю строку, иnplus1 => 「」.
 piojo10 нояб. 2017 г., 14:03
@EugeneBarsky Это может быть различие в философии, в дополнение к синтаксису. Можно утверждать, что было бы лучше использовать помощникаsub сделать логику иregex сделать финальный матч. Но с грамматиками, вероятно, потребуется больше опыта, чтобы знать, что такое лучшие практики.
 piojo10 нояб. 2017 г., 11:26
@EugeneBarsky, я вижу. Да, это кажется странным. я думаю$0 должно быть 123 и$<nplus1> должно быть 124. Согласны? Я посмотрю, смогу ли я заставить эту работу ...
 piojo10 нояб. 2017 г., 11:32
@EugeneBarsky Я совершил большую ошибку в первый раз, но с парой простых изменений это работает. Немного о интерполяции строк с{} в регулярных выражениях это неправильно, по крайней мере, в этой ситуации. Смотрите обновленный ответ, но вам нужно поставить$n+1 в новой переменной, так что вы можете вставить это в регулярное выражение.
 Eugene Barsky10 нояб. 2017 г., 11:28
Да, это то, что я хотел. И с 123 строкой$0 должно быть 1 иnplus1($0) должно быть 2 (если мы не добавим якоря).
Решение Вопроса

<{...}> Конструкция выполняет код Perl 6 внутри регулярного выражения и оценивает результат как регулярное выражение:

my sub nplus1($n) {$n +1} my regex nnplus1 { ^ (\d+) <{ nplus1($0) }> $ } say so '23' ~~ &nnplus1; # Output: True say so '22' ~~ &nnplus1; # Output: False

Ваш ответ на вопрос