Swift如何消除表达式上下文中的类型参数? [英] How does Swift disambiguate Type Arguments in Expression Contexts?

查看:214
本文介绍了Swift如何消除表达式上下文中的类型参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

看看以下两个表达式:

$ $ $ $ $ $ $ $ $ $ $ $ $ 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 like Dictionary<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­ . ­identifier­generic-argument-clause­opt

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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆