Skip to content

Commit

Permalink
fix lexer parsing comparison without whitespaces
Browse files Browse the repository at this point in the history
  • Loading branch information
ggmichaelgo committed Oct 28, 2024
1 parent b419648 commit d94293a
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 2 deletions.
20 changes: 18 additions & 2 deletions lib/liquid/lexer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,12 @@ class Lexer2
SINGLE_STRING_LITERAL = /'[^\']*'/
WHITESPACE_OR_NOTHING = /\s*/

COMPARISON_JUMP_TABLE = [].tap do |table|
SINGLE_COMPARISON_TOKENS = [].tap do |table|
table["<".ord] = COMPARISON_LESS_THAN
table[">".ord] = COMPARISON_GREATER_THAN
end

TWO_CHARS_COMPARISON_JUMP_TABLE = [].tap do |table|
table["=".ord] = [].tap do |sub_table|
sub_table["=".ord] = COMPARISON_EQUAL
sub_table.freeze
Expand All @@ -99,6 +104,9 @@ class Lexer2
sub_table["=".ord] = COMPARISION_NOT_EQUAL
sub_table.freeze
end
end

COMPARISON_JUMP_TABLE = [].tap do |table|
table["<".ord] = [].tap do |sub_table|
sub_table["=".ord] = COMPARISON_LESS_THAN_OR_EQUAL
sub_table[">".ord] = COMPARISON_NOT_EQUAL_ALT
Expand Down Expand Up @@ -182,14 +190,22 @@ def tokenize
else
@output << special
end
elsif (sub_table = COMPARISON_JUMP_TABLE[peeked])
elsif (sub_table = TWO_CHARS_COMPARISON_JUMP_TABLE[peeked])
@ss.scan_byte
if (found = sub_table[@ss.peek_byte])
@output << found
@ss.scan_byte
else
raise SyntaxError, "Unexpected character #{peeked.chr}"
end
elsif (sub_table = COMPARISON_JUMP_TABLE[peeked])
@ss.scan_byte
if (found = sub_table[@ss.peek_byte])
@output << found
@ss.scan_byte
else
@output << SINGLE_COMPARISON_TOKENS[peeked]
end
else
type, pattern = NEXT_MATCHER_JUMP_TABLE[peeked]

Expand Down
24 changes: 24 additions & 0 deletions test/unit/lexer_unit_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,30 @@ def test_comparison
assert_equal([[:comparison, '=='], [:comparison, '<>'], [:comparison, 'contains'], [:end_of_string]], tokens)
end

def test_comparison_without_whitespace
tokens = Lexer.new('1>0').tokenize
assert_equal([[:number, '1'], [:comparison, '>'], [:number, '0'], [:end_of_string]], tokens)
end

def test_comparison_with_negative_number
tokens = Lexer.new('1>-1').tokenize
assert_equal([[:number, '1'], [:comparison, '>'], [:number, '-1'], [:end_of_string]], tokens)
end

def test_raise_for_invalid_comparison
assert_raises(SyntaxError) do
Lexer.new('1>!1').tokenize
end

assert_raises(SyntaxError) do
Lexer.new('1=<1').tokenize
end

assert_raises(SyntaxError) do
Lexer.new('1!!1').tokenize
end
end

def test_specials
tokens = Lexer.new('| .:').tokenize
assert_equal([[:pipe, '|'], [:dot, '.'], [:colon, ':'], [:end_of_string]], tokens)
Expand Down

0 comments on commit d94293a

Please sign in to comment.