Представьте себе ряд сложных грамматик, представленных в виде ролей, хотя этот простой пример достаточно, чтобы показать конфликт:Должен ли Perl 6 распутать включение одной и той же роли из разных источников?
role Alpha {
token alpha { :i <[A..Z]> }
}
role Digit {
token digit { <[0..9]> }
}
role Either
does Alpha
does Digit {
token either { <alpha> | <digit> }
}
grammar Thingy
does Either
does Alpha
{
token TOP { <alpha> <either>* }
}
my $match = Thingy.parse('1a3');
dd $match;
Это не работает, потому что Perl 6 не распутать отношения, чтобы выяснить, что конфликт на самом деле то же самое из того же источника:
Метод «альфа» должен быть решен класса Thingy, поскольку она существует в нескольких ролях
Но, читая S14, я вижу:
Роль не может наследоваться от класса, но может состоять из других ролей. Однако этот состав «крона» не оценивается до времени композиции композиции. Это означает, что если две роли приносят один и тот же crony, нет конфликта - это похоже на то, что класс потянул на себя роль crony и соответствующие роли не сделали. Роль никогда не может противоречить самому себе, независимо от способа его включения.
Я читал, что означает, что роли применяются как можно позже, так что класс Thingy
сможет распутать, что Alpha
входит в двух различных частей. Я полагал, что это сработает как создание списка всех ролей, которые будут составлять последний класс, а затем применить этот список только к конечному классу. Таким образом, что-то вроде Either
будет смешивать только те вещи, которые он определил, и будет полагаться на более позднюю композицию, чтобы ввести Alpha
.
Я столкнулся с этим, когда я пытался реализовать грамматики для различных (IETF) RFC. Многие из них ссылаются на грамматики из других RFC, что делает невозможным разрешение Perl 6 наследованием на C3. Итак, я понял, что роли будут отключать отношения. По-видимому, это не так.
Имеет ли это что-то особенное для грамматик? Следующие не выполняются одинаково (и как ожидалось): 'perl6 -e 'role Foo {method bar {}}; role Baz {method bar {}}; class My :: Грамматика {также делает Foo; также Баз; } '' В противном случае вы можете, конечно, решить его самостоятельно (это указано в документах для ролей):' token Host {$ = <Грамматика :: IETF :: URI :: RFC3986 :: host> [' : '<.port>]? } ' –
ugexe
Это не принципиально специфично для грамматик, но гораздо более полезно там для названных правил, которые могут отображаться в нескольких частях грамматик. Я бы предпочел не разрешать вещи сам, потому что это огромный беспорядок, когда грамматики огромны. –
Ответ на вопрос в заголовке «Да, это должно». –