13

我正在尝试在 Roslyn 中实现 C# 规范 7.16.2“查询表达式翻译”。但是,我在 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")

我的代码不会产生与示例匹配的结果,因为(根据“除了何时”行)我翻译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)

示例结果再次缺少规范建议的括号。

4

2 回答 2

2

在该示例中,构造“e”是一个表达式,而构造“(e)”代表一个主要的。也就是说,C# 语法中有一个产生式,它允许在任何需要主节点的地方使用“( e )”。还有一个产生式允许在任何需要表达式的地方使用主节点。

在“from”代码片段中,需要一个表达式“e”(根据 C# 语法),在“Select()”片段中,需要一个主表达式,此处表示为“(e)”。

这个例子的作者(也许是不明智的)选择了一个主要的“客户”而不是一个表达来说明这一点。如果该示例使用了一个表达式,那么翻译将包含括号。该示例是正确的,但具有误导性。

在回答您的问题时,您可以通过识别您是在处理主要还是表达式来识别括号是否必要。对于小学,他们不是。

披露:我的专长是编译器技术、C# 语法和 Reflection.Emit,但不是(还)Roslyn。我找不到任何在线文档,所以我无法告诉你如何在 Roslyn 中做到这一点。

于 2014-01-21T13:33:01.613 回答
0

你的翻译加上附加的(并且)是正确的。但是如果你想消除多余的括号,你可以调用

.WithAdditionalAnnotations(CodeAnnotations.Simplify)

关于你的结果SyntaxNode

于 2013-11-13T10:11:22.577 回答