永发信息网

Ruby写的一个对四则运算表达式解析和求值的程序

答案:2  悬赏:50  手机版
解决时间 2021-04-13 05:56
Ruby写的一个对四则运算表达式解析和求值的程序
最佳答案
加上#encoding:utf-8
全部回答
class ParseError < Exception
end
#词法分析类
class Lex
        def initialize(strExp)
                @strExp = strExp.gsub(/s+/, '')
        end
        def nextToken
                if @strExp =~ /^d+/
                        @strExp = $'
                        $&.to_i
                elsif @strExp =~ /^(+|-|*|/|(|))/
                        @strExp = $'
                        $&
                elsif @strExp =~ /^$/
                        nil
                else
                        raise ParseError.new('Unknown character ==> ' 
                                + @strExp)
                end
        end
end
#语法分析和求值在这里一勺烩了
class Syntax
        def parse(&procToken)
                @procToken = procToken
                nextToken
                val = exp
                matchType(NilClass)
                return val
        end
private
        def nextToken
                @currentToken = @procToken.call
        end
        def matchStr(t)
                if @currentToken.is_a?(String) and @currentToken == t
                        nextToken
                        return t
                else
                        requireError(t)
                end
        end
        def matchType(t)
                tmp = @currentToken
                if @currentToken.is_a?(t)
                        nextToken
                        return tmp
                else
                        requireError(t.class)
                end
        end
        def requireError(*a)
                raise ParseError.new(
                        "require '#{a.join(',')}', " + 
                                "token='#{@currentToken}'")
        end
        def exp
                val = term
                while TRUE
                        if @currentToken == '+'
                                matchStr('+')
                                val += term
                        elsif @currentToken == '-'
                                matchStr('-')
                                val -= term
                        else
                                break
                        end
                end
                return val
        end
        def term
                val = factor
                while TRUE
                        if @currentToken == '*'
                                matchStr('*')
                                val *= factor
                        elsif @currentToken == '/'
                                matchStr('/')
                                d = factor
                                raise '除数为零' if d == 0
                                val /= d
                        else
                                break
                        end
                end
                return val
        end
        def factor
                if @currentToken.is_a?(Integer)
                        return matchType(Integer)
                elsif @currentToken == '('
                        matchStr('(')
                        val = exp
                        matchStr(')')
                        return val
                else
                        requireError(['Integer', '('])
                end
        end
end
#为了方便使用定义一个包装函数
def parseExp(exp)
        l = Lex.new(exp)
        s = Syntax.new
        s.parse { l.nextToken }
end
#测试代码
EXPS = %w{
        100
        (1)
        1+2
        1*3
        1+2-3
        5-2-1
        5-(2-1)
        1-2*3
        (1-2)*3
        4/2
        (1+2)*(3+4)
        (1+2)*(3+(4*2))
        1+(2+3 
        1+2+
        1++
        4/(1-1)
}
EXPS.each do
        |x|
        begin
                puts "#{x}=#{parseExp(x)}"
        rescue Exception => e
                puts "*Error* #{e}(#{e.class}), exp=#{x}"
        end
end
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
如果是爱上了一个人,没有理由的爱的很深的,
wapqq用户怎么点亮??
联通综合营业厅在什么地方啊,我要过去处理事
怀孕七个月了,有霉菌性**炎,这几天胎儿又下坠
我是阳历1991年5月26日出生,请问一生的事业
木叶白牙和波风水门哪个厉害?
(20分)阅读材料,回答下列问题。“中国网事
婚纱礼服设计的工资高吗?
姜粉有什么功效,烧仙草常期食用有什么好处和
关于补钙的问题
浙江宏业工艺品有限公司地址有知道的么?有点
仟达炊饭地址在哪,我要去那里办事
我为什么还想以前男朋,他都要结婚了,我是不
二代宠物能和一代宠物结婚吗?
单选题She_______tothewaiterwhoselanguage
推荐资讯
粤港通风尚汽车美容地址有知道的么?有点事想
使用飞信发短信要不要钱?
梦幻坐骑成长有什么用
上海西界酒吧味道怎么样?
51的相册MTV又能制作成碟片吗
单选题在重庆打工的河南籍农民工黑新雯成为我
关于文言文的问题
铁的单质在什么情况下可以氧化成四氧化三铁?
东芝L525分区问题
请问武林外传仓库元宝密码清空要多少天?
单选题四种金属X、Y、Z、W其中Y与W和稀硫酸反
龙腾世纪:起源,背包和等级问题?
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?