This is the grammar specification for app inputs.
Notation.
x? zero or one x x* zero or more x x+ one or more x x/y one or more x's separated by y
Rules.
goal
-> item*
item
-> alpha-item
-> any C++ token
alpha-item
-> alpha-type-decl
-> alpha-nested-item
alpha-type-decl
-> alpha-forward-type-decl
-> alpha-base-type-decl
-> alpha-unit-type-decl
-> alpha-data-type-decl
-> alpha-type-type-decl
alpha-forward-type-decl
-> '$data' id alpha-type-head? '$forward'? root-code? ';'
-> '$type' id alpha-type-head? '$forward'? ';'
alpha-base-type-decl
-> '$base' 'explicit'? id alpha-type-head? base-products code? ';'
-> '$base' id alpha-type-head? ';'
base-products
-> '(' balanced-items-list? ')'
alpha-unit-type-decl
-> '$unit' 'explicit'? id alpha-type-head? products unit-code? ';'
alpha-data-type-decl
-> '$data' id alpha-type-head? '=' sums root-code? ';'
sums
-> sum/'|'
sum
-> 'explicit'? id products code?
-> '0'
alpha-type-type-decl
-> '$type' id alpha-type-head? '=' alpha-type-spec ';'
products
-> '(' product-list? ')'
product-list
-> product/','
product
-> product-decl accessor
product-decl
-> 'const'? alpha-type-spec '&'? id
accessor
-> '=>' '(' ')'
-> '=>' 'const' '(' ')'
-> '=>' 'const'
->
user
-> '{' balanced-item* '}'
user-code
-> '$user'? user
body-user-code
-> user-code
handle-user-code
-> user-code
code
-> body-user-code handle-user-code?
root-code
-> ':' handle-user-code
unit-code
-> body-user-code? root-code?
alpha-type-head
-> '<' alpha-type-head-param/',' '>'
alpha-type-head-param
-> 'class' id
alpha-type-spec
-> id alpha-type-params?
alpha-type-params
-> '<' alpha-type-param/',' '>'
alpha-type-param
-> id alpha-type-params?
alpha-nested-item
-> option
-> match-stmt
option
-> '$option' string-literal
match-stmt
-> '$match' subjects pattern-cases
subjects
-> '(' balanced-items-list ')'
pattern-cases
-> '{' pattern-case* '}'
pattern-case
-> patterns guard? '=>' '{' balanced-item* '}'
patterns
-> '(' pattern-list ')'
pattern-list
-> pattern/','
pattern
-> positional-pattern
positional-pattern
-> inductive-pattern
-> binding-pattern
-> zero-pattern
inductive-pattern
-> pattern-decl subpatterns
binding-pattern
-> id
zero-pattern
-> '0'
pattern-decl
-> pattern-spec id?
pattern-spec
-> id alpha-type-params?
subpatterns
-> '(' subpattern-list? ')'
subpattern-list
-> subpattern/','
subpattern
-> positional-pattern
-> nonpositional-pattern
nonpositional-pattern
-> explicit-pattern
-> implicit-pattern
-> ellipsis-pattern
explicit-pattern
-> id ':' positional-pattern
implicit-pattern
-> id ':'
ellipsis-pattern
-> '...'
guard
-> '|' '(' balanced-item+ ')'
balanced-item
-> balanced-item-no-comma
-> ','
balanced-item-no-comma
-> alpha-nested-item
-> '(' balanced-item* ')'
-> '[' balanced-item* ']'
-> '{' balanced-item* '}'
-> any C++ token but ',' not conflicting with any of the above
balanced-items-list
-> balanced-items-no-comma/','
balanced-items-no-comma
-> balanced-item-no-comma+
Notes.
An "id" is any valid C++ identifier.
A "string-literal" is any valid C++ non-multi-part string literal e.g. "xy" is
okay but not "x" "y".