Может ли последовательность .(
когда-либо появляться в коде С# или VB.Net?
(Не в строках, комментариях или XML-литералах, EDIT: директива препроцессора)
Я уверен, что ответ отрицательный, но я хотел бы убедиться.
Может ли последовательность .(
когда-либо появляться в коде С# или VB.Net?
(Не в строках, комментариях или XML-литералах, EDIT: директива препроцессора)
Я уверен, что ответ отрицательный, но я хотел бы убедиться.
В грамматике появляются только те, что .
:
real-literal:
decimal-digits . decimal-digits ...
. decimal-digits ...
namespace-or-type-name:
namespace-or-type-name . identifier ...
member-access:
primary-expression . identifier ...
predefined-type . identifier ...
qualified-alias-member . identifier ...
base-access:
base . identifier
unbound-type-name:
unbound-type-name . identifier
qualified-identifier:
qualified-identifier . identifier
member-name:
interface-type . identifier
indexer-declarator:
type interface-type . this
(The... означает, что я удалил оставшуюся часть правила производства.) Ни в одном из этих случаев не существует .(
как .
, за которым следуют цифры, действительный идентификатор или ключевое слово this
.
В С# сегмент #region
позволяет любым символам следовать за ним:
#region foo.(
// this is perfectly legal C#
#endregion
Обратите внимание, что в VB.Net это не вызывает беспокойства, поскольку метка области должна быть допустимым строковым литералом, поэтому она имеет кавычки:
#Region "foo.("
' quotes required
#End Region
Он также является законным после #error
и #warn
, которые не имеют эквивалента VB.
Самая большая проблема заключается в том, что вы можете иметь любой произвольный код внутри блока #if
. В С#:
#if false
foo.( perfectly legal
#endif
В VB.Net:
#If False Then
foo.( perfectly legal
#End If
На самом деле это хуже, потому что версия VB допускает произвольные выражения, поэтому вы не можете знать, действительно ли какой-то код является VB, если вы не оцениваете выражения. Другими словами, одного парсинга недостаточно - вы тоже должны оценить.
Тем не менее, анализируя грамматику в С# Language Specification Version 4.0, Приложение B, символ .
появляется в следующих строках:
real-literal: decimal-digits . decimal-digits exponent-partopt real-type-suffixopt . decimal-digits exponent-partopt real-type-suffixopt operator-or-punctuator: one of { } [ ] ( ) . , : ; namespace-or-type-name: namespace-or-type-name . identifier type-argument-listopt member-access: primary-expression . identifier type-argument-listopt predefined-type . identifier type-argument-listopt qualified-alias-member . identifier base-access: base . identifier unbound-type-name: unbound-type-name . identifier generic-dimension-specifieropt qualified-identifier: qualified-identifier . identifier member-name: interface-type . identifier indexer-declarator: type interface-type . this [ formal-parameter-list ]
Так как a .
всегда следует десятичной цифрой, идентификатором или маркером this
, единственный способ иметь последовательность .(
- это позволить нескольким символам operator-or-punctuator
рядом друг с другом. Смотря вверх operator-or-punctuator
, мы видим:
token: operator-or-punctuator
Так как token
используется только в лексическом анализе, нечего утверждать, что a .
является законным, за которым следует (
в регулярном коде.
Конечно, это все равно оставляет комментарии, литералы и т.д., которые я оставляю, потому что вы уже знаете об этом.
Никакая ссылка на грамматику и полностью ненаучная, но здесь моя догадка:
.(
не является законным в С# (не может говорить для VB.NET).
Помимо комментариев и строковых литералов, я думаю, что .
может отображаться только как:
(
, это не выход.(
не является цифрой.Наконец, оператор .
не перегружен, поэтому foo.(bar)
тоже не будет работать.
Пересмотрев ссылку на VB, Im теперь уверен, что ответ для VB не является.
VB использует символ .
только для трех вещей: внутри чисел чисел с плавающей запятой и для доступа к члену и доступа к вложенным именам.
Оставляя в стороне XML-литералы, единственное, что может появиться за доступом к члену, - это IdentifierOrKeyword
(§1.105.6). Идентификаторы очень хорошо определены, и они могут начинаться только с букв, подчеркиваний или, в случае экранированного идентификатора, символа [
.
То же самое относится к доступу вложенного имени (и, для полноты, также в блоках With
и инициализаторах поля).
Что касается литералов с плавающей запятой, то там должно следовать хотя бы еще одна цифра (§1.6.3).
На этой странице http://blogs.msdn.com/b/lucian/archive/2010/04/19/grammar.aspx Я поставил копию полной грамматики для С# 4 и VB10 в машиночитаемом формате (EBNF и ANTLR) и удобочитаемый (HTML). Версия HTML включает в себя вычисляемый набор "may-should" для каждого токена.
В соответствии с этим набор PERIOD "may-should" не включает LPAREN в С# 4 или VB10.
К сожалению, грамматики не совсем полны. Тем не менее, в командах VB/С# эти грамматики - это то, с чего мы начинаем с большого нашего анализа. Например...
VB10 представил "однострочный оператор lambdas" формы "Sub() STMT". Сама лямбда является выражением и может отображаться в списке, например. "Dim array = {Sub() STMT1, Sub() STMT2}". Мы должны были знать о двусмысленности в отношении того, что появилось после выражения, и что произошло после заявления. Например, "Dim x = Sub() Dim y = 5, z = 3" неоднозначно, потому что "z = 3" может быть частью первого ИЛИ второго Dim.
VB10 представила функцию "неявного продолжения линии", которая более или менее аналогична разрешению С# включать SEMICOLON в любом месте исходного кода. Нам нужно было выяснить, не приведет ли это к каким-либо двусмысленности. Это эквивалентно заданию того, является ли префиксом какого-либо предложения на языке сам по себе допустимое предложение. Это эквивалентно выяснению того, является ли пересечение двух контекстно-свободных языков пустым. Это неразрешимая проблема в целом, но не в случае грамматики VB, которую мы смогли решить с помощью дополнительной "человеческой проницательности" в алгоритм.
Я не думаю, что они добавят что-нибудь подобное на С#, просто выглядят неправильно.
Я вообще не уверен в VB.Net. просто глядя на то, как они делали дженерики, кажется, что команда VB.Net не имеет этого "не выглядящего странного" отношения.
Итак, если вы создаете какой-либо инструмент, который должен работать с будущими версиями этих языков, лучше следить за VB.Net...