Swift如何消除表达式上下文中的类型参数? [英] How does Swift disambiguate Type Arguments in Expression Contexts?
问题描述
$ $ $ $ $ $ $ $ $ $ $ $ $ b $(Foo< Bar,Bar>(0))
baz(Foo< Bar,Bar>(0))
code> baz , Foo
和 Bar
都是( baz
可以是一个类型或方法, Foo
和 Bar
可以是类型或变量),所以无法明确<
是否代表类型参数列表或小于运算符。
//两个不同的结果,括号中显示的差异
baz((Foo< Bar,Bar>(0))// //泛型
baz(( Foo< Bar),(Bar> 0))//小于
语言不应该依赖于 baz
, Foo
和 Bar
在解析像这样的表达式时。然而,无论我在哪里放置空格,Swift都设法消除下面的表达式:
println(Dictionary< String,String>(0 ))
println(Dictionary< String,String>(0))
编译器是否管理这个?而且,更重要的是,Swift语言规范中还有什么地方。其中描述了这些规则。仔细查看Swift书的语言参考
部分,我只找到了这一部分:
<在某些结构中,具有前导< / code>或
>
的运算符可能会被拆分为两个或更多个标记。其余部分以相同的方式处理,并可能再次分裂。因此,在Dictionary< String,Array< Int>>等结构中的结尾
。在这个例子中,关闭的>
字符之间不需要使用空格来消除歧义。 ;>
字符不被视为单个标记,可能会被误解为位移>>
operator。
某些结构
这种情况下?实际的语法只包含一个提及类型参数的生产规则:
lockquote
显式成员表达式后缀表达式$ $ $ $ $ 。 identifiergeneric-argument-clause opt
任何解释或资源非常感谢。
感谢@Martin R,我找到了编译器源代码的相关部分,解释了它是如何解决歧义的。
swift / ParseExpr.cpp
,第1533行:
/// generic-args的情况与包含'<'
///和'>'运算符的表达式是不明确的。运算符表达式是有利的,除非通用的
///参数列表可以被成功解析,并且结尾括号是
///后面跟着这些令牌之一:
/// lparen_following rparen lsquare_following rsquare lbrace rbrace
/// period_following comma分号
基本上,编译器试图解析类型列表,然后在关闭角度支架后检查标记。如果该标记为
- 右括号,括号或大括号, (
>(
,> [
,但不是>(
,> [
), - li>
- 逗号或分号
它将表达式解析为泛型调用,否则将其解析为一个或多个关系表达式。
如注释的C#,问题在C#中以类似的方式解决。
Take a look at the following two expressions:
baz(Foo<Bar, Bar>(0))
baz(Foo < Bar, Bar > (0))
Without knowing what, baz
, Foo
and Bar
are (baz
can be a type or a method, Foo
and Bar
can be types or variables), there is no way of disambiguating whether the <
represents a type argument list or a less-than operator.
// two different outcomes, difference shown with parentheses
baz((Foo<Bar,Bar>(0))) // generics
baz((Foo < Bar), (Bar > 0)) // less-than
Any sane programming language should not rely on what baz
, Foo
and Bar
are when parsing an expression like this. Yet, Swift manages to disambiguate the below expression no matter where I place whitespaces:
println(Dictionary<String, String>(0))
println(Dictionary < String, String > (0))
How does the compiler manage this? And, more importantly, is there any place in the Swift Language Spec. where the rules for this are described. Looking through the Language Reference
part of the Swift book, I only found this section:
In certain constructs, operators with a leading
<
or>
may be split into two or more tokens. The remainder is treated the same way and may be split again. As a result, there is no need to use whitespace to disambiguate between the closing>
characters in constructs likeDictionary<String, Array<Int>>
. In this example, the closing>
characters are not treated as a single token that may then be misinterpreted as a bit shift>>
operator.
What does certain constructs
refer to in this context? The actual grammar only contains one production rule that mentions type arguments:
explicit-member-expression → postfix-expression
.
identifiergeneric-argument-clauseopt
Any explanation or resource would be greatly appreciated.
Thanks to @Martin R, I found the relevant part of the compiler source code, which contains a comment that explains how it resolves the ambiguity.
swift/ParseExpr.cpp
, line 1533:
/// The generic-args case is ambiguous with an expression involving '<'
/// and '>' operators. The operator expression is favored unless a generic
/// argument list can be successfully parsed, and the closing bracket is
/// followed by one of these tokens:
/// lparen_following rparen lsquare_following rsquare lbrace rbrace
/// period_following comma semicolon
Basically, the compiler attempts to parse a list of types and then checks the token after the closing angle bracket. If that token is
- a closing parenthesis, bracket or brace,
- an opening parenthesis, bracket or period without whitespace between itself and the closing angle bracket (
>(
,>[
, but not> (
,> [
), - an opening brace or
- a comma or semicolon
It parses the expression as a generic call, otherwise it parses it as one or more relational expressions.
As described in the book Annotated C#, the problem is solved in a similar way in C#.
这篇关于Swift如何消除表达式上下文中的类型参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!