Math Parser/Lexer - Token接口设计

Math Parser/Lexer - Token interface design

目前正在做一个小宠物项目,数学 Parser/Lexer 并最终求解 fun/learning。我已经搞定了一个基本的原型,现在我想把它转换成 TypeScript 来清理一切。感兴趣的人可以在这里 https://github.com/chips5k/math-solver-prototype 找到原型。

我正在尝试提出一种基于干净界面的方法来处理我的令牌。我怀疑我看错了,但希望有人能提供有用的建议。

在我的 TS 设计中,我有几个接口,基本接口是 Token,NumericToken 和 FunctionToken 扩展了这些接口。然后我有几个 类 实现这些接口,例如:AdditionToken、VariableToken、NumberToken、PiToken、SineToken 等...

我的问题是,为了使用这些接口,我最终需要检查基本类型的方法,例如 isNumeric、isFunction、isVariable 或直接类型 === TokenFactory.NUMERIC 等...这,对我来说,感觉不对,因为它基本上使使用界面的意义消失了。我怀疑我可以采用 nicer/cleaner 更多的多态方法,但不幸的是我没有想法并且无法找到有关我正在做的事情的信息。

在尝试解决一系列标记时,事情崩溃的一个例子就显示出来了:

if(t.isFunction()) {
   var a = stack.unshift();
   var b = stack.unshift();
   if(a.isNumeric() && b.isNumeric()){
       result.push(tokenFactory.create(t.evaluate<number>(a.evaluate<number>, b.evaluate<number>));
   } else {
     //return to stack and move on, e.g can't solve x + 1 directly
   }
} else {
   stack.push(t);
}

基本上是在寻找被认为是处理这种情况的理想方法,我怀疑它可能是设计的替代方法。

TIA!

basic type e.g isNumeric, isFunction, isVariable or alternatively a direct type === TokenFactory.NUMERIC etc... This, to me, feels wrong

没有。这是相当惯用的,因为类型控制那里的功能。

例如,您会看到 TypeScript checker.ts 散落着对 .kind (SyntaxKind) 的检查,它位于 TypeScript AST 节点鉴别器上。

您还可以考虑添加一个递归的访问者,例如

function visit(item){

if (item.addition) {
  return visit(item.left) + visit(item.right)
}

if (item.literal) {
  return literal.value();
}

// ETC.
}