Skip to content

Instantly share code, notes, and snippets.

@maehrm
Last active June 16, 2018 01:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maehrm/0d709c4eb785df121aca175dbc419263 to your computer and use it in GitHub Desktop.
Save maehrm/0d709c4eb785df121aca175dbc419263 to your computer and use it in GitHub Desktop.
作ろう、ミニ言語 | 初心者向け | DoRuby https://doruby.jp/users/yam/entries/mini_lang
# coding: utf-8
class RacoonParser
rule
start code
code : code s_exp
| s_exp
s_exp : '(' func params ')' { result = @racoon.send(val[1], val[2]) }
param : s_exp
| atom
params : params param { result = val[0..1] }
| param
func : TEXT
| ID
atom : DEC
| TEXT { result = @racoon.vars[val[0]] if @racoon.vars[val[0]] }
| ID
end
---- header
require 'strscan'
---- inner
attr_accessor :racoon
def parse(str)
scanner = StringScanner.new(str)
@q = []
until scanner.eos?
scanner.scan(/#[^\n]*\n/) ? nil :
scanner.scan(/\s+/) ? nil :
scanner.scan(/\d+/) ? @q << [:DEC, scanner.matched] :
scanner.scan(/[\(|\)]/) ? @q << [scanner.matched, scanner.matched] :
scanner.scan(/[a-zA-Z0-9\-\_\/]+/) ? @q << [:TEXT, scanner.matched] :
scanner.scan(/./) ? @q << [:ID, scanner.matched] :
nil
end
do_parse
end
def next_token
@q.shift
end
---- footer
class Racoon
attr_accessor :vars
def initialize
@vars = Hash.new
end
%w(+ - * /).each{|id|
define_method(id) {|args|
args.flatten.map(&:to_i).inject(id.to_sym)
}
}
def var(args)
variable_name, value = args
@vars[variable_name] = value
end
def display(args)
puts "=> #{args}"
end
end
parser = RacoonParser.new
parser.racoon = Racoon.new
line_count = 0
loop do
begin
line_count += 1
print "#{line_count.to_s.rjust(3, '0')} #{0x1F363.chr("UTF-8")} > "
parser.parse(gets)
rescue Racc::ParseError => e
$stderr.puts e
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment