C#语言规范4.0版本中,基础访问是否定义正确?

5

我在查阅《C#语言规范v4.0》时注意到有一组规则被定义为:

invocationExpression:
    primaryExpression '(' argumentList? ')'

primary-expression: 
    primary-no-array-creation-expression
    array-creation-expression

primary-no-array-creation-expression:
    literal
    simple-name
    parenthesized-expression
    member-access
    invocation-expression
    element-access
    this-access
    base-access
    post-increment-expression
    post-decrement-expression
    object-creation-expression
    delegate-creation-expression
    anonymous-object-creation-expression
    typeof-expression
    checked-expression
    unchecked-expression 
    default-value-expression
    anonymous-method-expression

base-access:
    'base'   '.'   identifier
    'base'   '['   argument-list   ']'

当我尝试匹配这个语句(顺便说一下,这是一个正确的语句,我曾在一个项目中看到它被使用)

base.VisitList<T>(list, visitor);

根据给定的规则,我没有看到可以完成此操作的方法。 base-access 不应该被定义为:
 base-access:
        'base'   '.'   identifier type-parameter-list(opt)
        'base'   '['   argument-list   ']'

能否用类似这样的语法来捕捉该语句?

编辑 我看到的例子是在项目的C#版本db4o中,大致如下(我删除了大部分声明,只保留重要的声明)

internal abstract class ExpressionVisitor
{
    protected virtual void VisitList<T>()
    {
    }
}

internal class HashCodeCalculation : ExpressionVisitor
{
    protected override void VisitList<T>()
    {
        base.VisitList<T>();
    }
}

似乎是4.0规范中的错误。 - Michael Liu
1
在5.0规范中,“base access”的语言似乎与1.2规范中的语言完全相同(我能找到的最早版本,早于泛型)。我想他们只是没有及时更新规范的这个部分。 - Damien_The_Unbeliever
3个回答

5

我看起来确实有规范错误。

解析表达式的方法是:

this.VisitList<T>(list, visitor)

is as follows:

invocation-expression

primary-expression '(' argumentList? ')'

primary-no-array-creation-expression '(' argumentList? ')'

member-access '(' argumentList? ')'

primary-expression '.' identifier type-argument-listopt '(' argumentList? ')'

this-access '.' identifier type-argument-listopt '(' argumentList? ')'

'this' '.' identifier type-argument-listopt '(' argumentList? ')'

等等。

换句话说,this-access 被定义为

this-access:
    'this'

如果将base-access定义为以下内容,那么这将非常有意义:

base-access:
    'base'

然后解析表达式的方法如下:

base.VisitList<T>(list, visitor)

以下是可能的内容:

将如下所示:

invocation-expression

primary-expression '(' argumentList? ')'

primary-no-array-creation-expression '(' argumentList? ')'

member-access '(' argumentList? ')'

primary-expression '.' identifier type-argument-listopt '(' argumentList? ')'

base-access '.' identifier type-argument-listopt '(' argumentList? ')'

'base' '.' identifier type-argument-listopt '(' argumentList? ')'

等等,还有其他问题。

但事实并非如此。


我同意,似乎规范不正确。或者编译器没有遵守规范;-) - PMF

1
我怀疑这不是有效的C#代码。也许你在C++中看到过它?
以下代码由于语法错误而无法编译:
public class VisitList<T> : List<T>
{
    public VisitList(int n)
        : base.VisitList<T>(n)
    {

    }
}

这样可以:
public class VisitList<T> : List<T>
{
    public VisitList(int n)
        : base(n)
    {

    }
}

我给出的例子来自于 db4o 的 C# 版本。你可以查看我的更新。 - sve
好的,看起来更有道理了。identifier 怎么声明的? - PMF
它被定义为遵循某些规则的字符序列,例如:标识符仅以字母或下划线 _ 开头 - 常规内容。 - sve

0

标准 ECMA-334 第5版/2017年12月 C# 语言规范

第151页的第12.7.9节基础访问现在如下所示:

base-access:
base . identifier type-argument-listopt
base [ argument-list ]

由于这个被改变了,似乎承认第四版确实存在缺陷或遗漏。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接