1d5707f13f1f9840f3c7c05adfcd8fa0
2015/12/10 14:34:26 投稿
0

【Refactor Me】((Rubyで) 書いた ((雑な) S式) パーサ)

リファクタリングのネタが思いつかない方のために、beforeコードを用意しました。

このbeforeコードをリファクタリングしてくれた方にも sushi のチャンスがあります!

beforeコードをコピーして新規投稿を作成してね!


((Pythonで) 書く (Lisp) インタプリタ) を見ながらRubyでS式のパーサを書いてみたんだけど…。 もっとかっこよく書けるかな?

Before

def parse(s)
  read_from(tokenize(s))
end

def tokenize(s)
  s.gsub('(', ' ( ').gsub(')', ' ) ').split
end

def read_from(tokens)
  raise 'unexpected EOF while reading' if tokens.empty?
  token = tokens.shift
  if '(' == token
    l = []
    l << read_from(tokens) while tokens[0] != ')'
    tokens.shift                # ')' を削除
    l
  else
    token.to_sym
  end
end

require 'minitest/autorun'

class TestParse < Minitest::Test
  def test_parse
    assert_equal(:a, parse('a'))
    assert_equal([:a, :b, :c], parse('(a b c)'))
    assert_equal([:a, :b, [:c]], parse('(a b (c))'))
    assert_equal([:a, [:b, :c, [:d, :e], :f]],
                 parse('(a (b c (d e) f))'))

    assert_raises { parse('(a b') }
  end
end

After

# your cool parser

みんなのコメント