Функция <.ident> / перехват в грамматиках perl6 - PullRequest
0 голосов
/ 04 июня 2018

При чтении грамматики Xml для perl6 (https://github.com/supernovus/exemel/blob/master/lib/XML/Grammar.pm6), У меня возникают некоторые трудности с пониманием следующего токена.

token pident {
  <!before \d> [ \d+ <.ident>* || <.ident>+ ]+ % '-'
}

Более конкретно <.ident>, других определений, поэтому я предполагаю, что это зарезервированный термин. Хотя я не могу найти правильное определение на perl6.org. Кто-нибудь знает, что это значит?

Ответы [ 2 ]

0 голосов
/ 04 июня 2018

Кто-нибудь знает, что означает [<.ident>]?

Во-первых, как отметил jj, <.ident> только соответствует, он не захватывает, из-за .,В оставшейся части этого ответа я обычно опускаю ., потому что он не имеет значения для значения правила, кроме аспекта захвата.

<ident> в коде, который вы цитировали, называет "правило", котороеделает эквивалент:

token ident {
    [ <alpha> ]   # First character can't be a number
    [ <alnum> ]*  # Other characters can be a number
}

То, что говорит официальный документ

Официальный документ в действительности говорит:

    Predefined Character Class...     Matches...
    <ident>                           Identifier. Also a default rule.

Но этовводит в заблуждение док.

  • Это не класс персонажей.(Правила класса символов соответствуют одному символу в этом классе символов. <ident> соответствует одному или нескольким символам, которые соответствуют шаблону, хотя и включает в себя классы символов.)

  • Все правила по умолчаниюправила.(Я думаю, что комментарий по умолчанию здесь для того, чтобы подчеркнуть, что вы можете написать свое собственное правило <ident>, если вам не нравится встроенный шаблон, что тоже верно, но в целом гораздо менее чувственно для правил, которые соответствуют классам канонических символов, таким какas <lower>.)

  • Не соответствует идентификаторам или, точнее, не соответствует многим идентификаторам Perl6.(См. Как правило <ident> используется при сопоставлении идентификаторов Perl 6 в конце этого ответа для объяснения того, что он делает как part сопоставления идентификатора.)

Остальная часть этого ответа

Не стесняйтесь считать этот вопрос достаточным ответом и переходите к чему-то другому.Для тех, кто интересуется подробностями, я написал следующие разделы:

  • Логика высокого уровня, которую вызывает Правило <ident>

  • Логика среднего уровня, которая в <ident> правило

  • Код машинного уровня, который реализует <ident>rule

  • Спецификация правила <ident>

  • Как правило <ident> используется в соответствующем Perl6 идентификаторы

Логика высокого уровня, которая вызывает <ident> rule

Инструкция grammar XML::Grammar вводит пользовательскую грамматику Perl 6.

Грамматика - это класс.( «Грамматика - это на самом деле просто немного специализированные классы» .)

A rule - это метод.(say rule { ... } ~~ Method; # True.)

Любой класс, созданный с помощью объявления вида grammar foo { ... }, наследует класс Grammar, который, в свою очередь, наследует класс Match.

ВКомпилятор Rakudo Perl 6, класс Match does роль NQPMatchRole.

NQPMatchRole включает ident правило (в данном случае с регулярным объявлением method).

Поскольку grammar XML::Grammar не объявляет правило ident, вызов <ident> отправляет методу в NQPMatchRole следующий за нормальным методомлогика диспетчеризации.

логика среднего уровня, которая содержится в правиле <ident>

NQPMatchRole, написана на языке nqp, подмножество Perl 6 используется для начальной загрузки полного Perl 6, исердце NQP , инструментария компилятора.

Извлечение и переформатирование только самого заметного кода из объявления ident метода, написанного на nqp, правило начинается с:

(    nqp::ord($target, $!pos) == 95
  || nqp::iscclass(nqp::const::CCLASS_ALPHABETIC, $target, $!pos)   )

Это соответствует, если первый символ либо _ (95 является кодом ASCII / Unкодовая точка icode для подчеркивания) или символ, соответствующий классу символов, определенному в NQP, называемому CCLASS_ALPHABETIC.

Другой важный бит кода:

nqp::findnotcclass( nqp::const::CCLASS_WORD

Это соответствует нулю или более последующие символы в классе символов CCLASS_WORD.

A поиск NQP для CCLASS_ALPHABETIC показывает несколько совпадений.Наиболее полезным представляется файл теста NQP .Хотя этот файл проясняет, что CCLASS_WORD является надмножеством CCLASS_ALPHABETIC, он не дает понять, с чем на самом деле совпадают эти классы.

Код машинного уровня, реализующий правило <ident>

NQP предназначается для нескольких «бэкэндов» или конкретных виртуальных машин.

Учитывая относительную нехватку документации / тестов Rakudo / NQP относительно того, что эти правила и классы символов фактически совпадают, нужно взглянуть на один из этих бэкэндов.чтобы проверить, что к чему.

MoarVM является единственным формально поддерживаемым бэкэндом.

A Поиск MoarVM для CCLASS показывает несколько совпадений.

Важным представляется ops.c , который включает в себя оператор switch (cclass) , который в свою очередь включает в себя случаи для MVM_CCLASS_ALPHABETIC и MVM_CCLASS_WORD, которые соответствуют NQPконстанты с одинаковыми именами.

Согласно комментариям кода:

CCLASS_ALPHABETIC в настоящее время соответствует точно тем же символам, что и полное правило Perl 6 или NQP <:L>, т.е.символы Unicode классифицируются как «Буквы».

Я думаю, это означает, что <alpha> эквивалентно объединению CCLASS_ALPHABETIC и _ (подчеркивание).

CCLASS_WORD совпаденийтот же плюс <:Nd>, то есть десятичные цифры (вy человеческий язык, а не только английский).

Я думаю, это означает, что полное правило Perl 6 level / NQP <alnum> эквивалентно CCLASS_WORD.

Спецификация <ident>правило

Официальная спецификация Perl 6 воплощена в жареном 1 .

A Поиск жареного мяса для ident показывает несколько совпадений.

Большинство используют <ident> только случайно.Спецификация требует, чтобы они работали, как показано, но вы не поймете, что <ident> должен делать, взглянув на случайное использование.

Три теста явно проверяют сам <ident>.Один из них по сути избыточен, оставляя два.Я не вижу изменений между 6.c и 6.c.errata версиями этих двух матчей:

С S05-mass / rx.t :

ok ('2+3 ab2' ~~ /<ident>/) && matchcheck($/, q/mob<ident>: <ab2 @ 4>/), 'capturing builtin <ident>';

ok проверяет, что его первый аргумент возвращает True.Этот вызов проверяет, что <ident> пропускает 2+3 и соответствует ab2.

From S05-mass / charsets.t :

is $latin-chars.comb(/<ident>/).join(" "), "ABCDEFGHIJKLMNOPQRSTUVWXYZ _ abcdefghijklmnopqrstuvwxyz ª µ º ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö øùúûüýþÿ", 'ident chars';

isпроверяет, что его первый аргумент соответствует второму.Этот вызов проверяет соответствие правила ident из строки, состоящей из первых 256 кодовых точек Unicode (набор символов Latin-1).

Вот вариант этого теста, который более четко показывает соответствие, которое происходит:

say ~$_ for $latin-chars ~~ m:g/<ident>/;

печатает:

ABCDEFGHIJKLMNOPQRSTUVWXYZ
_
abcdefghijklmnopqrstuvwxyz
ª
µ
º
ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ
ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö
øùúûüýþÿ

<ident> на самом деле соответствует намного больше, чем сто или около того символов из Latin-1.Итак, хотя вышеприведенные тесты охватывают то, что <ident> является официально указанным / протестированным для соответствия, они явно не охватывают полную картину.

Итак, давайте рассмотрим другой источник, который обычно ассоциируетсяс «спецификацией», историческими проектными документами Perl 6 .

Сначала отметим предупреждение в верхней части проектных документов:

Note: these documents may be out of date.
For Perl 6 documentation see docs.perl6.org;
for specs, see the official test suite.

Термин "specs "в этом предупреждении является сокращением от" specification ".Как уже объяснялось, официальный набор тестов спецификаций является жарким.

(Некоторые люди до сих пор думают об этих исторических документах по дизайну как о «спецификациях» и называют их «спецификациями», но более подходящим способомДело в том, что «спецификации» в применении к проектным документам являются сокращением от «спекуляций» или, возможно, «ложной бессмыслицы», если первые не дают достаточно ясного объяснения тому, что на них нельзя полностью положиться.)

A поиск ident в design.perl6.org показывает несколько совпадений.

Самое полезное совпадение в Предопределенные подправления section S05 :

Вот некоторые из предопределенных подправил для любой грамматики или регулярного выражения:

  • ид ... Соответствует идентификатору.

Итак, теперь мы видим, откуда документы получили свое значение значения <ident>.

Как правило <ident> используется при сопоставлении идентификаторов Perl 6

my @Identifiers = < $bar %hash Foo Foo::Bar your_ident anothers' my-ident >; 
say (~$/ if m/^<ident>$/ for @Identifiers); # (Foo your_ident)
say (~$/ if m/ <ident> / for @Identifiers); # (bar hash Foo Foo your_ident anothers my)

В грамматике nqp, которая определена в NQP's Grammar.nqp , есть:

token identifier { <.ident> [ <[\-']> <.ident> ]* }

В грамматике Perl 6, которая определена в Grammar.nqp Ракудо, есть код, который выглядит немного по-другому, но имеет тот же эффект:

token apostrophe { <[ ' \- ]> }
token identifier { <.ident> [ <.apostrophe> <.ident> ]* }

Так что <identifier> соответствуетшаблон, который включает один или несколько <ident> s.

Метод ident находится в NQPMatchRole, что означает, что он является встроенным и является частью пространства имен правил пользовательских грамматик.

Методы identifier не экспортируются ни Perl 6, ни nqp, поэтому они не являются частью пространства имен правил пользовательских грамматик.

Если я напишу свой собственный токен indentifier, мы увидимэто в действии:

my token identifier { <.ident> [ <[\-']> <.ident> ]* }
my token sigil { <[$@%&]> }
say (~$/ if m/^ <sigil>? <identifier> $/ for @Identifiers)

отображает:

($bar %hash Foo your_ident my-ident)

Подводя итог вышесказанному и некоторые другие соображения:

  • <ident> соответствует просточасти того, что соответствует <identifier> (хотя для простейших имен они одинаковы).Рассмотрим is-prime, который является идентификатором Perl 6, но содержит два <ident> совпадения;

  • <identifier> соответствует только частям "идентификаторов Perl 6" (хотя они одинаковы длясамые простые имена).Рассмотрим infix:<+>, который иногда также называют идентификатором Perl 6, но требует совпадения <identifier> и сопоставления с образцом двоеточия;

  • Идентификаторы Perl 6 соответствуют только частям имен(хотя они одинаковы для самых простых имен).Рассмотрим Foo-Bar::Baz-Qux, который содержит два <identifier> совпадения (каждое по очереди содержит два <ident> совпадения).


1 Официальная спецификация Perl6 - набор тестов, называемый roast - R epository O f A ll S pecification T ests,Последняя версия определенной ветки roast определяет конкретную версию Perl 6. До сих пор существовало только две официальные ветви / версии roast и, следовательно, Perl 6.первый был / есть 6.c он же 6.Christmas.Это было сокращено в Рождество 2015 и было намеренно оставлено замороженным с того дня.Второй - 6.c.errata, который очень консервативно добавляет исправления к 6.c, которые считаются достаточно совместимыми и / или слишком важными, чтобы не быть доступными как текущая официальная рекомендуемая версия Perl 6 .«Официально совместимый» компилятор Perl 6 проходит некоторую официальную ветку roast.Компилятор Rakudo проходит 6.c.errata.

Если вы прочитаете все тесты, включающие функцию, скажем, в ветке 6.c.errata roast, то вы официально прочитаете полное определение указанное значение этой функции для 6.c.errata версии языка Perl 6.

0 голосов
/ 04 июня 2018

В общем, место для поиска документации Документация Perl6 .Это часть регулярного выражения, , и вы можете найти его в определении классов символов .Соответствует идентификаторам Perl6.. перед ident делает для подавления захвата .

...