2016-04-10 80 views
0

作爲學習Ruby的一部分,我試圖實現一個基本的解釋器,它讀取輸入並進行基本的算術計算。到目前爲止,基本的算術運算正在工作,但在運算符優先級上有問題哪些還沒有處理。這是代碼。我在初學者水平。此代碼中的任何錯誤都是由於我缺乏知識。如何修改此代碼以處理運算符優先級。 示例輸出在我的計算器翻譯器中實現運算符優先級

2+2+2 = 6 #correct 
10+10/2 = 10 # incorrect as in irb answer must be 15 

Github Repo of this interpreter

=begin 
Basic calculator Interpreter 
can add, substract, multiply , divide with any number of operands at a time 
Drawback : Lacks operator precedence 
=end 
class Interpreter 
    attr_accessor :input 
    def initialize 
     @input = gets.chomp    
    end 
    def intepret   
     first_operand = []  
     f    = []  
     operator  = '+'   
     array   = Array.new  
     lc    = 0 

     @input.split.join.split("").each_with_index.map do |i, index| 

      if i.is_number? 
       first_operand.push(i) 
       if index == @input.length-1      
        array.push(first_operand.join("").to_i)     
       end 
      elsif i.is_plus?     
       f = first_operand 
       first_operand = nil 
       first_operand = []    
       array.push(f.join("").to_i) 
       array.push("+") 
      elsif i.is_minus?   
       f = first_operand 
       first_operand = nil 
       first_operand = []    
       operator = '-'    
       array.push(f.join("").to_i) 
       array.push("-") 
      elsif i.is_multi?    
       f = first_operand 
       first_operand = nil 
       first_operand = []    
       operator = '*'    
       array.push(f.join("").to_i) 
       array.push("*") 
      elsif i.is_divide?    
       f = first_operand 
       first_operand = nil 
       first_operand = []    
       operator = '/'    
       array.push(f.join("").to_i) 
       array.push("/") 
      else 
       puts "Illegal input exiting.." 
       exit    
      end    

      lc = lc+1 

     end  
     #apply the appropriate operation on the inputs based on the operand   
     #puts "=======TOKENS======"  
     #puts array.inspect 
     result = 0 
     array.each_with_index.map do |x, key| 
      result = x if key == 0   
      if x == '+' 
       if key == 0 
        result = add(result, array[key+1]) 
       else 
        result = add(result, array [key+1]) 
       end 
      elsif x == '-' 
       if key == 0 
        result = minus(result, array[key+1]) 
       else 
        result = minus(result, array [key+1]) 
       end 
      elsif x == '*' 
       if key == 0 
        result = multi(result, array[key+1]) 
       else 
        result = multi(result, array [key+1]) 
       end 
      elsif x == '/' 
       begin 
        if key == 0 
         result = divide(result, array[key+1]) 
        else 
         result = divide(result, array [key+1]) 
        end 
       rescue 
        puts "Zero Divsion error" 
        exit 
       end 
      end 
     end 
     puts "Result is: "+result.to_s 
    end 
    def print_token(type, value) 
     puts type + ' '+ value 
    end 
    def add(f,s) 
     return f.to_i + s.to_i 
    end 
    def minus(f,s) 
     return f.to_i - s.to_i 
    end 
    def multi(f,s) 
     return f.to_i * s.to_i 
    end 
    def divide(f,s) 
     return f.to_i/s.to_i 
    end 
end 
# Override the string class, to directly use methods like obj.is_number? rather than is_number?(obj) 
class String 
    def is_number? 
    true if Float(self) rescue false 
    end 
    def is_plus? 
    true if self == '+' rescue false 
    end 
    def is_minus? 
    true if self == '-' rescue false 
    end 
    def is_multi? 
    true if self == '*' rescue false 
    end 
    def is_divide? 
    true if self == '/' rescue false 
    end 
end 
#continue accepting inputs until exit CTRL + D 
while true 
    print 'pck>:' 
    i_obj = Interpreter.new 
    i_obj.intepret 
end 
+0

除'is_number?'以外的所有String查詢方法都可以簡化爲'self =='operator'',因爲它們不會給出錯誤,您可以安全地移除'rescue'。 –

+0

@SilverPhoenix感謝您的幫助,但這不能回答我的問題。 –

回答