Подтвердить что ты не робот

Несоответствие в спецификации С# 7.16.2.5

Я собираюсь реализовать С# spec 7.16.2 "Перевод выражения запроса" в Roslyn. Однако я столкнулся с проблемой в 7.16.2.5 "Выделите предложения".

Он читает

Выражение запроса формы

from x in e select v

переводится в

( e ) . Select ( x => v )

за исключением случаев, когда v является идентификатором x, перевод просто

( e )

Например

from c in customers.Where(c => c.City == "London")
select c

просто переведен в

customers.Where(c => c.City == "London")

Мой код не приводит к результату, соответствующему этому примеру, потому что (согласно строке "except when" ) я переводил from x in e select x в ( e ), а не только e. Таким образом, мой код переводит пример в

( customers.Where(c => c.City == "London") )

Является ли пример в спецификации неправильным, или мне нужно делать обработку, чтобы узнать, нужны ли круглые скобки? Если да, это где-то в спецификации?

Аналогично, 7.16.2.6 (предложения Groupby) говорит

Выражение запроса формы

from x in e group v by k

переводится в

( e ) . GroupBy ( x => k , x => v )

за исключением случаев, когда v является идентификатором x, перевод

( e ) . GroupBy ( x => k )

Пример

from c in customers
group c.Name by c.Country

переводится в

customers.
GroupBy(c => c.Country, c => c.Name)

где снова в результате примера отсутствуют скобки, предложенные спецификацией.

4b9b3361

Ответ 1

В примере конструкция 'e' является выражением, а конструкция '(e)' представляет собой первичную. То есть в грамматике С# есть производство, которое позволяет использовать "(e)" везде, где ожидается первичное. Существует также производство, которое позволяет использовать первичный объект везде, где ожидается выражение.

В фрагменте кода "from" требуется выражение "e" (в соответствии с грамматикой С#), а в фрагменте "Select()" требуется первичное значение, представленное здесь как "(e)".

Автор примера (возможно, неразумно) выбрал первичные "клиенты", а не выражение, чтобы проиллюстрировать эту точку. Если бы этот пример использовал выражение вместо этого, то в переводе содержались бы круглые скобки. Пример правильный, но пограничный ввод в заблуждение.

В ответ на ваш вопрос вы можете узнать, нужны ли скобки, распознавая, имеете ли вы дело с первичным или выражением. Для первичного они не являются.

Раскрытие: мой опыт - это технология компилятора, синтаксис С# и Reflection.Emit, но не (пока) Roslyn. Я не мог найти никаких онлайн-документов, поэтому я не могу сказать вам, как это сделать в Roslyn.

Ответ 2

Ваш перевод с дополнительными ( и ) верен. Но если вы хотите устранить лишние круглые скобки, вы можете вызвать

.WithAdditionalAnnotations(CodeAnnotations.Simplify)

в полученном вами SyntaxNode.