Раку роллы
Правила Raku — это регулярные выражения , средства сопоставления строк общего назначения и средства синтаксического анализа языка программирования Raku , которые являются основной частью языка. Поскольку конструкции Perl по сопоставлению с образцом в течение некоторого времени превосходили возможности формальных регулярных выражений, документация Raku называет их исключительно регулярными выражениями , дистанцируя этот термин от формального определения.
Raku предоставляет расширенный набор функций Perl 5 в отношении регулярных выражений, объединяя их в более крупную структуру, называемую правилами , которая обеспечивает возможности синтаксического анализа грамматики выражений , а также действует как замыкание по отношению к их лексической области действия. [1] Правила вводятся с rule
Ключевое слово, использование которого очень похоже на определения подпрограмм. Анонимные правила могут быть введены с помощью regex
(или rx
) или просто использоваться в строке, как регулярные выражения в Perl 5, через ключевое слово m
(совпадение) или s
операторы (подстановки).
История
[ редактировать ]В «Апокалипсисе 5» , документе, описывающем предварительные проектные решения для сопоставления с образцом Raku, Ларри Уолл перечислил 20 проблем, связанных с «текущей культурой регулярных выражений». Среди них было то, что регулярные выражения Perl были «слишком компактными и «симпатичными»», «слишком сильно полагались на слишком малое количество метасимволов», «мало поддерживали именованные захваты», «мало поддерживали грамматики» и «плохая интеграция с «реальными» язык". [2]
был разработан компилятор правил стиля Raku В период с конца 2004 по середину 2005 года для виртуальной машины Parrot под названием Parrot Grammar Engine (PGE), который позже был переименован в более общий Parser Grammar Engine . PGE — это комбинация среды выполнения и компилятора грамматик в стиле Raku, которая позволяет любому компилятору на основе Parrot использовать эти инструменты для анализа, а также предоставлять правила для их среды выполнения.
Среди других функций Raku в Perl 5.10 в 2007 году была добавлена поддержка именованных захватов. [3]
В мае 2012 года эталонная реализация Raku, Rakudo , выпустила ежемесячный снимок Rakudo Star с работающим анализатором JSON , полностью построенным на правилах Raku. [4]
Изменения по сравнению с Perl 5
[ редактировать ]В регулярных выражениях Perl 5 осталось только шесть неизмененных функций:
- Литералы: символы слова (буквы, цифры и подчеркивание ) совпадают буквально.
- Захват:
(...)
- Альтернативы:
|
- Обратная косая черта:
\
- Кванторы повторения:
*
,+
, и?
, но не{m,n}
- Минимальный соответствующий суффикс:
*?
,+?
,??
Некоторые из наиболее мощных дополнений включают в себя:
- Возможность ссылаться на правила, используя
<rulename>
строить целые грамматики. - Несколько операторов фиксации, которые позволяют программисту контролировать возврат во время сопоставления.
Следующие изменения значительно улучшают читаемость регулярных выражений:
- Упрощенные группы без захвата:
[...]
, которые такие же, как в Perl 5:(?:...)
- Упрощенные утверждения кода:
<?{...}>
- Позволяет включать пробелы без сопоставления, что позволяет использовать многострочные регулярные выражения. Использовать
\
или' '
для выражения пробелов. - Расширенное форматирование регулярных выражений (Perl 5)
/x
) теперь является значением по умолчанию.
Неявные изменения
[ редактировать ]Некоторые возможности регулярных выражений Perl 5 более эффективны в Raku из-за их способности инкапсулировать расширенные возможности правил Raku. Например, в Perl 5 были операторы положительного и отрицательного просмотра вперед. (?=...)
и (?!...)
. В Раку эти же функции существуют, но называются <before ...>
и <!before ...>
.
Однако, поскольку before
может инкапсулировать произвольные правила, его можно использовать для выражения опережающего просмотра в качестве синтаксического предиката грамматики. Например, следующая грамматика выражений синтаксического анализа описывает классический неконтекстно-свободный язык. :
S ← &(A !b) a+ B
A ← a A? b
B ← b B? c
В правилах Раку это будет:
rule S { <before <A> <!before b>> a+ <B> }
rule A { a <A>? b }
rule B { b <B>? c }
Конечно, учитывая возможность смешивать правила и обычный код, это можно упростить еще больше:
rule S { (a+) (b+) (c+) <{$0.elems == $1.elems == $2.elems}> }
Однако при этом используются утверждения , которые представляют собой слегка отличающуюся концепцию в правилах Раку, но более существенно отличающуюся в теории синтаксического анализа, что делает это семантическим, а не синтаксическим предикатом. Самым важным отличием на практике является производительность. У механизма правил нет возможности узнать, каким условиям может соответствовать утверждение, поэтому оптимизация этого процесса невозможна.
Интеграция с Perl
[ редактировать ]Во многих языках регулярные выражения вводятся в виде строк, которые затем передаются библиотечным процедурам, которые анализируют и компилируют их во внутреннее состояние. В Perl 5 регулярные выражения частично выполняли лексический анализ со сканером Perl. Это упростило многие аспекты использования регулярных выражений, хотя и значительно усложнило сканер. В Раку правила являются частью грамматики языка. Для правил не существует отдельного анализатора, как это было в Perl 5. Это означает, что код, встроенный в правила, анализируется одновременно с самим правилом и окружающим его кодом. Например, можно вкладывать правила и код без повторного вызова парсера:
rule ab {
(a.) # match "a" followed by any character
# Then check to see if that character was "b"
# If so, print a message.
{ $0 ~~ /b {say "found the b"}/ }
}
Вышеупомянутое представляет собой один блок кода Raku, который содержит определение внешнего правила, внутренний блок кода утверждения и внутри него регулярное выражение, содержащее еще один уровень утверждения.
Выполнение
[ редактировать ]Ключевые слова
[ редактировать ]В сочетании с правилами Раку используется несколько ключевых слов:
- регулярное выражение
- Именованное или анонимное регулярное выражение, которое по умолчанию игнорирует пробелы в регулярном выражении.
- жетон
- Именованное или анонимное регулярное выражение, подразумевающее
:ratchet
модификатор. - правило
- Именованное или анонимное регулярное выражение, подразумевающее
:ratchet
и:sigspace
модификаторы. - прием
- Анонимное регулярное выражение, которое принимает произвольные разделители, такие как
//
где регулярное выражение принимает только фигурные скобки. - м
- Операторная форма анонимного регулярного выражения, выполняющая сопоставление с произвольными разделителями.
- мм
- Сокращение для m с
:sigspace
модификатор. - с
- Операторная форма анонимного регулярного выражения, выполняющая замену с произвольными разделителями.
- SS
- Сокращение для s с
:sigspace
модификатор. /.../
- Простое размещение регулярного выражения между косыми чертами является сокращением
rx/.../
.
Вот пример типичного использования:
token word { \w+ }
rule phrase { <word> [ \, <word> ]* \. }
if $string ~~ / <phrase> \n / {
...
}
Модификаторы
[ редактировать ]Модификаторы можно размещать после любого ключевого слова регулярного выражения и перед разделителем. Если регулярное выражение имеет имя, модификатор идет после имени. Модификаторы управляют способом анализа регулярных выражений и их поведением. Их всегда знакомят с ведущим :
характер.
Некоторые из наиболее важных модификаторов включают в себя:
:i
или:ignorecase
– Выполнять сопоставление без учета регистра.:m
или:ignoremark
– Выполняйте сопоставление без учета объединения символов.:g
или:global
– Выполните сопоставление более одного раза для заданной целевой строки.:s
или:sigspace
– Замените пробелы в регулярном выражении правилом сопоставления пробелов, а не просто игнорируйте его.:Perl5
– Рассматривайте регулярное выражение как регулярное выражение Perl 5.:ratchet
– Никогда не выполняйте возврат в правиле.
Например:
regex addition { :ratchet :sigspace <term> \+ <expr> }
Грамматики
[ редактировать ]Грамматику можно определить с помощью grammar
оператор. Грамматика — это, по сути, просто пространство имен для правил:
grammar Str::SprintfFormat {
regex format_token { \%: <index>? <precision>? <modifier>? <directive> }
token index { \d+ \$ }
token precision { <flags>? <vector>? <precision_count> }
token flags { <[\ +0\#\-]>+ }
token precision_count { [ <[1-9]>\d* | \* ]? [ \. [ \d* | \* ] ]? }
token vector { \*? v }
token modifier { ll | <[lhmVqL]> }
token directive { <[\%csduoxefgXEGbpniDUOF]> }
}
Это грамматика, используемая для определения языка Perl. sprintf
обозначение форматирования строк.
За пределами этого пространства имен вы можете использовать эти правила следующим образом:
if / <Str::SprintfFormat::format_token> / { ... }
Правило, используемое таким образом, фактически идентично вызову подпрограммы с дополнительной семантикой и побочными эффектами сопоставления с образцом (например, вызовы правил могут быть возвращены).
Примеры
[ редактировать ]Вот несколько примеров правил в Раку:
rx { a [ b | c ] (d | e) f : g }
rx { (ab*) <{ $1.size % 2 == 0 }> }
Последнее идентично:
rx { (ab[bb]*) }
Ссылки
[ редактировать ]- ^ Уолл, Ларри (24 июня 2002 г.). «Краткий обзор 5: Регулярные выражения и правила» .
- ^ Уолл, Ларри (4 июня 2002 г.). «Апокалипсис 5: Сопоставление с образцом» .
- ^ Perl 5.10 теперь доступен - Perl Buzz, заархивировано 9 января 2008 г. на Wayback Machine.
- ^ Мориц (5 мая 2012 г.). «Выпущена Rakudo Star 2012.05» .
Внешние ссылки
[ редактировать ]- Раку Грамматики — страница справочного руководства по грамматикам.
- Учебник по грамматике — учебник по грамматике в Raku.
- Краткое описание 05 — Документ стандартов, охватывающий регулярные выражения и правила Perl 6.
- Введение в регулярные выражения Perl 6 — краткое введение в регулярные выражения Perl 6.