正如您所发现的,您的 Tokens 枚举不能真正用于实际令牌,因为无法制作不同版本的 Tokens.x(我猜 Tokens.x 是为了代表公式中的数字...)来保存不同的数值。
你需要的是一个Token 类——一个“真正的”类——它可以保存(至少)一个令牌类型和一个值:
public class Token {
private TokenType type;
private Object value;
public Token(TokenType type) {
this.type = type;
this.value = null;
}
public Token(TokenType type, Object value) {
this.type = type;
this.value = value;
}
// getters and setters for type and value omitted below
// ...
}
TokenType 将是一个枚举; value 属性是一个 Object,因此它可以包含您可能需要的不同令牌类型的任何类型的值对象。
现在,在决定如何使用 type 和 value 属性来表示您的令牌时,有几种方法可供选择。
一种方法是将您当前的 Tokens 枚举重命名为 TokenType 并将其值用于您的类型。大多数令牌类型,例如TokenType.csc 和TokenType.add,根本不需要任何值,因为type 告诉您您需要知道的一切。但是数字标记需要知道它们关联的数值,因此它们将具有 type 或 TokenType.x,而 value 将保持数值为 Double、Integer、BigDecimal 或其他任何值。
但是,您可能会发现使用表示更广泛句法类别的标记类型会更方便,例如“二元运算符”、“一元运算符”、“数字”、“公式结尾”:
public enum TokenType {BINOP, UNOP, NUMBER, END};
BINOP 和 UNOP 令牌将使用 value 属性来指示它们所代表的特定运算符。枚举非常适合此目的:
public enum BinOps {ADD, SUB, MUL, ... };
public enum UnOps {SIN, COS, TAN, ... };
NUMBER 将在value 属性中携带它们的数值(同样,Double、Integer、BigDecimal 或其他)。 END 令牌不需要任何value。