1
dreampuf 2013-03-01 20:03:29 +08:00
"众所周知" 被代表了。
|
2
miaoever 2013-03-01 20:10:06 +08:00
|
4
pppab 2013-03-01 20:59:38 +08:00
先词法、语法分析,在分析过程中进行计算。
|
6
acecode 2013-03-02 00:05:54 +08:00
避免使用eval的原因主要是
|
7
acecode 2013-03-02 00:14:29 +08:00 1
(擦,本来想换行的。。。忽略上一条吧)避免使用eval的原因主要是 1.大段参数的效率比较慢, 2.变量作用域默认(好像)是全局作用域, 3.动态内容可能引入精心构造的恶意代码; 如果只是做计算器用途的话, 可以考虑用字符串替换+正则过滤来处理, 比如: 先过滤下常用函数表(sin, cos, ...), 然后再用正则匹配下/[0-9+-*/()]+/,如果执行出错就用try catch捕获下
|
8
qiao 2013-03-02 08:36:35 +08:00 2
樓主應該先去學下編譯原理。 然後可以使用 js 的 parser generator 如 jison http://zaach.github.com/jison/demos/calc/ 或者 pegjs http://pegjs.majda.cz/online 來實現你想要的功能。(個人比較喜歡 pegjs )
|
9
jabbany 2013-03-02 09:14:43 +08:00 1
可以参考一下:https://github.com/silentmatt/js-expression-eval
安全的代替EVAL,可以自己定义运算符号和函数 |
10
yangzh OP |
11
Mutoo 2013-03-02 13:25:11 +08:00 1
1)使用现成的 js 库,可以在网上找到很多,如
http://www.codeproject.com/Articles/12116/JavaScript-Mathematical-Expression-Evaluator 2)学习编译原理(初级),自己实现一个。 另外给你一个计算器工作原理的介绍: http://zh.wikipedia.org/wiki/逆波兰表示法 |
12
Cadina 2013-03-02 14:01:15 +08:00
中缀表达式变成前缀表达式就行了,比如:
(3+5)*(2-4) (* (+ 3 5) (- 2 4)) 然后按照表达式树递归计算 |
13
yangzh OP |
14
middleware 2013-03-02 17:50:04 +08:00
你不用寫一個完全的編譯器,只是一個簡單的 parser,大約四五條 BNF 語法,生成 AST 之後再從葉子節點開始求值。
|
15
dingstyle 2013-03-03 10:35:32 +08:00
楼上几位说用编译原理转AST都把问题复杂化了吧,这类表达式用调度场算法[1]转换成逆波兰表达式[2]再计算就可以了。
[1]: http://en.wikipedia.org/wiki/Shunting-yard_algorithm [2]: http://en.wikipedia.org/wiki/Reverse_Polish_notation |
16
FrankFang128 2013-03-03 12:33:01 +08:00
1.大段参数的效率比较慢。
效率这种事还是要测试才知道。如果慢得可以接受的话,就没问题。 2.变量作用域默认(好像)是全局作用域。 你在eval加个闭包不就没事了。 3.动态内容可能引入精心构造的恶意代码; 如果只是做计算器用途的话, 可以考虑用字符串替换+正则过滤来处理。 如果只有用户能看到这些代码,恶意就恶意呗,他只能恶到自己。 |