“算术表达式”有两种形式:
- 一个数
- 一个
'(op e1 e2)
这样的结构(其中e1
和e2
是两个“算术表达式”
代码如下
其实就是一个解释器,用递归下降的方式实现
--chekck token is number isnumber = (exp) -> tonumber(exp) ~= nil isspace = (c) -> c == ' ' or c == '\t' len = (exp) -> string.len(exp) --trim space trim = (exp ,pos) -> while pos <= len(exp) and isspace string.sub(exp,pos,pos) pos += 1 pos --get token from pos and return next valid pos token = (exp,pos) -> pos = trim(exp,pos) if pos > len(exp) return nil,pos lpos = pos while pos <= len(exp) and not isspace string.sub(exp,pos,pos) pos += 1 t = string.sub(exp,lpos,pos-1) return t,pos calc = (exp,pos)-> t ,pos = token(exp,pos) if t == nil return nil,pos if isnumber t return tonumber(t),pos if t == '(' op,pos = token(exp,pos) v1 ,pos = calc(exp,pos) v2,pos = calc(exp,pos) t ,pos = token(exp,pos) if( t ~= ')') return nil,pos v = nil switch op when '+' v = v1 + v2 when '-' v = v1 - v2 when '/' v = v1 / v2 when '*' v = v1 / v2 else v = nil return v,pos else return nil,pos run = (exp) -> r,pos = calc(exp,1) if r == nil print('error exp ',exp,'at pos ',pos) return r print run '( / ( + 100 2 ) 3 )' print run '( - ( + ( * 10.25 333 ) 999 ) 100 )' print rum '(+ 1 2)' --failed print run ' + 1 ' print run '( / ( + 1 2 3 )' print run '( ^ 1 2 )'