Prepare logical for grouping

This commit is contained in:
Charles-P. Clermont
2026-01-27 10:07:35 -05:00
parent 7f414e5fa6
commit f9b5313020
3 changed files with 18 additions and 16 deletions
+14 -8
View File
@@ -6,22 +6,24 @@ module Liquid
CLOSE_SQUARE = [:close_square, "]"].freeze CLOSE_SQUARE = [:close_square, "]"].freeze
COLON = [:colon, ":"].freeze COLON = [:colon, ":"].freeze
COMMA = [:comma, ","].freeze COMMA = [:comma, ","].freeze
COMPARISION_NOT_EQUAL = [:equality, "!="].freeze
COMPARISON_CONTAINS = [:comparison, "contains"].freeze COMPARISON_CONTAINS = [:comparison, "contains"].freeze
COMPARISON_EQUAL = [:equality, "=="].freeze
COMPARISON_GREATER_THAN = [:comparison, ">"].freeze COMPARISON_GREATER_THAN = [:comparison, ">"].freeze
COMPARISON_GREATER_THAN_OR_EQUAL = [:comparison, ">="].freeze COMPARISON_GREATER_THAN_OR_EQUAL = [:comparison, ">="].freeze
COMPARISON_LESS_THAN = [:comparison, "<"].freeze COMPARISON_LESS_THAN = [:comparison, "<"].freeze
COMPARISON_LESS_THAN_OR_EQUAL = [:comparison, "<="].freeze COMPARISON_LESS_THAN_OR_EQUAL = [:comparison, "<="].freeze
COMPARISON_NOT_EQUAL_ALT = [:equality, "<>"].freeze EQUALITY_EQUAL_EQUAL = [:equality, "=="].freeze
EQUALITY_NOT_EQUAL = [:equality, "!="].freeze
EQUALITY_NOT_EQUAL_ALT = [:equality, "<>"].freeze
DASH = [:dash, "-"].freeze DASH = [:dash, "-"].freeze
DOT = [:dot, "."].freeze DOT = [:dot, "."].freeze
DOTDOT = [:dotdot, ".."].freeze DOTDOT = [:dotdot, ".."].freeze
DOT_ORD = ".".ord DOT_ORD = ".".ord
DOUBLE_STRING_LITERAL = /"[^\"]*"/ DOUBLE_STRING_LITERAL = /"[^\"]*"/
EOS = [:end_of_string].freeze EOS = [:end_of_string].freeze
IDENTIFIER = /[a-zA-Z_][\w-]*\??/ IDENTIFIER = /[a-zA-Z_][\w-]*\??/
NUMBER_LITERAL = /-?\d+(\.\d+)?/ LOGICAL_AND = [:logical, 'and'].freeze
LOGICAL_OR = [:logical, 'or'].freeze
NUMBER_LITERAL = /-?\d+(\.\d+)?/
OPEN_ROUND = [:open_round, "("].freeze OPEN_ROUND = [:open_round, "("].freeze
OPEN_SQUARE = [:open_square, "["].freeze OPEN_SQUARE = [:open_square, "["].freeze
PIPE = [:pipe, "|"].freeze PIPE = [:pipe, "|"].freeze
@@ -38,11 +40,11 @@ module Liquid
TWO_CHARS_COMPARISON_JUMP_TABLE = [].tap do |table| TWO_CHARS_COMPARISON_JUMP_TABLE = [].tap do |table|
table["=".ord] = [].tap do |sub_table| table["=".ord] = [].tap do |sub_table|
sub_table["=".ord] = COMPARISON_EQUAL sub_table["=".ord] = EQUALITY_EQUAL_EQUAL
sub_table.freeze sub_table.freeze
end end
table["!".ord] = [].tap do |sub_table| table["!".ord] = [].tap do |sub_table|
sub_table["=".ord] = COMPARISION_NOT_EQUAL sub_table["=".ord] = EQUALITY_NOT_EQUAL
sub_table.freeze sub_table.freeze
end end
table.freeze table.freeze
@@ -51,7 +53,7 @@ module Liquid
COMPARISON_JUMP_TABLE = [].tap do |table| COMPARISON_JUMP_TABLE = [].tap do |table|
table["<".ord] = [].tap do |sub_table| table["<".ord] = [].tap do |sub_table|
sub_table["=".ord] = COMPARISON_LESS_THAN_OR_EQUAL sub_table["=".ord] = COMPARISON_LESS_THAN_OR_EQUAL
sub_table[">".ord] = COMPARISON_NOT_EQUAL_ALT sub_table[">".ord] = EQUALITY_NOT_EQUAL_ALT
sub_table.freeze sub_table.freeze
end end
table[">".ord] = [].tap do |sub_table| table[">".ord] = [].tap do |sub_table|
@@ -151,6 +153,10 @@ module Liquid
# Special case for "contains" # Special case for "contains"
output << if type == :id && t == "contains" && output.last&.first != :dot output << if type == :id && t == "contains" && output.last&.first != :dot
COMPARISON_CONTAINS COMPARISON_CONTAINS
elsif type == :id && t == "and" && output.last&.first != :dot
LOGICAL_AND
elsif type == :id && t == "or" && output.last&.first != :dot
LOGICAL_OR
else else
[type, t] [type, t]
end end
+3 -7
View File
@@ -62,14 +62,10 @@ module Liquid
# #
# `a == b and b or c` is evaluated like (a and (b or c)) # `a == b and b or c` is evaluated like (a and (b or c))
def logical def logical
operator = nil
expr = equality expr = equality
while (operator = id?('and') || id?('or')) expr = BinaryExpression.new(expr, operator, equality) if (operator = consume?(:logical))
if expr.is_a?(BinaryExpression) && (expr.operator == 'and' || expr.operator == 'or') expr.right_node = BinaryExpression.new(expr.right_node, operator, equality) while (operator = consume?(:logical))
expr.right_node = BinaryExpression.new(expr.right_node, operator, equality)
else
expr = BinaryExpression.new(expr, operator, equality)
end
end
expr expr
end end
+1 -1
View File
@@ -104,7 +104,7 @@ module Liquid
block.attach(body) block.attach(body)
@blocks << block @blocks << block
break unless parser.id?('or') || parser.consume?(:comma) break unless parser.consume?(:logical) == 'or' || parser.consume?(:comma)
end end
parser.consume(:end_of_string) parser.consume(:end_of_string)