mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* bin/irb lib/irb.rb lib/irb/...: IRB 0.9.5.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@8322 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
c56355fbdc
commit
622b522047
33 changed files with 464 additions and 337 deletions
394
lib/irb/slex.rb
394
lib/irb/slex.rb
|
@ -1,9 +1,9 @@
|
|||
#
|
||||
# irb/slex.rb - symple lex analizer
|
||||
# $Release Version: 0.9$
|
||||
# $Release Version: 0.9.5$
|
||||
# $Revision$
|
||||
# $Date$
|
||||
# by Keiju ISHITSUKA(keiju@ishituska.com)
|
||||
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
||||
#
|
||||
# --
|
||||
#
|
||||
|
@ -11,229 +11,234 @@
|
|||
#
|
||||
|
||||
require "e2mmap"
|
||||
require "irb/notifier"
|
||||
|
||||
class SLex
|
||||
@RCS_ID='-$Id$-'
|
||||
module IRB
|
||||
class SLex
|
||||
@RCS_ID='-$Id$-'
|
||||
|
||||
extend Exception2MessageMapper
|
||||
def_exception :ErrNodeNothing, "node nothing"
|
||||
def_exception :ErrNodeAlreadyExists, "node already exists"
|
||||
extend Exception2MessageMapper
|
||||
def_exception :ErrNodeNothing, "node nothing"
|
||||
def_exception :ErrNodeAlreadyExists, "node already exists"
|
||||
|
||||
class << self
|
||||
attr_accessor :debug_level
|
||||
def debug?
|
||||
debug_level > 0
|
||||
end
|
||||
end
|
||||
@debug_level = 0
|
||||
|
||||
def initialize
|
||||
@head = Node.new("")
|
||||
end
|
||||
|
||||
def def_rule(token, preproc = nil, postproc = nil, &block)
|
||||
# print node.inspect, "\n" if SLex.debug?
|
||||
postproc = block if block_given?
|
||||
node = create(token, preproc, postproc)
|
||||
end
|
||||
|
||||
def def_rules(*tokens, &block)
|
||||
if block_given?
|
||||
p = block
|
||||
end
|
||||
for token in tokens
|
||||
def_rule(token, nil, p)
|
||||
end
|
||||
end
|
||||
|
||||
def preproc(token, proc)
|
||||
node = search(token)
|
||||
node.preproc=proc
|
||||
end
|
||||
|
||||
def postproc(token)
|
||||
node = search(token, proc)
|
||||
node.postproc=proc
|
||||
end
|
||||
|
||||
def search(token)
|
||||
@head.search(token.split(//))
|
||||
end
|
||||
|
||||
def create(token, preproc = nil, postproc = nil)
|
||||
@head.create_subnode(token.split(//), preproc, postproc)
|
||||
end
|
||||
|
||||
def match(token)
|
||||
case token
|
||||
when Array
|
||||
when String
|
||||
return match(token.split(//))
|
||||
else
|
||||
return @head.match_io(token)
|
||||
end
|
||||
ret = @head.match(token)
|
||||
printf "match end: %s:%s", ret, token.inspect if SLex.debug?
|
||||
ret
|
||||
end
|
||||
|
||||
def inspect
|
||||
format("<SLex: @head = %s>", @head.inspect)
|
||||
end
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
#
|
||||
# class Node -
|
||||
#
|
||||
#----------------------------------------------------------------------
|
||||
class Node
|
||||
# if postproc is nil, this node is an abstract node.
|
||||
# if postproc is non-nil, this node is a real node.
|
||||
def initialize(preproc = nil, postproc = nil)
|
||||
@Tree = {}
|
||||
@preproc = preproc
|
||||
@postproc = postproc
|
||||
end
|
||||
|
||||
attr_accessor :preproc
|
||||
attr_accessor :postproc
|
||||
DOUT = Notifier::def_notifier("SLex::")
|
||||
D_WARN = DOUT::def_notifier(1, "Warn: ")
|
||||
D_DEBUG = DOUT::def_notifier(2, "Debug: ")
|
||||
D_DETAIL = DOUT::def_notifier(4, "Detail: ")
|
||||
|
||||
def search(chrs, opt = nil)
|
||||
return self if chrs.empty?
|
||||
ch = chrs.shift
|
||||
if node = @Tree[ch]
|
||||
node.search(chrs, opt)
|
||||
DOUT.level = Notifier::D_NOMSG
|
||||
|
||||
def initialize
|
||||
@head = Node.new("")
|
||||
end
|
||||
|
||||
def def_rule(token, preproc = nil, postproc = nil, &block)
|
||||
D_DETAIL.pp token
|
||||
|
||||
postproc = block if block_given?
|
||||
node = create(token, preproc, postproc)
|
||||
end
|
||||
|
||||
def def_rules(*tokens, &block)
|
||||
if block_given?
|
||||
p = block
|
||||
end
|
||||
for token in tokens
|
||||
def_rule(token, nil, p)
|
||||
end
|
||||
end
|
||||
|
||||
def preproc(token, proc)
|
||||
node = search(token)
|
||||
node.preproc=proc
|
||||
end
|
||||
|
||||
#$BMW%A%'%C%/(B?
|
||||
def postproc(token)
|
||||
node = search(token, proc)
|
||||
node.postproc=proc
|
||||
end
|
||||
|
||||
def search(token)
|
||||
@head.search(token.split(//))
|
||||
end
|
||||
|
||||
def create(token, preproc = nil, postproc = nil)
|
||||
@head.create_subnode(token.split(//), preproc, postproc)
|
||||
end
|
||||
|
||||
def match(token)
|
||||
case token
|
||||
when Array
|
||||
when String
|
||||
return match(token.split(//))
|
||||
else
|
||||
if opt
|
||||
chrs.unshift ch
|
||||
self.create_subnode(chrs)
|
||||
else
|
||||
SLex.fail ErrNodeNothing
|
||||
end
|
||||
return @head.match_io(token)
|
||||
end
|
||||
ret = @head.match(token)
|
||||
D_DETAIL.exec_if{D_DEATIL.printf "match end: %s:%s\n", ret, token.inspect}
|
||||
ret
|
||||
end
|
||||
|
||||
def create_subnode(chrs, preproc = nil, postproc = nil)
|
||||
if chrs.empty?
|
||||
if @postproc
|
||||
SLex.fail ErrNodeAlreadyExists
|
||||
else
|
||||
print "Warn: change abstract node to real node\n" if SLex.debug?
|
||||
@preproc = preproc
|
||||
@postproc = postproc
|
||||
end
|
||||
return self
|
||||
def inspect
|
||||
format("<SLex: @head = %s>", @head.inspect)
|
||||
end
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
#
|
||||
# class Node -
|
||||
#
|
||||
#----------------------------------------------------------------------
|
||||
class Node
|
||||
# if postproc is nil, this node is an abstract node.
|
||||
# if postproc is non-nil, this node is a real node.
|
||||
def initialize(preproc = nil, postproc = nil)
|
||||
@Tree = {}
|
||||
@preproc = preproc
|
||||
@postproc = postproc
|
||||
end
|
||||
|
||||
attr_accessor :preproc
|
||||
attr_accessor :postproc
|
||||
|
||||
ch = chrs.shift
|
||||
if node = @Tree[ch]
|
||||
if chrs.empty?
|
||||
if node.postproc
|
||||
p node
|
||||
p self
|
||||
p ch
|
||||
p chrs
|
||||
SLex.fail ErrNodeAlreadyExists
|
||||
else
|
||||
print "Warn: change abstract node to real node\n" if SLex.debug?
|
||||
node.preproc = preproc
|
||||
node.postproc = postproc
|
||||
end
|
||||
else
|
||||
node.create_subnode(chrs, preproc, postproc)
|
||||
end
|
||||
else
|
||||
if chrs.empty?
|
||||
node = Node.new(preproc, postproc)
|
||||
else
|
||||
node = Node.new
|
||||
node.create_subnode(chrs, preproc, postproc)
|
||||
end
|
||||
@Tree[ch] = node
|
||||
end
|
||||
node
|
||||
end
|
||||
|
||||
#
|
||||
# chrs: String
|
||||
# character array
|
||||
# io must have getc()/ungetc(); and ungetc() must be
|
||||
# able to be called arbitrary number of times.
|
||||
#
|
||||
def match(chrs, op = "")
|
||||
print "match>: ", chrs, "op:", op, "\n" if SLex.debug?
|
||||
if chrs.empty?
|
||||
if @preproc.nil? || @preproc.call(op, chrs)
|
||||
printf "op1: %s\n", op if SLex.debug?
|
||||
@postproc.call(op, chrs)
|
||||
else
|
||||
nil
|
||||
end
|
||||
else
|
||||
def search(chrs, opt = nil)
|
||||
return self if chrs.empty?
|
||||
ch = chrs.shift
|
||||
if node = @Tree[ch]
|
||||
if ret = node.match(chrs, op+ch)
|
||||
return ret
|
||||
node.search(chrs, opt)
|
||||
else
|
||||
if opt
|
||||
chrs.unshift ch
|
||||
self.create_subnode(chrs)
|
||||
else
|
||||
SLex.fail ErrNodeNothing
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def create_subnode(chrs, preproc = nil, postproc = nil)
|
||||
if chrs.empty?
|
||||
if @postproc
|
||||
D_DETAIL.pp node
|
||||
SLex.fail ErrNodeAlreadyExists
|
||||
else
|
||||
D_DEBUG.puts "change abstract node to real node."
|
||||
@preproc = preproc
|
||||
@postproc = postproc
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
ch = chrs.shift
|
||||
if node = @Tree[ch]
|
||||
if chrs.empty?
|
||||
if node.postproc
|
||||
DebugLogger.pp node
|
||||
DebugLogger.pp self
|
||||
DebugLogger.pp ch
|
||||
DebugLogger.pp chrs
|
||||
SLex.fail ErrNodeAlreadyExists
|
||||
else
|
||||
D_WARN.puts "change abstract node to real node"
|
||||
node.preproc = preproc
|
||||
node.postproc = postproc
|
||||
end
|
||||
else
|
||||
node.create_subnode(chrs, preproc, postproc)
|
||||
end
|
||||
else
|
||||
if chrs.empty?
|
||||
node = Node.new(preproc, postproc)
|
||||
else
|
||||
node = Node.new
|
||||
node.create_subnode(chrs, preproc, postproc)
|
||||
end
|
||||
@Tree[ch] = node
|
||||
end
|
||||
node
|
||||
end
|
||||
|
||||
#
|
||||
# chrs: String
|
||||
# character array
|
||||
# io must have getc()/ungetc(); and ungetc() must be
|
||||
# able to be called arbitrary number of times.
|
||||
#
|
||||
def match(chrs, op = "")
|
||||
D_DETAIL.print "match>: ", chrs, "op:", op, "\n"
|
||||
if chrs.empty?
|
||||
if @preproc.nil? || @preproc.call(op, chrs)
|
||||
DOUT.printf(D_DETAIL, "op1: %s\n", op)
|
||||
@postproc.call(op, chrs)
|
||||
else
|
||||
nil
|
||||
end
|
||||
else
|
||||
ch = chrs.shift
|
||||
if node = @Tree[ch]
|
||||
if ret = node.match(chrs, op+ch)
|
||||
return ret
|
||||
else
|
||||
chrs.unshift ch
|
||||
if @postproc and @preproc.nil? || @preproc.call(op, chrs)
|
||||
DOUT.printf(D_DETAIL, "op2: %s\n", op.inspect)
|
||||
ret = @postproc.call(op, chrs)
|
||||
return ret
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
else
|
||||
chrs.unshift ch
|
||||
if @postproc and @preproc.nil? || @preproc.call(op, chrs)
|
||||
printf "op2: %s\n", op.inspect if SLex.debug?
|
||||
ret = @postproc.call(op, chrs)
|
||||
return ret
|
||||
DOUT.printf(D_DETAIL, "op3: %s\n", op)
|
||||
@postproc.call(op, chrs)
|
||||
return ""
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
else
|
||||
chrs.unshift ch
|
||||
if @postproc and @preproc.nil? || @preproc.call(op, chrs)
|
||||
printf "op3: %s\n", op if SLex.debug?
|
||||
@postproc.call(op, chrs)
|
||||
return ""
|
||||
else
|
||||
end
|
||||
end
|
||||
|
||||
def match_io(io, op = "")
|
||||
if op == ""
|
||||
ch = io.getc
|
||||
if ch == nil
|
||||
return nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def match_io(io, op = "")
|
||||
if op == ""
|
||||
ch = io.getc
|
||||
if ch == nil
|
||||
return nil
|
||||
end
|
||||
else
|
||||
ch = io.getc_of_rests
|
||||
end
|
||||
if ch.nil?
|
||||
if @preproc.nil? || @preproc.call(op, io)
|
||||
printf "op1: %s\n", op if SLex.debug?
|
||||
@postproc.call(op, io)
|
||||
else
|
||||
nil
|
||||
ch = io.getc_of_rests
|
||||
end
|
||||
else
|
||||
if node = @Tree[ch]
|
||||
if ret = node.match_io(io, op+ch)
|
||||
ret
|
||||
if ch.nil?
|
||||
if @preproc.nil? || @preproc.call(op, io)
|
||||
D_DETAIL.printf("op1: %s\n", op)
|
||||
@postproc.call(op, io)
|
||||
else
|
||||
nil
|
||||
end
|
||||
else
|
||||
if node = @Tree[ch]
|
||||
if ret = node.match_io(io, op+ch)
|
||||
ret
|
||||
else
|
||||
io.ungetc ch
|
||||
if @postproc and @preproc.nil? || @preproc.call(op, io)
|
||||
DOUT.exec_if(D_DETAIL) {printf "op2: %s\n", op.inspect}
|
||||
@postproc.call(op, io)
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
else
|
||||
io.ungetc ch
|
||||
if @postproc and @preproc.nil? || @preproc.call(op, io)
|
||||
printf "op2: %s\n", op.inspect if SLex.debug?
|
||||
D_DETAIL.printf("op3: %s\n", op)
|
||||
@postproc.call(op, io)
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
else
|
||||
io.ungetc ch
|
||||
if @postproc and @preproc.nil? || @preproc.call(op, io)
|
||||
printf "op3: %s\n", op if SLex.debug?
|
||||
@postproc.call(op, io)
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -275,3 +280,4 @@ if $0 == __FILE__
|
|||
end
|
||||
exit
|
||||
end
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue