终结符和非终结符

joh*_*ohn 2 design-patterns interpreter-pattern

我目前正在阅读有关解释器模式的内容,它说明了有关终端和非终端符号的内容。所以我去了维基百科并阅读了它。但我还是不明白终结符和非终结符是什么。你能给我一些编程的例子吗?我不想复制粘贴维基百科页面……我想要真实世界的例子。

Leo*_*Aso 5

每一种语言——无论是人类语言、计算机语言还是科学记数法——都是由符号组成的。这些符号是语言中最小的有意义的单位,例如人类语言有单词和标点符号;数学有数字和运算符;Java 有标识符、文字和符号。这些基本符号是终结符,是您可以将语句分解成的最小部分。

这些终结符串在一起以进行陈述,并且语言有特定的方式可以将非终结符串连在一起以传达意义,例如在数学中,您可以连接一个数字、一个操作数和另一个数字(例如5 + 2)来进行运算,以及在 Java 中,您可以连接一个标识符、一个等号符号、一个数字文字和一个分号符号(例如size = 50 ;)来构成一个赋值语句。这些允许的组合终端的方式称为非终端。非终结符可以是终结符、其他非终结符或两者的组合。

所以基本上,终端是一种语言的符号,而非终端是这些终端的组合,以构成表达式和语句。例如,一种简单的编程语言可能有诸如ifelsewhile+-()++--'\n'、等终端3.14159。这些终端可以组合成非终端,例如:

  • 赋值语句
  • 如果语句
  • while 循环
  • 变量声明
  • 等等

解释器模式是将那些终结符和非终结符定义为与语言结构相匹配的类或数据类型。因此,对于像数字或标识符这样的终结符,它们可以定义为

abstract class Symbol {
    abstract int evaluate();
}

class Number extends Symbol {
    int value;

    @Override int evaluate() {
        return value;
    }
}

class Identifier extends Symbol {
    String name;

    @Override int evaluate() {
        return getIdentifierValue(name);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后像 if 语句或表达式这样的非终结符可以像这样定义

class IfStatement extends Symbol {
    Symbol condition;
    Symbol ifBranch;
    Symbol elseBranch;

    @Override int evaluate() {
        if (condition.evaluate() != 0)
            return ifBranch.evaluate();
        else
            return elseBranch.evaluate();
    }
}

class AddExpression extends Symbol {
    Symbol left;
    Symbol right;

    @Override int evaluate() {
        return left.evaluate() + right.evaluate();
    }
}
Run Code Online (Sandbox Code Playgroud)

所以你可以看到,终端代表数字、标识符和字符串等值,非终端代表从这些终端递归构建的表达式和语句。我不太擅长解释理论,但我希望这里的实际例子能帮助你理解。