Problem
The grammar defines all binary operators in a flat BINARY_OP token without precedence hierarchy, causing incorrect parsing of expressions mixing different operators.
Impact: Expressions with multiple operators parse incorrectly, producing wrong evaluation order.
Examples
Example 1: Logical AND with Equality
var.env == "prod" && var.debug
- Current parse:
var.env == (prod && debug)
- Expected parse:
(var.env == prod) && debug
Example 2: Ternary with Logical AND (from #32)
- Current parse:
true && (true ? 1 : 0)
- Expected parse:
(true && true) ? 1 : 0
Example 3: Mixed Arithmetic and Comparison
var.a + var.b * var.c > 10
- Current parse:
var.a + (var.b * (var.c > 10))
- Expected parse:
(var.a + (var.b * var.c)) > 10
Root Cause
The grammar uses a single BINARY_OP token for all operators:
?operation : unary_op | binary_op
binary_op : expression binary_term new_line_or_comment?
binary_term : binary_operator new_line_or_comment? expression
!binary_operator : BINARY_OP
BINARY_OP : DOUBLE_EQ | NEQ | LT | GT | LEQ | GEQ | MINUS | ASTERISK | SLASH | PERCENT | DOUBLE_AMP | DOUBLE_PIPE | PLUS
This provides no precedence ordering between operators.
Expected Precedence Hierarchy
Standard operator precedence (matching C, Java, JavaScript, and HCL2 specification):
- Unary:
!, - (highest precedence)
- Multiplicative:
*, /, %
- Additive:
+, -
- Relational:
<, >, <=, >=
- Equality:
==, !=
- Logical AND:
&&
- Logical OR:
||
- Ternary:
? : (lowest precedence)
All binary operators should be left-associative except ternary, which is right-associative.
Solution Approach
Implement a precedence ladder in the grammar using separate rules for each precedence level. Each level should use left-recursive patterns for left-associativity.
Related Issues
This issue was previously reported in #32 (closed in 2024) but the bug still exists in v7.3.1. Issues #246 and #247 may be related symptoms of this precedence problem.
Additional Information
I have implemented and tested a complete fix for this issue. The fix uses rule aliases to maintain transformer compatibility. If useful, I can submit a PR with the grammar changes and comprehensive test suite.
Version: python-hcl2 v7.3.1
Impact: High - affects correctness of all expressions with mixed operators
Problem
The grammar defines all binary operators in a flat BINARY_OP token without precedence hierarchy, causing incorrect parsing of expressions mixing different operators.
Impact: Expressions with multiple operators parse incorrectly, producing wrong evaluation order.
Examples
Example 1: Logical AND with Equality
var.env == (prod && debug)(var.env == prod) && debugExample 2: Ternary with Logical AND (from #32)
true && (true ? 1 : 0)(true && true) ? 1 : 0Example 3: Mixed Arithmetic and Comparison
var.a + (var.b * (var.c > 10))(var.a + (var.b * var.c)) > 10Root Cause
The grammar uses a single BINARY_OP token for all operators:
This provides no precedence ordering between operators.
Expected Precedence Hierarchy
Standard operator precedence (matching C, Java, JavaScript, and HCL2 specification):
!,-(highest precedence)*,/,%+,-<,>,<=,>===,!=&&||? :(lowest precedence)All binary operators should be left-associative except ternary, which is right-associative.
Solution Approach
Implement a precedence ladder in the grammar using separate rules for each precedence level. Each level should use left-recursive patterns for left-associativity.
Related Issues
This issue was previously reported in #32 (closed in 2024) but the bug still exists in v7.3.1. Issues #246 and #247 may be related symptoms of this precedence problem.
Additional Information
I have implemented and tested a complete fix for this issue. The fix uses rule aliases to maintain transformer compatibility. If useful, I can submit a PR with the grammar changes and comprehensive test suite.
Version: python-hcl2 v7.3.1
Impact: High - affects correctness of all expressions with mixed operators