mefrill,
> ПК> вне зависимости от того, как были определены идентификаторы F, G, A и B ранее, выражение:
> ПК>> ПК>F(G<A, B>(7));
> ПК>
> ПК>в соответствии с описанными правилами, будет всегда распознано как вызов F с одним аргументом, являющимся вызовом generic метода с двумя аргументами-типами (A и B), плюс одним "обычным" аргументом (7).
>
> ПК>А раз знания о "смысле" идентификаторов не требуется, то и тезис о способе образования идентификаторов, процитированный чуть выше, насколько я вижу, к вопросу Влада не относится.
>
> ПК>В процитированном фрагменте стандарта C# я не увидел ничего, что не может быть описано с помощью КС-грамматики, хотя, конечно, получившаяся грамматика будет изрядно громоздкой.
> Вот здесь, видимо, я уже ошибся. Из приведенного фрагмента стандарта я понял, что проблема заключается в том, как интерпретировать фрагмент
> > F(G<A, B>(7));
>
Да, собственно говоря, очень любопытный пример, т.к. и C#, и C++ в силу сходного синтаксиса неизбежно сталкиваются с одной и той же проблемой. Но решили эту неоднозначность авторы C# и авторы C++ по-разному.
> И главная трудность состоит в том, что без знания типа объекта, представленного в тексте программы именем G, мы не можем правильно провести интерпретацию данного фрагмента. Если тип G это имя некоторого объекта, то понятно, что G < A это операция меньше, примененная к двум объектам с именами G и A. Если же, G это имя параметрического типа, то к нему, очевидно, такую операцию применить нельзя.
Это подход, принятый в C++. Более сложный для анализа компилятором, и, действительно, не поддающийся описанию контекстно-свободной грамматикой, т.к. как минимум не проще задания грамматикой предварительного объявления переменных, что сводит задачу к классике.
> Поэтому, вводя в граматику нетерминалы Generic_Type и Identifier, а также и способы их объявления мы вполне можем эту неоднозначность в грамматике преодолеть. Что-то типа:
>
> typename--> Generic_Type '<' Identifier, Identifier '>'
> expr --> typename '(' Identifier ')' | Identifier '<' Identifier | expr, expr | ...
>
> Ничего другого я и не имел ввиду. Но, вероятно, я неверно понял вопрос?
ВопросАвтор: VladD2
Дата: 22.12.04
Влада был в том, приводит ли
другой способ разрешения данной неоднозначности, принятый в C# 2.0, к невозможности описать язык контекстно-свободной грамматикой.
"Смысл" данной конструкции в C# 2.0 определяется не "значением" идентификаторов, а только тем, какая лексема стоит за закрывающей угловой скобкой. Если это одно из следующего:
( ) ] : ; , . ? == !=
то неоднозначность разрешается в пользу того, что выражение в уголках является аргументами generic типа.
If a sequence of tokens can be parsed (in context) as a simple-name (§14.5.2), member-access (§14.5.4), or
pointer-member-access (§25.5.2) ending with a type-argument-list (§26.5.1), the token immediately following the closing > token is examined. If it is one of
( ) ] : ; , . ? == !=
then the type-argument-list is retained as part of the simple-name, member-access or pointer-member-access and any other possible parse of the sequence of tokens is discarded.
Чтобы совсем уж прояснить ситуацию, можно рассмотреть простой пример:
F(G<A, B>(7));
в C# 2.0 не будет разобрано как:
F( (G<A), (B>(7)) );
даже если G, A и B являются именами переменных типа int. В этом случае скобочки нужно будет расставить руками, т.к. без них компилятор C# 2.0 должен будет "жаловаться" на то, что G не является именем generic типа.
Вероятно смутившее '(in context)', в данной формулировке из спецификации C# означает то, что данные правила применяются только к тем случаям, где в процессе разбора мы натолкнулись на возможность
в данном месте отпарсить, скажем, G<A, B>, по-разному. Если в данном месте альтернативных способов разбора данного выражения нет, то данные правила не применяются. В частности в конце цитаты приводятся два примера, это дело иллюстрирующих:
x = F<A> + y;
всегда будет разобрано как
x = (F < A) > (+y);
т.к. после '>' не следует одна из ранее перечисленных лексем. А в выражении:
x = y is C<T> + z;
это значения не имеет, т.к. после 'y is' никакие альтернативы, приводящие к тому, что <T> не будет аргументами С, идти не могут.
Posted via RSDN NNTP Server 1.9 delta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен