def initialize source
parser = REXML::Parsers::BaseParser.new( source )
@root = @current = State.new
previous = @current
branches = []
slinker = [ ]
elinker = [ ]
sequence = lambda {|e| previous = previous[ e ] = State.new }
oneplus = lambda {|e|
slinker.pop
s = slinker[-1].call( e )
branches << [e, s]
s
}
zeroplus = lambda {|e|
branches.pop[e] = sequence.call( e )
elinker.pop
}
schoice = lambda {|e|
previous = branches[-2]
sequence.call( e )
}
echoice = lambda {|e| previous[e] = branches[-1] }
slinker << sequence
elinker << sequence
begin
event = parser.pull
case event[0]
when :start_element
case event[1]
when "element"
evt = Event.new( event[0], event[2]["name"] )
slinker[-1].call( evt )
slinker << sequence
when "attribute"
evt = Event.new( :has_attribute, event[2]["name"] )
slinker[-1].call( evt )
when "optional"
branches << previous
elinker << zeroplus
when "choice"
branches << previous
branches << State.new
slinker << schoice
elinker << echoice
when "oneOrMore"
slinker << oneplus
when "zeroOrMore"
branches << previous
slinker << oneplus
when "empty"
when "text"
evt = Event.new( :text )
slinker[-1].call(evt)
end
when :end_element
case event[1]
when "element"
evt = Event.new( event[0] )
elinker[-1].call( evt )
slinker.pop
when "attribute"
when "zeroOrMore"
e,s = branches.pop
previous[e] = s
elinker << zeroplus
when "oneOrMore"
e,s = branches.pop
previous[ e ] = s
when "choice"
slinker.pop
elinker.pop
previous = branches.pop
branches.pop
when "optional"
when "empty"
end
when :end_document
previous[ Event.new( event[0] ) ] = State.new
end
end while event[0] != :end_document
end