1require 'psych/handler' 2 3module Psych 4 ### 5 # This class works in conjunction with Psych::Parser to build an in-memory 6 # parse tree that represents a YAML document. 7 # 8 # == Example 9 # 10 # parser = Psych::Parser.new Psych::TreeBuilder.new 11 # parser.parse('--- foo') 12 # tree = parser.handler.root 13 # 14 # See Psych::Handler for documentation on the event methods used in this 15 # class. 16 class TreeBuilder < Psych::Handler 17 # Returns the root node for the built tree 18 attr_reader :root 19 20 # Create a new TreeBuilder instance 21 def initialize 22 @stack = [] 23 @last = nil 24 @root = nil 25 end 26 27 %w{ 28 Sequence 29 Mapping 30 }.each do |node| 31 class_eval %{ 32 def start_#{node.downcase}(anchor, tag, implicit, style) 33 n = Nodes::#{node}.new(anchor, tag, implicit, style) 34 @last.children << n 35 push n 36 end 37 38 def end_#{node.downcase} 39 pop 40 end 41 } 42 end 43 44 ### 45 # Handles start_document events with +version+, +tag_directives+, 46 # and +implicit+ styling. 47 # 48 # See Psych::Handler#start_document 49 def start_document version, tag_directives, implicit 50 n = Nodes::Document.new version, tag_directives, implicit 51 @last.children << n 52 push n 53 end 54 55 ### 56 # Handles end_document events with +version+, +tag_directives+, 57 # and +implicit+ styling. 58 # 59 # See Psych::Handler#start_document 60 def end_document implicit_end = !streaming? 61 @last.implicit_end = implicit_end 62 pop 63 end 64 65 def start_stream encoding 66 @root = Nodes::Stream.new(encoding) 67 push @root 68 end 69 70 def end_stream 71 pop 72 end 73 74 def scalar value, anchor, tag, plain, quoted, style 75 s = Nodes::Scalar.new(value,anchor,tag,plain,quoted,style) 76 @last.children << s 77 s 78 end 79 80 def alias anchor 81 @last.children << Nodes::Alias.new(anchor) 82 end 83 84 private 85 def push value 86 @stack.push value 87 @last = value 88 end 89 90 def pop 91 x = @stack.pop 92 @last = @stack.last 93 x 94 end 95 end 96end 97