c++ - 如何在 Bison 中模拟 C++ 后缀?

标签 c++ compiler-construction bison

我正在尝试使用 flex 和 bison 实现一个简单的编译器,但陷入了后缀表示法。 (编译器应该像 C++ 编译器一样运行)

问题来了: 给定以下代码:

    int x = 0;
    int y = x++ || x++  ; //y=1 , x = 2 this is understandable

    int z = x++ + x++ ;  // z = 0 , x=2

第一行没问题,因为语法如下:

    expression = expression || expression; //  x=0
    expression = 0 || expression   // x= 1
    expression = 0 || 1  //x=2
    expression = 1 // x=2 
    y = 1

但是,我不明白为什么z=0。

当我的 Bison 语法看到“变量”++ 时,它首先返回变量值,然后才将其递增 1。我曾经认为这就是 C++ 的工作方式,但它不适用于“z”变量。

关于如何解决这个案例有什么建议吗?

最佳答案

int z = x++ + x++;

虽然 z 可能看起来是 0,但实际上它不是,它实际上可以是任何值,并且完全取决于您使用的编译器。这是因为 z 的赋值具有未定义的行为。

未定义的行为来自 x 的值在序列点之间被改变了不止一次。在 C++ 中,||运算符是一个序列点,这就是为什么 y 的赋值按预期工作,但是 + 运算符不是序列点。

C++ 中当然还有其他各种序列点,;是一个更突出的例子。

我还应该指出,++ 运算符返回变量的先前值,即在本例中

#include <iostream>

using namespace std;

int main() {
    int x = 0;
    int y = x++;
    cout << y << endl;
    return 0;
}

打印出的 y 值为 0。

关于c++ - 如何在 Bison 中模拟 C++ 后缀?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13659610/

相关文章:

c++ - 从进程名称获取窗口标题

c++ - 在仿真器中使用 union 来模拟 CPU 寄存器有多合适?

c++ - 如何使用 Turbo C++ 编译器在 Notepad++ 中编译和调试 C++

c++ - 为什么编译器会重复一些指令?

compiler-construction - FPGA 编译器的中间表示

Bison错误报告解读

c - Bison 抛出一个段错误,假设它与 *char 有关

c++ - 泄漏的谷歌模拟对象不会失败

c++ - 警告 : control reaches end of non-void function in recursive function

c - 如何使用 Flex/Bison 求解算术表达式