Module

parser.expressions

Expression parsing for Kida parser.

Provides mixin for parsing expressions (ternary, binary, unary, primary, etc.).

Uses inline TYPE_CHECKING declarations for host attributes and cross-mixin dependencies. See: plan/rfc-mixin-protocol-typing.md

Classes

ExpressionParsingMixin 23
Mixin for parsing expressions. Host attributes accessed via inline TYPE_CHECKING declarations. See…

Mixin for parsing expressions.

Host attributes accessed via inline TYPE_CHECKING declarations. See: plan/rfc-mixin-protocol-typing.md

Methods

Internal Methods 23
_parse_expression 0 Expr
Parse expression with ternary and null coalescing. Filters are handled at high…
def _parse_expression(self) -> Expr

Parse expression with ternary and null coalescing.

Filters are handled at higher precedence (in _parse_unary_postfix). Null coalescing (??) has lowest precedence (below or).

Returns
Expr
_parse_null_coalesce 0 Expr
Parse null coalescing: a ?? b. Returns b if a is None/undefined, otherwise a. …
def _parse_null_coalesce(self) -> Expr

Parse null coalescing: a ?? b.

Returns b if a is None/undefined, otherwise a. Right-associative: a ?? b ?? c = a ?? (b ?? c) Part of RFC: kida-modern-syntax-features.

Returns
Expr
_parse_ternary 0 Expr
Parse ternary conditional: a if b else c Jinja2 also supports short form: a if…
def _parse_ternary(self) -> Expr

Parse ternary conditional: a if b else c

Jinja2 also supports short form: a if b (defaults to '' if false)

The condition can include filters because filters have higher precedence than comparisons: x if y | length > 0 else z

Returns
Expr
_parse_null_coalesce_no_ternary 0 Expr
Parse null coalescing without ternary support. Used in for loops where we need…
def _parse_null_coalesce_no_ternary(self) -> Expr

Parse null coalescing without ternary support.

Used in for loops where we need ?? but not ternary (to preserve inline if): {% for x in items ?? [] %} ← works {% for x in items if x.visible %} ← still works

Part of RFC: kida-modern-syntax-features.

Returns
Expr
_parse_or 0 Expr
Parse 'or' expression.
def _parse_or(self) -> Expr
Returns
Expr
_parse_and 0 Expr
Parse 'and' expression.
def _parse_and(self) -> Expr
Returns
Expr
_parse_not 0 Expr
Parse 'not' expression.
def _parse_not(self) -> Expr
Returns
Expr
_parse_comparison 0 Expr
Parse comparison expression.
def _parse_comparison(self) -> Expr
Returns
Expr
_can_start_test_arg 0 bool
Check if current token can start a test argument without parens. Used for: is …
def _can_start_test_arg(self) -> bool

Check if current token can start a test argument without parens.

Used for: is sameas False, is sameas None Only allow simple values to avoid ambiguity with following expressions.

Returns
bool
_parse_addition 0 Expr
Parse addition/subtraction/concatenation. The ~ operator is string concatenati…
def _parse_addition(self) -> Expr

Parse addition/subtraction/concatenation.

The ~ operator is string concatenation in Jinja.

Returns
Expr
_parse_multiplication_with_filters 0 Expr
Parse multiplication/division with filter chain. Filters are applied after mul…
def _parse_multiplication_with_filters(self) -> Expr

Parse multiplication/division with filter chain.

Filters are applied after multiplication but before addition:

a + b | filter parses as a + (b | filter) a * b | filter parses as (a * b) | filter -42 | abs parses as (-42) | abs → 42

Returns
Expr
_parse_multiplication 0 Expr
Parse multiplication/division.
def _parse_multiplication(self) -> Expr
Returns
Expr
_parse_unary 0 Expr
Parse unary operators. Unary operators bind tighter than filters: -42|abs par…
def _parse_unary(self) -> Expr

Parse unary operators.

Unary operators bind tighter than filters:

-42|abs parses as (-42)|abs → 42

Returns
Expr
_parse_power 0 Expr
Parse power operator.
def _parse_power(self) -> Expr
Returns
Expr
_parse_primary_postfix 0 Expr
Parse primary expressions with postfix operators (., [], (), ?., ?[). Does NOT…
def _parse_primary_postfix(self) -> Expr

Parse primary expressions with postfix operators (., [], (), ?., ?[).

Does NOT include filter operator (|) - filters are parsed at a lower precedence level in _parse_filter_chain.

Supports optional chaining: ?. and ?[ (RFC: kida-modern-syntax-features).

Returns
Expr
_parse_range 1 Range
Parse range literal after seeing start value. Syntax: 1..10 → inclusive…
def _parse_range(self, start: Expr) -> Range

Parse range literal after seeing start value.

Syntax:

1..10    → inclusive range [1, 10]
1...11   → exclusive range [1, 11) (like Python range)
1..10 by 2  → range with step

Part of RFC: kida-modern-syntax-features.

Parameters
Name Type Description
start
Returns
Range
_parse_filter_chain 1 Expr
Parse filter chain: expr | filter1 | filter2(arg). Also handles pipeline opera…
def _parse_filter_chain(self, expr: Expr) -> Expr

Parse filter chain: expr | filter1 | filter2(arg).

Also handles pipeline operator: expr |> filter1 |> filter2(arg).

Design: Mixing | and |> in the same expression is not allowed. The first operator encountered determines the style for the expression.

Filters are parsed after unary operators:

-42|abs parses as (-42)|abs → 42

Parameters
Name Type Description
expr
Returns
Expr
_parse_pipeline 1 Expr
Parse pipeline chain: expr |> filter1 |> filter2(arg). Pipelines are left-asso…
def _parse_pipeline(self, expr: Expr) -> Expr

Parse pipeline chain: expr |> filter1 |> filter2(arg).

Pipelines are left-associative: a |> b |> c == (a |> b) |> c

Each step is a filter application. The pipeline collects all steps into a single Pipeline node for potential optimization.

Design: Mixing | and |> is not allowed. Error on | after |>.

Parameters
Name Type Description
expr
Returns
Expr
_parse_subscript 0 Expr
Parse subscript: key or slice [start:stop:step].
def _parse_subscript(self) -> Expr
Returns
Expr
_parse_primary 0 Expr
Parse primary expression.
def _parse_primary(self) -> Expr
Returns
Expr
_parse_binary 1 Expr
Generic binary expression parser.
def _parse_binary(self, operand_parser: Callable[[], Expr], *op_types: TokenType) -> Expr
Parameters
Name Type Description
operand_parser
Returns
Expr
_parse_call_args 0 tuple[list[Expr], dict[s…
Parse function call arguments.
def _parse_call_args(self) -> tuple[list[Expr], dict[str, Expr]]
Returns
tuple[list[Expr], dict[str, Expr]]
_token_to_op 1 str
Map token type to operator string.
def _token_to_op(self, token_type: TokenType) -> str
Parameters
Name Type Description
token_type
Returns
str