Après avoir étudié Ruby, je l'ai fait comme un interprète qui peut exécuter quatre règles.
Corps de l'interprète
class Interpreter
  def calc(code)
    create_tokens(code)
    exec(stmt)
  end
  private
  def create_tokens(code)
    @tokens = []
    while !code.empty?
      arr = [
        [/^[0-9]+(\.[0-9]+)?/, "num"],
        [/^[\+\-\*\/]/, "bin"],
        [/^[()]/, "bra"],
        [/^\;/, "semicolon"],
      ]
      token = arr.map { |(regex, type)|
        val = code[regex]
        { type: type, val: val } if !val.nil?
      }.compact.first
      if token.nil?
        code.slice!(0)
      else
        @tokens << token
        code.slice!(0...token[:val].length)
      end
    end
  end
  def stmt
    child = [expr]
    if @tokens.first[:type] == "semicolon"
      item = @tokens.shift
      child << stmt if [email protected]?
      { item: item, child: child }
    end
  end
  def bin(filter, parse)
    node = parse.call
    while [email protected]? && filter.call(@tokens.first[:val])
      node = { item: @tokens.shift, child: [node, parse.call] }
    end
    node
  end
  def expr
    bin(-> (token) { token == "+" || token == "-" }, -> { term })
  end
  def term
    bin(-> (token) { token == "*" || token == "/" }, -> { fact })
  end
  def fact
    if @tokens.first[:val] == "("
      @tokens.shift
      node = expr
      @tokens.shift if @tokens.first[:val] == ")"
      node
    else
      { item: @tokens.shift }
    end
  end
  def exec(node)
    type = node[:item][:type]
    if type == "semicolon"
      left, right = node[:child]
      puts "#{exec(left)}"
      exec(right) if !right.nil?
    elsif type == "bin"
      left, right = node[:child]
      case node[:item][:val]
      when "+"
        exec(left) + exec(right)
      when "-"
        exec(left) - exec(right)
      when "*"
        exec(left) * exec(right)
      when "/"
        exec(left) / exec(right)
      end
    elsif type == "num"
      node[:item][:val].to_f
    end
  end
end
Méthode d'exécution
ip = Interpreter.new
ip.calc "12345679 * 8 + 0.1; 3.1415926535 * 2;"
ip.calc "18782+18782;"
Résultat d'exécution
$ ruby interpreter.rb
98765432.1
6.283185307
37564.0
Ruby, les affectations multiples sont bonnes. Lambda est également facile à écrire. Je voulais le raccourcir un peu (s'il vous plaît quelqu'un).