Class: H2o::Parser

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

Constant Summary collapse

ParseRegex =
/\G
  (.*?)(?:
    #{Regexp.escape(BLOCK_START)}    (.*?)
    #{Regexp.escape(BLOCK_END)}          |
    #{Regexp.escape(VAR_START)}      (.*?)
    #{Regexp.escape(VAR_END)}            |
    #{Regexp.escape(COMMENT_START)}  (.*?)
    #{Regexp.escape(COMMENT_END)}
  )(?:\r?\n)?
/xm

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source, filename, env = {}) ⇒ Parser

Returns a new instance of Parser.



17
18
19
20
21
22
23
24
# File 'lib/h2o/parser.rb', line 17

def initialize (source, filename, env = {})
  @env = env
  @storage = {}
  @source = source
  @filename = filename
  @tokenstream = tokenize
  @first = true
end

Instance Attribute Details

#envObject (readonly)

Returns the value of attribute env.



3
4
5
# File 'lib/h2o/parser.rb', line 3

def env
  @env
end

#sourceObject (readonly)

Returns the value of attribute source.



3
4
5
# File 'lib/h2o/parser.rb', line 3

def source
  @source
end

#storageObject

Returns the value of attribute storage.



4
5
6
# File 'lib/h2o/parser.rb', line 4

def storage
  @storage
end

#tokenObject (readonly)

Returns the value of attribute token.



3
4
5
# File 'lib/h2o/parser.rb', line 3

def token
  @token
end

Class Method Details

.parse_arguments(argument) ⇒ Object



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/h2o/parser.rb', line 109

def self.parse_arguments (argument)
  result = current_buffer = []
  filter_buffer = []
  data = nil
  ArgumentLexer.lex(argument).each do |token|
    token, data = token
    case token
      when :filter_start
        current_buffer = filter_buffer.clear
      when :filter_end
        result << filter_buffer.dup unless filter_buffer.empty?
        current_buffer = result
      when :nil
        current_buffer << nil
      when :boolean
        current_buffer << (data == 'true'? true : false)
      when :name
        current_buffer << data.to_sym
      when :number
        current_buffer << (data.include?('.') ? data.to_f : data.to_i)
      when :string
        data.match(STRING_RE)
        current_buffer << ($1 || $2)
      when :named_argument
        current_buffer << {} unless current_buffer.last.is_a?(Hash)
        
        named_args = current_buffer.last
        name, value = data.split(':', 2).map{|m| m.strip}
        named_args[name.to_sym] = parse_arguments(value).first
      when :operator
        # replace exclaimation mark '!' into not
        data = 'not' if data == '!'
        current_buffer << {:operator => data.to_sym}
    end
  end
  result
end

Instance Method Details

#first?Boolean

Returns:

  • (Boolean)


66
67
68
# File 'lib/h2o/parser.rb', line 66

def first?
  @first
end

#parse(*untils) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/h2o/parser.rb', line 70

def parse(*untils)
  nodelist = Nodelist.new(self)
  
  while @token = @tokenstream.pop
    token, content = @token
    case token
      when :text
        nodelist << TextNode.new(content) unless content.empty?
      when :variable
        names = []
        filters = []
        Parser.parse_arguments(content).each do |argument|
          if argument.is_a? Array
            filters << argument
          else
            names << argument
          end
        end
        nodelist << VariableNode.new(names.first, filters)
      when :block
        name, args = content.split(/\s+/, 2)
        name = name.to_sym
        
        if untils.include?(name)
          return nodelist
        end
        
        tag = Tags[name]
        raise "Unknow tag #{name}" if tag.nil?

        nodelist << tag.new(self, args) if tag
      when :comment
        nodelist << CommentNode.new(content)
    end
    @first = false
  end
  nodelist
end

#pretty_print(pp) ⇒ Object



147
148
149
# File 'lib/h2o/parser.rb', line 147

def pretty_print pp
  nil
end

#tokenizeObject



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/h2o/parser.rb', line 26

def tokenize
  result = []
  lstrip = false
  rstrip = false

  @source.scan(ParseRegex).each do |match|
    result << [:text, match[0]] if match[0] and !match[0].empty?
    # strip next left white spaces
    result.last[1].lstrip! if lstrip

    if data = match[1]
      data = data.strip
      
      # strip right whitespaces on previous text node
      if rstrip = data[0].chr == "-"
        data.slice!(0)
        result.last[1].rstrip! if rstrip
      end
      
      if lstrip = data[data.length-1].chr == "-"
        data.chop!
      end

      result << [:block, data.strip]
    elsif data = match[2]
      result << [:variable, data.strip]
    elsif data = match[3]
      result << [:comment, data.strip]
    end
  end
  
  rest = $~.nil? ? @source : @source[$~.end(0) .. -1]
  unless rest.empty?
    result << [:text, rest]
    # strip next left white spaces
    result.last[1].lstrip! if lstrip
  end
  result.reverse
end