Переопределение ws в грамматике - PullRequest
6 голосов
/ 01 июня 2019

Согласно документации, вы можете переопределить токен ws в грамматике, в некоторых случаях этот токен вызывается автоматически, например:

grammar Numbers { rule TOP { \d \d } }; 
my $result = Numbers.parse("3 \n 3");
say $result.perl
# OUTPUT: «Match.new(pos => 5, made => Any, from => 0, hash => Map.new(()), orig => "3 \n 3", list => ())␤»  

Одним из преимуществ переопределения ws может быть то, что оно не будет выброшено. Хорошо, я куплю это и использую для ws точно такое же определение, которое используется внутри:

grammar Numbers { rule TOP { \d \d }; regex ws { <!ww> \s* } };
my $result = Numbers.parse("3 \n 3");
say $result<ws> # OUTPUT: «Nil␤» 

Соответствие работает, но $ result все еще отбрасывается (переопределение этого для другого токена, который не использует ws по умолчанию, будет работать). Так всегда ли ws отбрасывается?

Обновление Это, вероятно, связано с этой ошибкой Rakudo

1 Ответ

12 голосов
/ 01 июня 2019

Пробелы, которые не были захвачены, не имеют ничего общего с определением ws, а скорее с тем, как работает sigspace ("значительный пробел").

Sigspace, включенный модификатором :s и включенный по умолчанию в rule, вставляет <.ws> в соответствии с его правилами (которые можно обобщить как «после атома»). Это не захват вызова правила ws. Переопределение ws не оказывает на это никакого влияния, поскольку это свойство правила, вызывающего ws, а не самого ws.

Действительно, если мы напишем явный вызов по умолчанию <ws>:

say "1 2" ~~ /\d <ws> \d/

Это будет захватывать, вывод вышеуказанной программы:

「1 2」
 ws => 「 」
...