代码不贴了,主要讲解一下思路。
//BNF定义:
//exprN代表优先级>=N的算符表达式
expr := expr20
expr100 := value //数值常量优先级最高,当然也可以把expr100合并到expr80,这样可以少写一个parseExpr100解析子函数
expr80 := ( expr ) | expr100 //其次是括号表达式
expr60 := sin expr60 | cos expr60 | ln expr60 | log expr60 | sqrt expr60 | ... | expr80 //其次是一元函数, 一元取负暂不考虑
expr50 := expr60 x^y expr50 | expr60 //二元函数的优先级高于乘除运算,低于一元函数,不加括号的情况下,二元函数从右往左运算;
expr40 := expr50 '*' expr50 | expr50 '/' expr50 | expr50 //接下来是二元乘除运算
==> expr50 | expr50 ( '*' expr40 )* | expr50 ( '/' expr40)*
expr20 := expr20 + expr40 | expr20 - expr40 | expr40 //接下来是二元加减运算
==> expr40 | expr40 ('+' expr40)* | expr40 ('-' expr40)*
//注意,减法运算不满足交换律,右边的被减数优先级必须至少是乘和除
//糟糕的问题:expr40、expr20正常的写法会导致左递归,需要改写
function AdvancedCalculator(){
//语法分析的原始输入流:
this.tokens = [];//中缀带括号的, 3种语法分析输入单位:类型为String的(和)、类型为Number的value、类型为Object/String的运算符
this.tokens_scan_index = 0;
this.saved_tokens_scan_index_stack = [];
this.value_buffer = [];
}
Advance