当前位置: 首页 > 工具软件 > MoonScript > 使用案例 >

用MoonScript实现算术表达式解析

汪翰墨
2023-12-01



“算术表达式”有两种形式:

  1. 一个数
  2. 一个 '(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 )'


 类似资料: