使用boost精神为基于堆栈的语言

Dea*_*ean 5 c++ parsing boost boost-spirit

我需要解析一个相当简单的基于堆栈的语言,例如

1 2 add
3 1 sub
Run Code Online (Sandbox Code Playgroud)

我在这里面临两个选择:

  1. 为代币编写自己的词法分析器,然后继续解析它
  2. 使用提升精神

我从来没有使用过提升精神,但从我所读到的内容(文档和示例)我仍然无法决定是否使用提升精神来解释和解析这种简单的语言或是否会使感觉使用它而不是推出我自己的词法分析器和解析器(我认为不应该太难).

使用boost精神来实现像上面那样简单的基于堆栈的语言能够获得回报(因为我需要先学习它才能使用它)?

seh*_*ehe 2

第一种方法在普通的 C++ 中可能非常简单:

int main() {
    Machine<int> machine;

    std::for_each(
            std::istream_iterator<std::string> { std::cin },
            {},
            [&](auto& instr) { machine.process(instr); }
        );
}
Run Code Online (Sandbox Code Playgroud)

这利用了这样一个事实:读取空格分隔的字符串作为“词法分析器”(分词器)就足够了。

现在,process以最简单的方式实现:

    static const char* opcodes[] = { "add", "sub", "mul", "div", "pop" };
    auto op = find(begin(opcodes), end(opcodes), instr);

    enum { add, sub, mul, div, pop, other };

    switch(op - opcodes) {
        case add: execute(Add{}); break;
        case sub: execute(Sub{}); break;
        case mul: execute(Mul{}); break;
        case div: execute(Div{}); break;
        case pop: execute(Pop{}); break;
        case other: {
            istringstream iss(instr);
            value_type v;
            if (iss >> v)
                execute(v);
            else
                throw runtime_error("Invalid instruction '" + instr + "'");
        }
    }
Run Code Online (Sandbox Code Playgroud)

添加一些调试跟踪,我们得到程序“1 2 add 3 1 sub mul”的以下输出:

Executing 1: 1 
Executing 2: 1 2 
Executing add: 3 
Executing 3: 3 3 
Executing 1: 3 3 1 
Executing sub: 3 2 
Executing mul: 6 
Run Code Online (Sandbox Code Playgroud)

Live On Coliru

使用提升精神

我已将其添加为单独的答案