The App Input Grammar

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".


CONTENTS NEXT