# expressions

URL: /kida/api/parser/expressions/
Section: parser
Description: 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

---

> For a complete page index, fetch /kida/llms.txt.

Open LLM text
(/kida/api/parser/expressions/index.txt)

Share with AI

Ask Claude
(https://claude.ai/new?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fkida%2Fapi%2Fparser%2Fexpressions%2Findex.txt)

Ask ChatGPT
(https://chatgpt.com/?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fkida%2Fapi%2Fparser%2Fexpressions%2Findex.txt)

Ask Gemini
(https://gemini.google.com/app?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fkida%2Fapi%2Fparser%2Fexpressions%2Findex.txt)

Ask Copilot
(https://copilot.microsoft.com/?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fkida%2Fapi%2Fparser%2Fexpressions%2Findex.txt)

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

1Class

## Classes

`ExpressionParsingMixin`

26

▼

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
26

▼

`_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

Also handles {{ await expr }} — RFC: rfc-async-rendering.

##### Returns

`Expr`

`_parse_power`

0

`Expr`

▼

Parse power operator.

`def _parse_power(self) -> Expr`

##### Returns

`Expr`

`_parse_list_comprehension`

2

`ListComp`

▼

Parse list comprehension after '[expr for ...'.

Called when _parse_primary() h…

`def _parse_list_comprehension(self, start_token: Token, elt: Expr) -> ListComp`

Parse list comprehension after '[expr for ...'.

Called when _parse_primary() has consumed '[' and the element expression,
and the current token is NAME 'for'.

##### Parameters

Name
Type
Description

`start_token`
`—`

`elt`
`—`

##### Returns

`ListComp`

`_contains_await`

1

`bool`

▼

Check if an expression tree contains an Await node.

staticmethod

`def _contains_await(node: object) -> bool`

##### Parameters

Name
Type
Description

`node`
`—`

##### Returns

`bool`

`_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).
Also handles safe pipeline: expr ?|> filter1 ?|> filter2(arg).
Also handles optional filter: expr ?| filter(args).

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_safe_pipeline`

1

`Expr`

▼

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

None-propagating: if e…

`def _parse_safe_pipeline(self, expr: Expr) -> Expr`

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

None-propagating: if expr is None, the entire pipeline returns None
without calling any filters. Each step checks for None before applying.

##### 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`

2

`Expr`

▼

Generic binary expression parser.

`def _parse_binary(self, operand_parser: Callable[[], Expr], *op_types: TokenType) -> Expr`

##### Parameters

Name
Type
Description

`operand_parser`
`—`

`*op_types`
`—`

##### 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`
