Swift如何消除表达式上下文中类型参数的歧义?

时间:2016-04-03 15:57:16

标签: swift generics compiler-construction grammar ambiguous-grammar

看看以下两个表达式:

baz(Foo<Bar, Bar>(0))
baz(Foo < Bar, Bar > (0))

在不知道什么的情况下,bazFooBarbaz可以是一种类型或方法,FooBar可以是类型或变量),没有办法消除歧义<是表示类型参数列表还是小于运算符。

// two different outcomes, difference shown with parentheses
baz((Foo<Bar,Bar>(0)))      // generics
baz((Foo < Bar), (Bar > 0)) // less-than

在解析像这样的表达式时,任何理智的编程语言都不应该依赖bazFooBar。然而,无论我在哪里放置空格,Swift都设法消除下面的表达歧义:

println(Dictionary<String, String>(0))
println(Dictionary < String, String > (0))

编译器如何管理?而且,更重要的是,Swift语言规范中是否有任何地方。其中描述了规则。通过Swift书的Language Reference部分,我只找到了这一部分:

  

在某些构造中,具有前导<>的运算符可能会被拆分为两个或更多个标记。其余部分以相同的方式处理,可能会再次拆分。因此,无需使用空格来消除>等结构中的结束Dictionary<String, Array<Int>>字符之间的歧义。在此示例中,结束>字符不会被视为单个标记,然后可能会被误解为位移>>运算符。

certain constructs在此背景下引用了什么?实际语法只包含一个提到类型参数的生产规则:

  

explicit-member-expression→postfix-expression . identifiergeneric-argument-clause opt

非常感谢任何解释或资源。

1 个答案:

答案 0 :(得分:5)

感谢@Martin R,我找到了编译器源代码的相关部分,其中包含一个解释如何解决歧义的注释。

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

基本上,编译器尝试解析类型列表,然后在结束尖括号之后检查令牌。如果该令牌是

  • 右括号,括号或括号
  • 一个左括号,括号或句点,它本身与结束尖括号之间没有空格(>(>[,但不是> (> [),
  • 一个大括号或
  • 逗号或分号

它将表达式解析为泛型调用,否则将其解析为一个或多个关系表达式。

如书Annotated C#中所述,问题在C#中以类似的方式解决。