J'ai fait un interpréteur (compilateur?) Avec environ 80 lignes en Ruby.

Après avoir étudié Ruby, je l'ai fait comme un interprète qui peut exécuter quatre règles.

code

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

Impressions

Ruby, les affectations multiples sont bonnes. Lambda est également facile à écrire. Je voulais le raccourcir un peu (s'il vous plaît quelqu'un).

Recommended Posts

J'ai fait un interpréteur (compilateur?) Avec environ 80 lignes en Ruby.
J'ai fait une annotation en Java.
J'ai créé un serveur écologique avec scala
J'ai fait une mort risquée avec Ruby
J'ai fait un blackjack avec Ruby (j'ai essayé d'utiliser minitest)
J'ai créé une bibliothèque d'extension Ruby en C
J'ai fait un portfolio avec Ruby On Rails
J'ai écrit sur Java downcast d'une manière facile à comprendre
[Ruby] J'ai fait un robot avec de l'anémone et du nokogiri.
J'ai créé une application Android qui GET avec HTTP
J'ai essayé DI avec Ruby
Je veux pousser une application créée avec Rails 6 vers GitHub
J'ai fait une roulette à Java.
J'ai fait un adaptateur pour la classe de communication avec Retrofit2 + Rx2
J'ai mis à jour mon propre blackjack réalisé avec Ruby pour mon portfolio
J'ai recherché un framework web avec Gem en Ruby
À propos des expressions régulières dans Ruby
J'ai essayé d'utiliser Ruby pour voir s'il y a un nombre capreca dans un entier dans une certaine plage
J'ai envoyé un e-mail en Java
J'ai créé une interface graphique avec Swing
À propos de la création d'applications avec Springboot
[Super Introduction] À propos des symboles dans Ruby
Exécuter des applications écrites en Java8 en Java6
Segfo Ruby en 2 lignes
J'ai essayé de résoudre le problème de la séquence Tribonacci en Ruby, avec récurrence.
Je veux ForEach un tableau avec une expression Lambda en Java
L'histoire de la rencontre d'un débordement arithmétique qui ne devrait pas être rencontré dans Ruby
J'ai essayé un problème de calendrier avec Ruby
Envoyer des e-mails depuis Gmail avec Ruby
[Ruby] J'ai créé un simple client Ping
J'ai fait diverses fonctions de la séquence de Fibonacci (Ruby)
Méthodes que j'ai trouvées utiles dans Ruby
J'ai créé une application Janken avec kotlin
J'ai créé une application Janken avec Android