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

RAM*_*RAM 5 .net c#

有时回来我在C#中尝试以下语句

i+++++i // does not compile <bt>

i++ + ++i // executed
Run Code Online (Sandbox Code Playgroud)

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

拉马钱德兰

Eri*_*ert 14

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

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

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

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

                +
               / \
              ++  i
             /
            ++
           /
          i   
Run Code Online (Sandbox Code Playgroud)

也就是说,等同于(((i ++)++)+ i).

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

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


Dan*_*iel 10

分离令牌时空格有效.

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

同样,+ +a也是如此+(+(a)),它只返回1(假设a=1).无论如何移除空间,两个+标记将形成一个++标记,从而将a增加到2.

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

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