tasl = *( block newline ) block

block = *WSP [ line-comment / statement *WSP ]

statement = namespace-definition
          / literal-definition
          / type-definition
          / class-declaration
          / edge-declaration

keyword-namespace = %x6E.61.6D.65.73.70.61.63.65
keyword-type      = %x74.79.70.65
keyword-class     = %x63.6C.61.73.73
keyword-edge      = %x65.64.67.65

namespace-definition = keyword-namespace 1*WSP identifier 1*WSP namespace-uri
literal-definition   = keyword-literal 1*WSP identifier 1*WSP term
type-definition      = keyword-type 1*WSP identifier 1*WSP type
class-declaration    = keyword-class 1*WSP term 1*WSP "::" 1*WSP type
edge-declaration     = keyword-edge 1*WSP term 1*WSP "::" 1*WSP term 1*WSP edge 1*WSP term
edge                 = "=>"
                     / "=/" 1*WSP type 1*WSP "/=>"

type = identifier    ; type variable
     / optional      ; optional type
     / reference     ; reference type
     / uri           ; uri type
     / product       ; product type
     / coproduct     ; coproduct type

optional   = "?" *WSP type
uri        = "<>"
reference  = "*" *WSP term
product    = "{" [ *WSP newline components ] *WSP "}"
components = *( *WSP [ line-comment / component *WSP ] newline )
component  = term 1*WSP "->" 1*WSP type
coproduct  = "[" [ *WSP newline options ] *WSP "]"
options    = *( *WSP [ line-comment / option *WSP ] newline )
option     = term 1*WSP "<-" 1*WSP type

term = identifier ":" 1*( pchar / "/" / "?" )

namespace-uri = absolute-uri ( "/" / "?" / "#" )
absolute-uri  = scheme ":" ( "//" authority / [ "/" ] 1*pchar ) *( "/" 1*pchar )

identifier = ALPHA *(ALPHA / DIGIT)

newline = LF / CRLF

line-comment = "#" *(WSP / VCHAR)