応用編

kyowa.y

class Kyowa
options no_result_var
rule
  exp:
     | exp ope

  ope: '(」・ω・)」きょう(/・ω・)/わー'
       {
         @ptr += 1
       }
     | '(」・ω・)」きょう!!(/・ω・)/わー!!'
       {
         @ptr -= 1
       }
     | '(」・ω・)」きょう!(/・ω・)/わー!'
       {
         @ary[@ptr] ||= 0
         @ary[@ptr] += 1
       }
     | '(」・ω・)」きょう!!!(/・ω・)/わー!!!'
       {
         @ary[@ptr] ||= 0
         @ary[@ptr] -= 1
       }
     | "Let's\(・ω・)/わー"
       {
         print (@ary[@ptr] || 0).chr
       }
     | '弊社!'
       {
         @ary[@ptr] = $stdin.getc # XXX: Ruby 1.9では動作が異なる
       }
     | 'KATSUMA☆KATSUMA!'
       {
         if (@ary[@ptr] || 0).zero?
           @ss.scan_until(/I WANNA KATSUMA!/)
         else
           @stack.push('')
         end
       }
     | 'I WANNA KATSUMA!'
       {
         if (buf = @stack.pop)
           @ss = StringScanner.new(buf + 'I WANNA KATSUMA!' + @ss.rest)
         end
       }
end

---- header

$KCODE = 's'

require 'strscan'
require 'readline'

---- inner

attr_reader :ptr
attr_reader :ary
attr_reader :stack

def initialize
  @ptr = 0
  @ary = []
  @stack = []
end

def scan
  until @ss.eos?
    tok = nil

    if tok = @ss.scan(/\(」・ω・\)」きょう!!!\(/・ω・\)/わー!!!/)
      yield tok, tok
    elsif tok = @ss.scan(/\(」・ω・\)」きょう!!\(/・ω・\)/わー!!/)
      yield tok, tok
    elsif tok = @ss.scan(/\(」・ω・\)」きょう!\(/・ω・\)/わー!/)
      yield tok, tok
    elsif tok = @ss.scan(/\(」・ω・\)」きょう\(/・ω・\)/わー/)
      yield tok, tok
    elsif tok = @ss.scan(/KATSUMA☆KATSUMA!/)
      yield tok, tok
    elsif tok = @ss.scan(/I WANNA KATSUMA!/)
      yield tok, tok
    elsif tok = @ss.scan(/Let's\\(・ω・\)/わー/) #'
      yield tok, tok
    elsif tok = @ss.scan(/弊社!/)
      yield tok, tok
    else
      @ss.getch
      tok = nil
    end

    @stack.last << tok if tok && @stack.last
  end

  yield false, '$'
end

def parse(src)
  @ss = StringScanner.new(src)
  yyparse self, :scan
end

---- footer

parser = Kyowa.new

if ARGV.empty?
  while buf = Readline.readline('kyowa> ', true)
    parser.parse(buf)
    puts <<-EOS
---
ptr: #{parser.ptr}
ary: #{parser.ary.inspect}
stack: #{parser.stack.inspect}

    EOS
  end
else
  ARGV.each do |fn|
    parser.parse(open(fn) {|f| f.read })
  end
end

Hello World!

(」・ω・)」きょう(/・ω・)/わー(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!KATSUMA☆KATSUMA!(」・ω・)」きょう!!(/・ω・)/わー!!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう(/・ω・)/わー(」・ω・)」きょう!!!(/・ω・)/わー!!!I WANNA KATSUMA!(」・ω・)」きょう!!(/・ω・)/わー!!Let's\(・ω・)/わー(」・ω・)」きょう(/・ω・)/わー(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!KATSUMA☆KATSUMA!(」・ω・)」きょう!!(/・ω・)/わー!!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう(/・ω・)/わー(」・ω・)」きょう!!!(/・ω・)/わー!!!I WANNA KATSUMA!(」・ω・)」きょう!!(/・ω・)/わー!!(」・ω・)」きょう!(/・ω・)/わー!Let's\(・ω・)/わー(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!Let's\(・ω・)/わーLet's\(・ω・)/わー(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!Let's\(・ω・)/わーKATSUMA☆KATSUMA!(」・ω・)」きょう!!!(/・ω・)/わー!!!I WANNA KATSUMA!(」・ω・)」きょう(/・ω・)/わー(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!KATSUMA☆KATSUMA!(」・ω・)」きょう!!(/・ω・)/わー!!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう(/・ω・)/わー(」・ω・)」きょう!!!(/・ω・)/わー!!!I WANNA KATSUMA!(」・ω・)」きょう!!(/・ω・)/わー!!Let's\(・ω・)/わー(」・ω・)」きょう(/・ω・)/わー(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!KATSUMA☆KATSUMA!(」・ω・)」きょう!!(/・ω・)/わー!!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう(/・ω・)/わー(」・ω・)」きょう!!!(/・ω・)/わー!!!I WANNA KATSUMA!(」・ω・)」きょう!!(/・ω・)/わー!!Let's\(・ω・)/わー(」・ω・)」きょう(/・ω・)/わー(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!KATSUMA☆KATSUMA!(」・ω・)」きょう!!(/・ω・)/わー!!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう(/・ω・)/わー(」・ω・)」きょう!!!(/・ω・)/わー!!!I WANNA KATSUMA!(」・ω・)」きょう!!(/・ω・)/わー!!Let's\(・ω・)/わー(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!Let's\(・ω・)/わー(」・ω・)」きょう!!!(/・ω・)/わー!!!(」・ω・)」きょう!!!(/・ω・)/わー!!!(」・ω・)」きょう!!!(/・ω・)/わー!!!(」・ω・)」きょう!!!(/・ω・)/わー!!!(」・ω・)」きょう!!!(/・ω・)/わー!!!(」・ω・)」きょう!!!(/・ω・)/わー!!!Let's\(・ω・)/わー(」・ω・)」きょう!!!(/・ω・)/わー!!!(」・ω・)」きょう!!!(/・ω・)/わー!!!(」・ω・)」きょう!!!(/・ω・)/わー!!!(」・ω・)」きょう!!!(/・ω・)/わー!!!(」・ω・)」きょう!!!(/・ω・)/わー!!!(」・ω・)」きょう!!!(/・ω・)/わー!!!(」・ω・)」きょう!!!(/・ω・)/わー!!!(」・ω・)」きょう!!!(/・ω・)/わー!!!Let's\(・ω・)/わーKATSUMA☆KATSUMA!(」・ω・)」きょう!!!(/・ω・)/わー!!!I WANNA KATSUMA!(」・ω・)」きょう(/・ω・)/わー(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!KATSUMA☆KATSUMA!(」・ω・)」きょう!!(/・ω・)/わー!!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう(/・ω・)/わー(」・ω・)」きょう!!!(/・ω・)/わー!!!I WANNA KATSUMA!(」・ω・)」きょう!!(/・ω・)/わー!!(」・ω・)」きょう!(/・ω・)/わー!Let's\(・ω・)/わーKATSUMA☆KATSUMA!(」・ω・)」きょう!!!(/・ω・)/わー!!!I WANNA KATSUMA!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!(」・ω・)」きょう!(/・ω・)/わー!Let's\(・ω・)/わー


shell> racc kyowa.y
shell> ruby kyowa.tab.rb helloworld.kyowa
Hello World!