Class: Liquid::Parser

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

Instance Method Summary collapse

Constructor Details

#initialize(input, reject_bare_brackets: false) ⇒ Parser

Returns a new instance of Parser.



5
6
7
8
9
10
# File 'lib/liquid/parser.rb', line 5

def initialize(input, reject_bare_brackets: false)
  ss = input.is_a?(StringScanner) ? input : StringScanner.new(input)
  @tokens = Lexer.tokenize(ss)
  @p      = 0 # pointer to current location
  @reject_bare_brackets = reject_bare_brackets
end

Instance Method Details

#argumentObject



78
79
80
81
82
83
84
85
86
87
# File 'lib/liquid/parser.rb', line 78

def argument
  str = +""
  # might be a keyword argument (identifier: expression)
  if look(:id) && look(:colon, 1)
    str << consume << consume << ' '
  end

  str << expression
  str
end

#consume(type = nil) ⇒ Object



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

def consume(type = nil)
  token = @tokens[@p]
  if type && token[0] != type
    raise SyntaxError, "Expected #{type} but found #{@tokens[@p].first}"
  end
  @p += 1
  token[1]
end

#consume?(type) ⇒ Boolean

Only consumes the token if it matches the type Returns the token's contents if it was consumed or false otherwise.

Returns:

  • (Boolean)


28
29
30
31
32
33
# File 'lib/liquid/parser.rb', line 28

def consume?(type)
  token = @tokens[@p]
  return false unless token && token[0] == type
  @p += 1
  token[1]
end

#expressionObject



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/liquid/parser.rb', line 50

def expression
  token = @tokens[@p]
  case token[0]
  when :id
    str = consume
    str << variable_lookups
  when :open_square
    if @reject_bare_brackets
      raise SyntaxError, "Bare bracket access is not allowed. Use #{Expression::SELF}['...'] instead"
    end
    str = consume.dup
    str << expression
    str << consume(:close_square)
    str << variable_lookups
  when :string, :number
    consume
  when :open_round
    consume
    first = expression
    consume(:dotdot)
    last = expression
    consume(:close_round)
    "(#{first}..#{last})"
  else
    raise SyntaxError, "#{token} is not a valid expression"
  end
end

#id?(str) ⇒ Boolean

Like consume? Except for an :id token of a certain name

Returns:

  • (Boolean)


36
37
38
39
40
41
42
# File 'lib/liquid/parser.rb', line 36

def id?(str)
  token = @tokens[@p]
  return false unless token && token[0] == :id
  return false unless token[1] == str
  @p += 1
  token[1]
end

#jump(point) ⇒ Object



12
13
14
# File 'lib/liquid/parser.rb', line 12

def jump(point)
  @p = point
end

#look(type, ahead = 0) ⇒ Object



44
45
46
47
48
# File 'lib/liquid/parser.rb', line 44

def look(type, ahead = 0)
  tok = @tokens[@p + ahead]
  return false unless tok
  tok[0] == type
end

#variable_lookupsObject



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/liquid/parser.rb', line 89

def variable_lookups
  str = +""
  loop do
    if look(:open_square)
      str << consume
      str << expression
      str << consume(:close_square)
    elsif look(:dot)
      str << consume
      str << consume(:id)
    else
      break
    end
  end
  str
end