Class: XRT::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/xrt/parser.rb

Instance Method Summary collapse

Constructor Details

#initialize(source = '') ⇒ Parser

Returns a new instance of Parser.



5
6
7
# File 'lib/xrt/parser.rb', line 5

def initialize(source='')
  @source = source
end

Instance Method Details

#documentObject



9
10
11
12
13
14
15
16
# File 'lib/xrt/parser.rb', line 9

def document
  doc = XRT::Statement::Document.new

  tokenized = self.tokens

  parse_contents(tokenized, doc)
  doc
end

#parse_contents(tokenized, node) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/xrt/parser.rb', line 18

def parse_contents(tokenized, node)
  while tokenized.length > 0
    statement = XRT::Statement::Factory.new_from_content(tokenized.shift)
    case statement
    when XRT::Statement::Block
      parse_contents(tokenized, statement)
      node << statement
    when XRT::Statement::End
      node << statement
      break
    when XRT::Statement::Text
      node << statement
    when XRT::Statement::Whitespace
      node << statement
    when XRT::Statement::Directive
      node << statement
    end
  end

  node
end

#read_directive(source) ⇒ Object



70
71
72
73
74
75
76
77
78
79
# File 'lib/xrt/parser.rb', line 70

def read_directive source
  return nil unless source[0...2] == '[%'

  buffer = ''
  while source[0...2] != '%]'
    buffer << source.slice!(0)
  end
  buffer << source.slice!(0, 2)
  buffer
end

#read_text(source) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/xrt/parser.rb', line 81

def read_text source
  return nil if source[0...2] == '[%'

  buffer = ''
  while true
    return buffer if source[0...2] == '[%'
    break if source.length < 2
    buffer << source.slice!(0)
  end

  buffer << source.slice!(0, source.length)

  buffer
end

#split_whitespace(text) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/xrt/parser.rb', line 57

def split_whitespace(text)
  prefix, suffix=nil
  text.sub!(/\A(\s+)/) {|matched|
    prefix = matched
    ''
  }
  text.sub!(/(\s+)\Z/) {|matched|
    suffix = matched
    ''
  }
  [prefix, text, suffix].compact.delete_if{|s| s.empty?}
end

#tokensObject



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/xrt/parser.rb', line 40

def tokens
  reading = @source.dup
  result = []

  while reading.length > 0
    if got = read_directive(reading)
      result << got
    elsif got = read_text(reading)
      result.concat(split_whitespace(got))
    else
      raise "failed to parse #{@source}"
    end
  end

  result
end