Является ли когда-либо законным в C # или VB.Net? - PullRequest
32 голосов
/ 07 апреля 2011

Может ли последовательность .( когда-либо появляться в коде C # или VB.Net?
(Не в строке, комментарии или литерале XML, EDIT : или директива препроцессора)

Я достаточно уверен, что ответ - нет, но я бы хотел убедиться.

Ответы [ 6 ]

22 голосов
/ 07 апреля 2011

Единственные места, в которых . появляется в грамматике:

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   

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

20 голосов
/ 07 апреля 2011

В C # сегмент #region позволяет любым символам следовать за ним:

#region foo.(
// this is perfectly legal C#
#endregion

Обратите внимание, что в VB.Net это не имеет значения, поскольку метка региона должна быть допустимым строковым литералом,поэтому он имеет кавычки:

#Region "foo.("
' quotes required
#End Region

Это также допустимо после #error и #warn, которые не имеют VB-эквивалента.

Однако самое большое беспокойство - это то, что вы можете иметь любой произвольныйкод внутри блока #if.В C #:

#if false
    foo.( perfectly legal
#endif

В VB.Net:

#If False Then
    foo.( perfectly legal
#End If

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

При этом, анализируя грамматику в C # 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   ]

Поскольку за . всегда следует десятичная цифра, идентификатор или маркер this, единственный способ получить последовательность .( состоит в том, чтобы разрешить несколько operator-or-punctuatorсимволы рядом друг с другом.Посмотрев на operator-or-punctuator, мы увидим:

token:
    operator-or-punctuator

Поскольку token используется только в лексическом анализе, нет никаких оснований предполагать, что . является допустимым, за которым следует ( в обычном коде.

Конечно, это все еще оставляет комментарии, литералы и т. Д., Которые я опускаю, потому что вы уже знаете о них.

10 голосов
/ 07 апреля 2011

Нет ссылок на грамматику и совершенно ненаучно, но вот моя догадка :

.( недопустимо в C # (не может говорить за VB.NET).

За пределами комментариев и строковых литералов я думаю, . может отображаться только как:

  1. Оператор доступа члена, за которым должен следовать идентификатор . Поскольку идентификаторы не могут начинаться с (, это не пойдет.
  2. В качестве десятичной точки в реальных литералах, за которыми должна следовать цифра . ( не является цифрой.

Наконец, оператор . не перегружается , поэтому foo.(bar) также не будет работать.

6 голосов
/ 07 апреля 2011

Изучив ссылку на VB, я теперь уверен, что ответ для VB - не .

VB использует символ . только для трех вещей: внутри литералов чисел с плавающей запятой и для доступа к элементу и доступа к вложенному имени.

Если оставить в стороне XML-литералы, единственное, что может появиться за доступом к члену, - это IdentifierOrKeyword (§1.105.6). Идентификаторы очень четко определены и могут начинаться только с букв, подчеркиваний или, в случае экранированного идентификатора, символа [.

То же самое касается доступа к вложенным именам (и, для полноты, также в With блоках и инициализаторах полей).

Что касается литералов с плавающей точкой, то за точкой должна стоять еще как минимум еще одна цифра (§1.6.3).

4 голосов
/ 04 марта 2012

На этой странице http://blogs.msdn.com/b/lucian/archive/2010/04/19/grammar.aspx Я поместил копию полной грамматики для C # 4 и VB10 в машиночитаемом формате (EBNF & ANTLR) и в читаемом человеком (HTML).HTML-версия включает в себя вычисленный набор «может следовать» для каждого токена.

В соответствии с этим набор «может следовать» PERIOD не включает LPAREN ни в C # 4, ни в VB10.

К сожалению, грамматики не совсем полны.Тем не менее, в командах VB / C # эти грамматики являются тем, с чего мы начинаем большую часть нашего анализа.Например ...

  • VB10 ввел "лямбда-выражения однострочные" в форме "Sub () STMT".Лямбда сама по себе является выражением и может появляться в списке, например, «Dim array = {Sub () STMT1, Sub () STMT2}».Мы должны были знать о неясностях относительно того, что последовало за выражением, а что за утверждением.Например, «Dim x = Sub () Dim y = 5, z = 3» является неоднозначным, поскольку «z = 3» может быть частью первого ИЛИ второго Dim.

  • VB10 представил функцию «неявного продолжения строки», которая более или менее аналогична разрешению C # включать SEMICOLON в любом месте исходного кода.Мы должны были выяснить, не внесет ли это какие-либо двусмысленности.Это равносильно тому, чтобы спросить, является ли префикс какого-либо предложения в языке само по себе допустимым предложением.Это эквивалентно выяснению, является ли пересечение двух контекстно-свободных языков пустым.В общем, это неразрешимая проблема, но не в случае грамматики VB, которую мы смогли решить с помощью дополнительного «человеческого понимания» алгоритма.

2 голосов
/ 07 апреля 2011

Не думаю, что они добавят что-то подобное в C #, просто выглядело бы неправильно.

Хотя я не совсем уверен насчет VB.Net. просто взглянув на то, как они сделали дженерики, кажется, что команда VB.Net не имеет такого «не выглядящего странно» отношения.

Итак, если вы создаете какой-либо инструмент, который будет работать с будущими версиями этих языков, лучше следите за VB.Net ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...