Math Parser / Lexer - 令牌界面设计

时间:2016-09-05 21:38:49

标签: oop parsing typescript lexer

目前正致力于一个小型宠物项目,一个Math Parser / Lexer,最终解决了有趣/学习的问题。我已经打破了一个基本的原型,我现在正在寻求将其转换为TypeScript来清理。对于那些感兴趣的人,可以在https://github.com/chips5k/math-solver-prototype找到原型。

我正在尝试提出一种基于干净接口的方法来处理我的令牌。我怀疑我是以错误的方式看待这个,但希望有人可以提供有用的建议。

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

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

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

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!

1 个答案:

答案 0 :(得分:1)

  

基本类型,例如isNumeric,isFunction,isVariable或者直接类型=== TokenFactory.NUMERIC等......这对我来说,感觉不对

不。这是相当惯用的,因为类型控制着哪些功能。

例如,你会看到TypeScript checker.ts散落着.kindSyntaxKind),它位于TypeScript AST节点鉴别器上。

另外,您可能需要考虑添加递归的访问者,例如

function visit(item){

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

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

// ETC.
}