在评估/解析表达式时,C#是否会产生影响?

时间:2010-07-20 14:05:30

标签: c# .net

有时回来我在C#

中尝试以下语句
i+++++i // does not compile <bt>

i++ + ++i // executed

空间对表达式有影响吗?
上述陈述以何种方式不同?

Ramachandran的

3 个答案:

答案 0 :(得分:14)

首先,让我解释编译器的工作原理。

我们要做的第一件事就是将源代码分解为令牌。然后我们将令牌组织成解析树。然后我们对解析树进行语义分析,然后基于该语义分析生成代码。任何这些阶段 - lexing,解析或分析 - 都会产生错误。这是重要的部分:如果后期阶段出现错误,我们不会再回到前一阶段

词法分析者是“贪婪的” - 它试图在每个阶段都能做出最大的代币。所以丹尼尔是对的。词法分析器将i +++++ i分解为i / ++ / ++ / + / i

然后解析器尝试将其转换为解析树,然后出现

                +
               / \
              ++  i
             /
            ++
           /
          i   

即等同于(((i ++)++)+ i)。

现在语义分析器看着它并说“i ++很好,因为我是一个变量。但是i ++不是一个变量,它是一个值。你不能对一个值做++,所以第二个 ++是非法的。“语义分析器然后给出错误:增量的操作数必须是变量

语义分析器然后重新执行lex并说你知道,这可能是i / ++ / + / ++ / i,它会以不同方式解析并且是合法的。我们不回溯,因为可能有数十亿可能的方法来重新解析和重新解析程序,我们不想尝试所有这些。只考虑你的情况; i +++++我可能是(((i ++)++)+ i)或)((i ++)+(+(+ i)))或(i +(+(+(+(+ i))) )或者......记住,+可以是一元加,二进制加,预增量或后增量的一部分,因此这五个加号可能有批次

答案 1 :(得分:10)

分隔令牌时空格有效。

明显的例子:int a = 1;inta=1;

不同

同样,+ +a+(+(a))相同,后者只返回1(假设为a=1)。无论如何移除空格,两个+标记将形成一个++标记,从而将a增加到2.

您的第一个示例标记化结果为5个标记:“i”“++”“++”“+”“i”

你的第二个例子导致5个令牌略有不同:“i”“++”“+”“++”“i”

答案 2 :(得分:3)

C-ish(C / C ++ / C#/ Java)编译器使用称为“max munch”的解析方式 - 他们总是试图使最大的令牌成为可能。

现在,一些字符会自动结束一个标记 - 例如分号或括号。空白就是其中之一。

所以,在你的第二个例子中,然后是5个令牌:“i”“++”“+”“++”“i”

然而,在你的第一个例子中,只有三个:“i”“+++++”和“i”

另外,我应该注意,虽然你的第二个例子将在C ++下编译,但它完全是非法的(你不允许在一个语句中两次修改相同的值)。它在C#中可能也是非法的,尽管C#在这些方面往往更灵活。