#grammar #raku
#грамматика #raku
Вопрос:
Согласно документации, определение по умолчанию ws
метода в грамматике должно соответствовать нулю или более пробелам, если эта точка не находится внутри слова:
regex ws { <!ww> s* }
В чем разница между этим определением и следующим:
regex ws { s }
Интересно, почему утверждение нулевой ширины <!ww>
используется вместо более простого s
? Я также отмечаю, что определение по умолчанию позволяет сопоставлять нулевые пробелы, но когда это произойдет на самом деле? Не было бы более понятным, если бы оно использовалось s
вместо s*
?
Комментарии:
1. Хорошо, тогда значение по умолчанию
ws
будет соответствовать последовательным символам, которые не являются символами word и не являются пробелами (например, смайликами). Например:perl6 -e 'my $str="c[carrot]c[potato]"; say $str.split(/<!ww>s*/).elems'
дает 4. Является ли это разумным поведением?2. Ларри счел это разумным поведением по умолчанию . Идея в том, что он хорошо работает для большинства типичных грамматик, и если вы хотите что-то еще, вы просто определяете свое собственное
ws
правило.
Ответ №1:
ww
Утверждение означает, что есть символы, совпадающие w
по обе стороны от текущей точки. !
Инвертирует его, что означает <!ww>
совпадение:
- В начале строки
- В конце строки
- Когда перед текущей позицией стоит не
w
символ (например, между » » и «a») - Когда после текущей позиции есть не
w
символ (например, между «a» и » «)
Фактически, это означает, что пробел никогда не может рассматриваться как встречающийся между двумя символами слова. Однако между символами, не являющимися словами, или между символом слова и символом, не являющимся словом, могут быть пробелы.
Это следует из того, что нужно для многих языков, которые мы, возможно, захотим проанализировать. Например, рассмотрим ab cd
. Значение по умолчанию ws
будет соответствовать любой стороне
, но не будет, например, совпадать с идентификатором.
Для языков, где это не подходит, это просто вопрос переопределения значения по умолчанию ws
для всего, что нужно этому языку.