# expressions URL: /api/parser/expressions/ Section: parser -------------------------------------------------------------------------------- expressions - Kida window.BENGAL_THEME_DEFAULTS = { appearance: 'light', palette: 'brown-bengal' }; window.Bengal = window.Bengal || {}; window.Bengal.enhanceBaseUrl = '/kida/assets/js/enhancements'; window.Bengal.watchDom = true; window.Bengal.debug = false; window.Bengal.enhanceUrls = { 'toc': '/kida/assets/js/enhancements/toc.632a9783.js', 'docs-nav': '/kida/assets/js/enhancements/docs-nav.57e4b129.js', 'tabs': '/kida/assets/js/enhancements/tabs.aac9e817.js', 'lightbox': '/kida/assets/js/enhancements/lightbox.1ca22aa1.js', 'interactive': '/kida/assets/js/enhancements/interactive.fc077855.js', 'mobile-nav': '/kida/assets/js/enhancements/mobile-nav.d991657f.js', 'action-bar': '/kida/assets/js/enhancements/action-bar.d62417f4.js', 'copy-link': '/kida/assets/js/enhancements/copy-link.7d9a5c29.js', 'data-table': '/kida/assets/js/enhancements/data-table.1f5bc1eb.js', 'lazy-loaders': '/kida/assets/js/enhancements/lazy-loaders.a5c38245.js', 'holo': '/kida/assets/js/enhancements/holo.ee13c841.js', 'link-previews': '/kida/assets/js/enhancements/link-previews.8d906535.js' }; (function () { try { var defaults = window.BENGAL_THEME_DEFAULTS || { appearance: 'system', palette: '' }; var defaultAppearance = defaults.appearance; if (defaultAppearance === 'system') { defaultAppearance = (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) ? 'dark' : 'light'; } var storedTheme = localStorage.getItem('bengal-theme'); var storedPalette = localStorage.getItem('bengal-palette'); var theme = storedTheme ? (storedTheme === 'system' ? defaultAppearance : storedTheme) : defaultAppearance; var palette = storedPalette ?? defaults.palette; document.documentElement.setAttribute('data-theme', theme); if (palette) { document.documentElement.setAttribute('data-palette', palette); } } catch (e) { document.documentElement.setAttribute('data-theme', 'light'); } })(); { "prerender": [ { "where": { "and": [ { "href_matches": "/docs/*" }, { "not": { "selector_matches": "[data-external], [target=_blank], .external" } } ] }, "eagerness": "conservative" } ], "prefetch": [ { "where": { "and": [ { "href_matches": "/*" }, { "not": { "selector_matches": "[data-external], [target=_blank], .external" } } ] }, "eagerness": "conservative" } ] } Skip to main content Magnifying Glass ESC Recent Clear Magnifying Glass No results for "" Start typing to search... ↑↓ Navigate ↵ Open ESC Close Powered by Lunr )彡 DocumentationInfoAboutArrow ClockwiseGet StartedCodeSyntaxTerminalUsageNoteTutorialsStarburstExtendingBookmarkReferenceTroubleshootingReleasesDevGitHubKida API Reference Magnifying Glass Search ⌘K Palette Appearance Chevron Down Mode Monitor System Sun Light Moon Dark Palette Snow Lynx Brown Bengal Silver Bengal Charcoal Bengal Blue Bengal List )彡 Magnifying Glass Search X Close Documentation Caret Down Info About Arrow Clockwise Get Started Code Syntax Terminal Usage Note Tutorials Starburst Extending Bookmark Reference Troubleshooting Releases Dev Caret Down GitHub Kida API Reference Palette Appearance Chevron Down Mode Monitor System Sun Light Moon Dark Palette Snow Lynx Brown Bengal Silver Bengal Charcoal Bengal Blue Bengal Kida API Reference Caret Right Analysis analyzer cache config dependencies landmarks metadata purity roles Caret Right Compiler Caret Right Statements basic control_flow functions special_blocks template_structure variables _protocols coalescing core expressions utils Caret Right Environment core exceptions filters loaders protocols registry tests Caret Right Parser Caret Right Blocks control_flow core functions special_blocks template_structure variables _protocols core errors expressions statements tokens Caret Right Utils html lru_cache workers _types bytecode_cache kida lexer nodes template tstring Kida API ReferenceParser ᗢ Caret Down Link Copy URL External Open LLM text Copy Copy LLM text Share with AI Ask Claude Ask ChatGPT Ask Gemini Ask Copilot 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 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 ← Previous errors Next → parser List © 2026 Kida built in ᓚᘏᗢ { "linkPreviews": { "enabled": true, "hoverDelay": 200, "hideDelay": 150, "showSection": true, "showReadingTime": true, "showWordCount": true, "showDate": true, "showTags": true, "maxTags": 3, "includeSelectors": [".prose"], "excludeSelectors": ["nav", ".toc", ".breadcrumb", ".pagination", ".card", "[class*='-card']", ".tab-nav", "[class*='-widget']", ".child-items", ".content-tiles"], "allowedHosts": [], "allowedSchemes": ["https"], "hostFailureThreshold": 3 } } window.BENGAL_LAZY_ASSETS = { tabulator: '/kida/assets/js/tabulator.min.js', dataTable: '/kida/assets/js/data-table.js', mermaidToolbar: '/kida/assets/js/mermaid-toolbar.9de5abba.js', mermaidTheme: '/kida/assets/js/mermaid-theme.344822c5.js', graphMinimap: '/kida/assets/js/graph-minimap.ff04e939.js', graphContextual: '/kida/assets/js/graph-contextual.355458ba.js' }; window.BENGAL_ICONS = { close: '/kida/assets/icons/close.911d4fe1.svg', enlarge: '/kida/assets/icons/enlarge.652035e5.svg', copy: '/kida/assets/icons/copy.3d56e945.svg', 'download-svg': '/kida/assets/icons/download.04f07e1b.svg', 'download-png': '/kida/assets/icons/image.c34dfd40.svg', 'zoom-in': '/kida/assets/icons/zoom-in.237b4a83.svg', 'zoom-out': '/kida/assets/icons/zoom-out.38857c77.svg', reset: '/kida/assets/icons/reset.d26dba29.svg' }; Arrow Up -------------------------------------------------------------------------------- Metadata: - Word Count: 1442 - Reading Time: 7 minutes