Skip to content

Current language reference

The current .yidl route is brace-blocked Lark concept syntax. The old indentation/transducer parser and %% fences belong to a different frontend. yidl-compile invokes that older frontend; use the Python API for this language.

Authoring rules

Surface Syntax/meaning
Module module example.generator labels the source module
Imports import "base.yidl" as base; from "base.yidl" import concept Base
Export export concept Classes makes a concept available to importers
Concept concept Child extends base.Base { ... }
Property property FieldName: str storage field_name; optional = value default
Record record Field { FieldName FieldOrder } — no commas between entries
Family family Fields { common Name, Order variant Plain {} }
Collection collection Fields: Field identity FieldId many; tuple identities supported
Computed view computed collection Selected: Field from Fields where Enabled == True
Resource resource Store = template $[ ... ]$; code, literal/import forms also exist
Matcher Named input aliases; defaults and named when rules; resource/contribution/operation result kinds
Contribution Resource/production, as, numeric index, order, target and bindings
Data production production P from Source to Target { set Name = source.Name }
Composable production production P -> composable { root Root = Resource ... }
Assembly assembly Module = P exports a named callable build
Operation Declared collection inputs/outputs and resource or matcher implementation

Conditions are equality terms joined with and; this is not unrestricted Python expression syntax. Resource bodies are Python/Astichi, but contribution binding expressions have a smaller grammar (literal, visible semantic name or tuple). An accepted parse is not proof that every syntactic combination has runtime semantics for your chosen surface/backend.

Delimiters and small failures

Resources accept quoted strings, inline backticks, fenced blocks and $[ ... ]$ or $( ... )$ forms defined below. Use the tutorial's $[ form for multiline Python. YIDL record bodies use separate property entries: record R { Name Order }. record R { Name, Order } raises a comma parser diagnostic. A comma in common or an explicit tuple is a different grammar position.

A missing imported key fails resolution; a missing export fails symbol lookup; duplicate inherited productions/defaults fail composition. An assembly name is not inferred from a production's name.

Exact grammar of this candidate

This block is extracted from the compiler grammar at site build time. It provides all productions, including phase/operation/diagnostic syntax. Tested grammar acceptance/rejection is covered by tests/generation/test_yidl_lark_parser.py, test_yidl_lark_update_a_diagnostics.py and test_yidl_operation_matchers.py.

Source authority: src/yidl/concept_grammar.lark.

start: file

file: module_decl? import_decl* top_level_decl*

module_decl: "module" qname

import_decl: "import" STRING "as" CNAME                 -> import_alias
           | "from" STRING "import" import_item ("," import_item)* -> import_from

import_item: symbol_kind CNAME ("as" CNAME)?

symbol_kind: "concept" -> symbol_concept
           | "property" -> symbol_property
           | "record" -> symbol_record
           | "union" -> symbol_union
           | "collection" -> symbol_collection
           | "port" -> symbol_port
           | "resource" -> symbol_resource
           | "matcher" -> symbol_matcher
           | "contribution" -> symbol_contribution
           | "assembly" -> symbol_assembly
           | "operation" -> symbol_operation
           | "production" -> symbol_production

top_level_decl: export_decl
              | concept_decl
              | property_decl
              | resource_decl

export_decl: "export" symbol_kind CNAME

concept_decl: "concept" CNAME extends_clause? "{" concept_member* "}"

extends_clause: "extends" qname ("," qname)*

concept_member: use_decl
              | property_decl
              | record_decl
              | union_decl
              | family_decl
              | collection_decl
              | computed_collection_decl
              | computed_collection_filter_decl
              | port_decl
              | resource_decl
              | matcher_decl
              | contribution_decl
              | production_decl
              | composable_production_decl
              | composable_production_extension_decl
              | assemble_decl
              | assembly_decl
              | direct_operation_decl
              | matcher_operation_decl
              | diagnostics_decl

use_decl: "use" qname ("as" CNAME)?

property_decl: "property" CNAME ":" type_expr default_clause? storage_clause?
default_clause: "=" value_expr
storage_clause: "storage" CNAME

type_expr: qname
         | "object" -> type_object
         | "str" -> type_str
         | "int" -> type_int
         | "bool" -> type_bool
         | "float" -> type_float
         | "literal" "[" literal_list "]" -> type_literal

record_decl: "record" CNAME "{" property_ref* "}"
property_ref: qname

union_decl: "union" CNAME "{" variant_decl* "}"
variant_decl: "variant" CNAME "{" property_ref* "}"

family_decl: "family" qname "{" family_member* "}"
family_member: "common" property_ref ("," property_ref)* -> family_common
             | variant_decl

collection_decl: "collection" CNAME ":" type_ref identity_clause? cardinality_clause?
type_ref: qname
identity_clause: "identity" identity_expr
identity_expr: property_ref
             | "(" property_ref ("," property_ref)+ ")"
cardinality_clause: "single" -> cardinality_single
                  | "many" -> cardinality_many

computed_collection_decl: "computed" "collection" CNAME ":" type_ref "from" qname "where" condition_expr
computed_collection_filter_decl: "filter" qname "where" condition_expr

port_decl: "port" CNAME STRING cardinality_clause

resource_decl: "resource" CNAME "=" resource_expr
resource_expr: "literal" value_expr       -> resource_literal
             | "import" STRING "." CNAME  -> resource_import
             | "code" snippet resource_options? -> resource_code
             | "template" snippet resource_options? -> resource_template
             | "astichi_code" snippet resource_options? -> resource_astichi_code
             | "astichi_template" snippet resource_options? -> resource_astichi_template

snippet: STRING -> snippet_string
       | BACKTICK_INLINE -> snippet_backtick_inline
       | BACKTICK_BLOCK -> snippet_backtick_block
       | DOLLAR_PAREN_INLINE -> snippet_dollar_paren_inline
       | DOLLAR_PAREN_BLOCK -> snippet_dollar_paren_block
       | DOLLAR_SQUARE_INLINE -> snippet_dollar_square_inline
       | DOLLAR_SQUARE_BLOCK -> snippet_dollar_square_block

resource_options: "{" resource_option* "}"
resource_option: "keep" keep_name_list -> resource_keep
               | "edge" resource_edge_kind "=" resource_ref_expr -> resource_edge
keep_name_list: CNAME ("," CNAME)*
resource_edge_kind: "arg_names" -> edge_arg_names
                  | "bind" -> edge_bind
                  | "keep_names" -> edge_keep_names

resource_ref_expr: resource_ref -> resource_name_ref
                 | "match" "." "resource" "(" ")" -> resource_match_ref

matcher_decl: "matcher" CNAME "(" matcher_input_list? ")" matcher_kind? "{" matcher_default? matcher_rule* "}"
matcher_input_list: matcher_input ("," matcher_input)*
matcher_input: CNAME ":" qname
matcher_kind: "->" "resource" -> matcher_kind_resource
            | "->" "contribution" -> matcher_kind_contribution
            | "->" "operation" -> matcher_kind_operation
matcher_default: "default" "->" resource_ref_expr
matcher_rule: "rule" CNAME "when" condition_expr "->" resource_ref_expr weight_clause?
resource_ref: qname
weight_clause: "weight" NUMBER

contribution_decl: "contribution" CNAME contribution_source "{" contribution_member* "}"
contribution_source: "=" resource_ref_expr
contribution_member: contribution_as
                   | contribution_index
                   | contribution_order
                   | target_decl
                   | bind_decl
                   | contribution_diagnostic
contribution_as: "as" CNAME
contribution_index: "index" contribution_value_expr
contribution_order: "order" contribution_value_expr
contribution_diagnostic: "diagnostic"
target_decl: "target" CNAME "{" target_path_option* "}"
target_path_option: "build" path -> target_build
                  | "owner" path -> target_owner
path: ("/" path_segment)+
path_segment: CNAME path_index*
            | "." -> path_current
            | "?" -> path_optional
            | "*" -> path_any
            | "+" -> path_many
path_index: "[" contribution_value_expr ("," contribution_value_expr)* "]"
bind_decl: contribution_bind_kind CNAME "=" contribution_value_expr
contribution_bind_kind: "ident" -> bind_ident
                      | "external" -> bind_external
?contribution_value_expr: literal_expr
                        | qname
                        | contribution_tuple_expr
contribution_tuple_expr: "(" contribution_value_expr "," (contribution_value_expr ("," contribution_value_expr)*)? ")"

production_decl: "production" CNAME "from" source_expr "to" qname "{" production_member* "}"
source_expr: CNAME "." "results" "(" ")" order_clause? -> matcher_results_source
           | qname order_clause? -> collection_source
order_clause: "ordered" "(" property_ref ("," property_ref)* ")"
production_member: "identity" value_expr
                 | "policy" qname
                 | "set" property_ref "=" value_expr

composable_production_decl: "production" CNAME composable_production_inputs? "->" "composable" "{" composable_production_member* "}"
composable_production_inputs: "(" matcher_input_list? ")"
composable_production_member: root_decl
                            | apply_decl
                            | phase_decl
phase_decl: "phase" CNAME phase_position? phase_context? "{" apply_decl* "}"
phase_position: phase_anchor phase_order?
              | phase_order
phase_anchor: "after" CNAME
phase_order: "order" SIGNED_INT
composable_production_extension_decl: "extend" "production" qname "{" phase_extension_decl* "}"
phase_extension_decl: "phase" CNAME phase_position? phase_context? "{" apply_decl* "}"
phase_context: assemble_from where_clause?
             | where_clause
root_decl: "root" CNAME "=" resource_ref_expr root_options?
root_options: "{" bind_decl* "}"
apply_decl: "apply" CNAME apply_tail?
apply_tail: assemble_from? where_clause? "using" CNAME
assemble_decl: "assemble" CNAME assemble_context? assemble_from? where_clause? "using" CNAME
assemble_context: "(" matcher_input_list? ")"
assemble_from: "from" matcher_input_list
where_clause: "where" condition_expr
assembly_decl: "assembly" CNAME "=" qname

direct_operation_decl: "operation" CNAME operation_io "using" resource_ref_expr operation_options?
matcher_operation_decl: "operation" CNAME operation_from operation_io "using" "matcher" CNAME operation_options?
operation_from: "from" matcher_input
operation_io: "inputs" "(" operation_input_list? ")" "outputs" "(" operation_output_list? ")"
operation_input_list: qname_list
operation_output_list: qname_list
qname_list: qname ("," qname)*
operation_options: "{" operation_option* "}"
operation_option: "ordered" "(" property_ref ("," property_ref)* ")"
                | "diagnostics" qname

diagnostics_decl: "diagnostics" CNAME "{" "collection" CNAME "gate" CNAME "}"

?condition_expr: condition_term
               | condition_expr "and" condition_term -> condition_and
condition_term: value_expr "==" value_expr

?value_expr: literal_expr
           | qname
           | source_ref
           | match_ref
           | lookup_expr
           | port_address_expr
           | tuple_expr

source_ref: "source" "." property_ref
match_ref: "match" "." "resource" "(" ")" -> match_resource
         | "match" "." "record" "(" STRING ")" "." property_ref -> match_record
         | "match" "." "value" "(" INT ")" -> match_value
lookup_expr: "lookup" "(" qname "," "key" "=" value_expr "," "value" "=" property_ref default_arg? ")"
default_arg: "," "default" "=" value_expr
port_address_expr: qname "." "of" "(" value_expr ")"
tuple_expr: "(" ")" -> tuple_empty
          | "(" value_expr "," ")" -> tuple_single
          | "(" value_expr "," value_expr ("," value_expr)* ","? ")" -> tuple_multi

literal_expr: STRING
            | INT
            | NUMBER
            | "True" -> true
            | "False" -> false
            | "None" -> none

literal_list: literal_expr ("," literal_expr)*

qname: CNAME ("." CNAME)*

COMMENT: /#[^\n]*/
BACKTICK_BLOCK.20: /```(?:[A-Za-z_][A-Za-z0-9_ -]*)?\r?\n(?s:.*?)(?:\r?\n)[ \t]*```/
BACKTICK_INLINE.20: /`[^\r\n`]*`/
DOLLAR_PAREN_BLOCK.20: /\$\(\r?\n(?s:.*?)(?:\r?\n)[ \t]*\)\$/
DOLLAR_PAREN_INLINE.20: /\$\([^\r\n]*?\)\$/
DOLLAR_SQUARE_BLOCK.20: /\$\[\r?\n(?s:.*?)(?:\r?\n)[ \t]*\]\$/
DOLLAR_SQUARE_INLINE.20: /\$\[[^\r\n]*?\]\$/

%import common.CNAME
%import common.ESCAPED_STRING -> STRING
%import common.INT
%import common.SIGNED_INT
%import common.SIGNED_NUMBER -> NUMBER
%import common.WS
%ignore WS
%ignore COMMENT