Grm. Grammar  ::= Header ";" Abstract ";" [Concrete] ;
Hdr. Header   ::= "grammar" CId "(" [CId] ")" ;
Abs. Abstract ::= "abstract" "{" [AbsDef] "}" ;
Cnc. Concrete ::= "concrete" CId "{" [CncDef] "}" ;

Fun. AbsDef   ::= CId ":" Type "=" Exp ;
--AFl. AbsDef   ::= "%" CId "=" String ; -- flag
Lin. CncDef   ::= CId "=" Term ;
--CFl. CncDef   ::= "%" CId "=" String ; -- flag

Typ. Type     ::= [CId] "->" CId ;
Tr.  Exp      ::= "(" Atom [Exp] ")" ;
AC.  Atom     ::= CId ;
AS.  Atom     ::= String ;
AI.  Atom     ::= Integer ;
AF.  Atom     ::= Double ;
AM.  Atom     ::= "?" ;
trA. Exp      ::= Atom ;
define trA a = Tr a [] ;

R.   Term     ::= "[" [Term] "]" ;          -- record/table
P.   Term     ::= "(" Term "!" Term ")" ;   -- projection/selection
S.   Term     ::= "(" [Term] ")" ;          -- sequence with ++
K.   Term     ::= Tokn ;                    -- token
V.   Term     ::= "$" Integer ;             -- argument
C.   Term     ::= Integer ;                 -- parameter value/label
F.   Term     ::= CId ;                     -- global constant
FV.  Term     ::= "[|" [Term] "|]" ;        -- free variation
W.   Term     ::= "(" String "+" Term ")" ; -- prefix + suffix table
RP.  Term     ::= "(" Term "@" Term ")";    -- record parameter alias
TM.  Term     ::= "?" ;                     -- lin of metavariable

L.   Term     ::= "(" CId "->" Term ")" ;   -- lambda abstracted table
BV.  Term     ::= "#" CId ;                 -- lambda-bound variable

KS.  Tokn     ::= String ;
KP.  Tokn     ::= "[" "pre" [String] "[" [Variant] "]" "]" ;
Var. Variant  ::= [String] "/" [String] ;


terminator Concrete ";" ;
terminator AbsDef ";" ;
terminator CncDef ";" ;
separator  CId "," ;
separator  Term "," ;
terminator Exp "" ;
terminator String "" ;
separator  Variant "," ;

token CId (('_' | letter) (letter | digit | '\'' | '_')*) ;
