为什么 PreIncrement 类型的 PrefixUnaryExpressionSyntax 允许使用 ParanthesisedExpressionsSyntax 的操作数?

Fra*_*ank 2 c# roslyn

我试图了解 C# 分析器和编译器的工作原理。

根据文档,像 pre-inc 和 post-inc 这样的一元运算符应该只接受变量、属性和索引器。

有趣的是,它们还接受 ParanthesisedExpressions,例如代码 ++(x);

这有语法原因吗?除了 ParanthesizedExpressionSyntax 在语义上等同于属性/索引器/变量之外,是否还有 ++(..something here..) 起作用的其他情况?

Mét*_*ule 5

这是因为 C# 语言规范允许。预自增运算符的规范为:

pre_increment_expression
    : '++' unary_expression
    ;
Run Code Online (Sandbox Code Playgroud)

unary_expression的规范是:

unary_expression
    : primary_expression
    | null_conditional_expression
    | '+' unary_expression
    | '-' unary_expression
    | '!' unary_expression
    | '~' unary_expression
    | pre_increment_expression
    | pre_decrement_expression
    | cast_expression
    | await_expression
    | unary_expression_unsafe
    ;
Run Code Online (Sandbox Code Playgroud)

最后,primary_expression允许使用括号:

primary_expression
    : primary_no_array_creation_expression
    | array_creation_expression
    ;

primary_no_array_creation_expression
    : literal
    | interpolated_string_expression
    | simple_name
    | parenthesized_expression <<---  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
    | nameof_expression
    | anonymous_method_expression
    | primary_no_array_creation_expression_unsafe
    ;
Run Code Online (Sandbox Code Playgroud)

所以现在的问题是:为什么应该pre_increment_expression允许 a unary_expression?因为替代方案将更难指定、开发和测试。另一种选择是写这样的东西:

pre_increment_expression
    : '++' pre_increment_expression_allowed
    ;

pre_increment_expression_allowed
    : element_access
    | member_access
    | some other expressions 
    ;
Run Code Online (Sandbox Code Playgroud)

如果您不重用现有表达式,则必须考虑您想要允许的所有表达式,这可能会变得非常复杂,然后开发新的语法树解析来支持该表达式。

复杂的例子:

请注意,可以编写以下内容(虽然没有多大意义,但仍然如此):

pre_increment_expression
    : '++' unary_expression
    ;
Run Code Online (Sandbox Code Playgroud)