Sha256: fb9b12797807e6758e850b58f31c9c545d6028a06b241142568c38c56c42fc0c

Contents?: true

Size: 1.26 KB

Versions: 1

Compression:

Stored size: 1.26 KB

Contents

require "strscan"
module Liquid
  class Lexer
    SPECIALS = {
      '|' => :pipe,
      '.' => :dot,
      ':' => :colon,
      ',' => :comma,
      '[' => :open_square,
      ']' => :close_square,
      '(' => :open_round,
      ')' => :close_round
    }
    IDENTIFIER = /[\w\-?!]+/
    SINGLE_STRING_LITERAL = /'[^\']*'/
    DOUBLE_STRING_LITERAL = /"[^\"]*"/
    NUMBER_LITERAL = /-?\d+(\.\d+)?/
    DOTDOT = /\.\./
    COMPARISON_OPERATOR = /==|!=|<>|<=?|>=?|contains/

    def initialize(input)
      @ss = StringScanner.new(input.rstrip)
    end

    def tokenize
      @output = []

      while !@ss.eos?
        @ss.skip(/\s*/)
        tok = case
        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(NUMBER_LITERAL) then [:number, t]
        when t = @ss.scan(IDENTIFIER) then [:id, t]
        when t = @ss.scan(DOTDOT) then [:dotdot, t]
        else
          c = @ss.getch
          if s = SPECIALS[c]
            [s,c]
          else
            raise SyntaxError, "Unexpected character #{c}"
          end
        end
        @output << tok
      end

      @output << [:end_of_string]
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
locomotivecms-liquid-2.6.0 lib/liquid/lexer.rb