问题描述
作为学习的一部分,Ruby试图实现一个基本的解释器,该解释器读取输入并进行基本的算术计算.到目前为止,基本的算术运算都可以运行,但是运算符优先级存在问题.尚未处理.这是代码.我是初学者.这段代码中的任何错误均归因于我缺乏知识.如何修改此代码以处理运算符优先级.样本输出
As part of learning Ruby am trying to implement a basic interpreter which reads input and do basic arithmetic calculations. So far basic arithmetic operations are working but having problem in operator precedence. Which is not handled yet. This is the code. Am at a beginner level. Any mistakes in this code are due to my lack of knowledge. How this code can be modified to handle operator precedence.Sample output
2+2+2 = 6 #correct
10+10/2 = 10 # incorrect as in irb answer must be 15
=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
推荐答案
首先,使用分流来处理输入码算法.这应该以反向波兰符号(RPN)给出令牌列表.然后,您可以评估RPN表达式.
First, process the input using the Shunting-yard algorithm. This should give a list of tokens in Reverse Polish notation (RPN). Then you can evaluate the RPN expression.
这篇关于在我的计算器解释器中实现运算符优先级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!