【问题标题】:Unary operator ambiguity [duplicate]一元运算符歧义[重复]
【发布时间】:2014-07-24 20:25:30
【问题描述】:

查看 C 语法,似乎输入 ++i 可以有 2 个推导:要么被视为前缀增量运算符,要么被视为 2 个整数提升,如 +(+i)--i 也是如此)。
我错过了什么?

unary-expression:
   postfix-expression
   ++ unary-expression
   -- unary-expression
   unary-operator cast-expression
   sizeof unary-expression
   sizeof ( type-name )

unary-operator: one of
    & * + - ~ !

cast-expression:
    unary-expression
    ( type-name ) cast-expression

【问题讨论】:

  • @JonathanLeffler 因此根据 Robert 在此 meta question 中的 cmets,这些不是重复的,除非它是精确的 dup 或 dup 是规范的问题/答案。我发现这个位置有点令人惊讶,但是关于 dups 的元问题确实有一些相互矛盾的答案。我试图得到澄清,但到目前为止还没有。
  • 基本问题是两种情况下的最大咀嚼规则;他们真的是同一个问题。也许我应该改用What is the name of this operator: "-->"?? (主要是在开玩笑;那是相当不同的。)但是还有许多其他可能的重复——所有这些都归结为最大咀嚼规则。
  • @JonathanLeffler 好吧,他的论点是问题必须是一个重复,只是把它归结为相同的答案并不能使它成为一个重复。考虑到他是主持人,我必须认真对待这个职位。
  • 虽然立场似乎过于僵化。

标签: c grammar lexical-analysis ambiguity unary-operator


【解决方案1】:

词法分析器正在使用maximal munch principle,并将尽可能多地使用字符来形成有效标记以避免这些类型的歧义。

我们可以通过转到draft C99 standard 部分6.4 词法元素 来确认这一点:

如果输入流已被解析为预处理标记,直到 给定字符,下一个预处理标记是最长的序列 可以构成预处理标记的字符。 [...]

它提供了两个例子:

EXAMPLE 1 程序片段 1Ex 被解析为预处理数 令牌(不是有效的浮点或整数常量令牌), 即使解析为一对预处理标记 1 和 Ex 可能 产生一个有效的表达式(例如,如果 Ex 是一个宏定义为 +1)。类似地,程序片段 1E1 被解析为一个预处理数字(一个是一个有效的浮动常量标记),无论 E 是否 是一个宏名。

示例 2 程序片段 x+++++y 被解析为 x ++ ++ + y,即 违反了对增量运算符的约束,即使解析 x ++ + ++ y 可能会产生正确的表达式。

【讨论】:

    【解决方案2】:

    根据 C 标准

    4 如果输入流已被解析为预处理标记 给定字符,下一个预处理标记是最长的 可以构成预处理标记的字符序列

    所以没有歧义。

    例如在这个程序中

    #include <stdio.h>
    
    int main( void ) 
    {
    
        int a = 1;
        int b = 10;
        int c = a+++b;
    
        printf( "c = %d\n", c ); 
    }   
    

    输出将是

    11
    

    因为表达

    a+++b
    

    将被解释为

    a++ + b
    

    不像

    a + ++b
    

    【讨论】:

      猜你喜欢
      • 2013-10-17
      • 2021-05-02
      • 2010-09-27
      • 1970-01-01
      • 1970-01-01
      • 2021-09-09
      • 1970-01-01
      • 1970-01-01
      • 2015-08-28
      相关资源
      最近更新 更多