mirror of
https://github.com/Shopify/liquid.git
synced 2026-09-12 23:40:45 -07:00
Remove the Token class from the lexer in favour of less smart but faster arrays
This commit is contained in:
+10
-40
@@ -1,30 +1,4 @@
|
||||
module Liquid
|
||||
class Token
|
||||
attr_accessor :type, :contents
|
||||
def initialize(*args)
|
||||
@type, @contents = args
|
||||
end
|
||||
|
||||
def self.[](*args)
|
||||
Token.new(*args)
|
||||
end
|
||||
|
||||
def inspect
|
||||
out = "<#{@type}"
|
||||
out << ": \'#{@contents}\'" if contents
|
||||
out << '>'
|
||||
end
|
||||
|
||||
def to_s
|
||||
self.inspect
|
||||
end
|
||||
|
||||
def ==(other)
|
||||
return unless other && other.respond_to?(:type) && other.respond_to?(:contents)
|
||||
@type == other.type && @contents == other.contents
|
||||
end
|
||||
end
|
||||
|
||||
class Lexer
|
||||
SPECIALS = {
|
||||
'|' => :pipe,
|
||||
@@ -51,7 +25,7 @@ module Liquid
|
||||
loop do
|
||||
tok = next_token
|
||||
unless tok
|
||||
@output << Token[:end_of_string]
|
||||
@output << [:end_of_string]
|
||||
return @output
|
||||
end
|
||||
@output << tok
|
||||
@@ -59,16 +33,16 @@ module Liquid
|
||||
end
|
||||
|
||||
def next_token
|
||||
consume_whitespace
|
||||
@ss.skip(/\s*/)
|
||||
return if @ss.eos?
|
||||
|
||||
|
||||
case
|
||||
when t = @ss.scan(COMPARISON_OPERATOR) then Token[:comparison, t]
|
||||
when t = @ss.scan(SINGLE_STRING_LITERAL) then Token[:string, t]
|
||||
when t = @ss.scan(DOUBLE_STRING_LITERAL) then Token[:string, t]
|
||||
when t = @ss.scan(FLOAT_LITERAL) then Token[:float, t]
|
||||
when t = @ss.scan(INTEGER_LITERAL) then Token[:integer, t]
|
||||
when t = @ss.scan(IDENTIFIER) then Token[:id, t]
|
||||
when t = @ss.scan(COMPARISON_OPERATOR) then [:comparison, t]
|
||||
when t = @ss.scan(SINGLE_STRING_LITERAL) then [:string, t]
|
||||
when t = @ss.scan(DOUBLE_STRING_LITERAL) then [:string, t]
|
||||
when t = @ss.scan(FLOAT_LITERAL) then [:float, t]
|
||||
when t = @ss.scan(INTEGER_LITERAL) then [:integer, t]
|
||||
when t = @ss.scan(IDENTIFIER) then [:id, t]
|
||||
else
|
||||
lex_specials
|
||||
end
|
||||
@@ -78,14 +52,10 @@ module Liquid
|
||||
def lex_specials
|
||||
c = @ss.getch
|
||||
if s = SPECIALS[c]
|
||||
return Token[s,c]
|
||||
return [s,c]
|
||||
end
|
||||
|
||||
raise SyntaxError, "Unexpected character #{c}."
|
||||
end
|
||||
|
||||
def consume_whitespace
|
||||
@ss.skip(/\s*/)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
+11
-11
@@ -14,11 +14,11 @@ module Liquid
|
||||
|
||||
def consume(type = nil)
|
||||
token = @tokens[@p]
|
||||
if type && token.type != type
|
||||
if type && token[0] != type
|
||||
raise SyntaxError, "Expected #{type} but found #{@tokens[@p]}"
|
||||
end
|
||||
@p += 1
|
||||
token.contents
|
||||
token[1]
|
||||
end
|
||||
|
||||
# Only consumes the token if it matches the type
|
||||
@@ -26,35 +26,35 @@ module Liquid
|
||||
# or false otherwise.
|
||||
def consume?(type)
|
||||
token = @tokens[@p]
|
||||
return false unless token && token.type == type
|
||||
return false unless token && token[0] == type
|
||||
@p += 1
|
||||
token.contents
|
||||
token[1]
|
||||
end
|
||||
|
||||
# Like consume? Except for an :id token of a certain name
|
||||
def id?(str)
|
||||
token = @tokens[@p]
|
||||
return false unless token && token.type == :id
|
||||
return false unless token.contents == str
|
||||
return false unless token && token[0] == :id
|
||||
return false unless token[1] == str
|
||||
@p += 1
|
||||
token.contents
|
||||
token[1]
|
||||
end
|
||||
|
||||
def look(type, ahead = 0)
|
||||
tok = @tokens[@p + ahead]
|
||||
return false unless tok
|
||||
tok.type == type
|
||||
tok[0] == type
|
||||
end
|
||||
|
||||
# === General Liquid parsing functions ===
|
||||
|
||||
def expression
|
||||
token = @tokens[@p]
|
||||
if token.type == :id
|
||||
if token[0] == :id
|
||||
variable_signature
|
||||
elsif [:string, :integer, :float].include? token.type
|
||||
elsif [:string, :integer, :float].include? token[0]
|
||||
consume
|
||||
token.contents
|
||||
token[1]
|
||||
else
|
||||
raise SyntaxError, "#{token} is not a valid expression."
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user