Skip to content

Commit 26cb294

Browse files
charlespwdclaude
andcommitted
fix(parser): implement RTL associativity for boolean expressions
- Use right-recursive descent for proper RTL precedence - Add bin/liquid-spec-all-adapters for CI workflow - Update CI to use dedicated script Fixes 128 precedence test failures from original implementation. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 3b13ee0 commit 26cb294

File tree

3 files changed

+16
-15
lines changed

3 files changed

+16
-15
lines changed

.github/workflows/liquid.yml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,7 @@ jobs:
5656
bundler-cache: true
5757
bundler: latest
5858
- name: Run liquid-spec for all adapters
59-
run: |
60-
for adapter in spec/*.rb; do
61-
echo "=== Running $adapter ==="
62-
bundle exec liquid-spec run "$adapter" --no-max-failures
63-
done
59+
run: bin/liquid-spec-all-adapters
6460

6561
memory_profile:
6662
runs-on: ubuntu-latest

bin/liquid-spec-all-adapters

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/usr/bin/env bash
2+
for adapter in spec/*.rb; do
3+
echo "=== Running $adapter ==="
4+
bundle exec liquid-spec run "$adapter" --no-max-failures
5+
done

lib/liquid/parser.rb

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,18 +59,18 @@ def expression
5959
logical
6060
end
6161

62-
# Logical relations in Liquid, unlike other languages, are right-to-left
63-
# associative. This creates a right-leaning tree and is why the method
64-
# looks a bit more complicated
65-
#
62+
# Logical relations use right-to-left associativity.
6663
# `a and b or c` is evaluated like (a and (b or c))
67-
# logical := equality (("and" | "or") equality)*
64+
# This enables short-circuit: if `a` is false, entire expression short-circuits.
65+
# logical := equality (("and" | "or") logical)?
6866
def logical
69-
operator = nil
70-
expr = equality
71-
expr = BinaryExpression.new(expr, operator, equality) if (operator = consume?(:logical))
72-
expr.right_node = BinaryExpression.new(expr.right_node, operator, equality) while (operator = consume?(:logical))
73-
expr
67+
left = equality
68+
if (operator = consume?(:logical))
69+
right = logical # recursive call builds proper RTL tree
70+
BinaryExpression.new(left, operator, right)
71+
else
72+
left
73+
end
7474
end
7575

7676
# equality := comparison (("==" | "!=" | "<>") comparison)*

0 commit comments

Comments
 (0)