Grm. Grammar  ::= 
  "grammar" CId "(" [CId] ")" "(" [Flag] ")" ";" 
  Abstract ";" 
  [Concrete] ;

Abs. Abstract ::= 
  "abstract" "{" 
     "flags" [Flag] 
     "fun"   [FunDef] 
     "cat"   [CatDef] 
  "}" ;

Cnc. Concrete ::= 
  "concrete" CId "{" 
     "flags"  [Flag] 
     "lin"    [LinDef] 
     "oper"   [LinDef] 
     "lincat" [LinDef] 
     "lindef" [LinDef] 
     "printname" [LinDef]
     "param"  [LinDef]     -- lincats with param value names
  "}" ;

Flg. Flag     ::= CId "=" String ;
Cat. CatDef   ::= CId "[" [Hypo] "]" ;

Fun. FunDef   ::= CId ":" Type "=" Exp ;
Lin. LinDef   ::= CId "=" Term ;

DTyp. Type    ::= "[" [Hypo] "]" CId [Exp] ;         -- dependent type
DTr.  Exp     ::= "[" "(" [CId] ")" Atom [Exp] "]" ; -- term with bindings

AC.   Atom     ::= CId ;
AS.   Atom     ::= String ;
AI.   Atom     ::= Integer ;
AF.   Atom     ::= Double ;
AM.   Atom     ::= "?" Integer ;

R.   Term     ::= "[" [Term] "]" ;          -- record/table
P.   Term     ::= "(" Term "!" Term ")" ;   -- projection/selection
S.   Term     ::= "(" [Term] ")" ;          -- concatenated sequence
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
TM.  Term     ::= "?" ;                     -- lin of metavariable

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


RP.  Term     ::= "(" Term "@" Term ")";    -- DEPRECATED: record parameter alias

terminator Concrete ";" ;
terminator Flag ";" ;
terminator CatDef ";" ;
terminator FunDef ";" ;
terminator LinDef ";" ;
separator  CId "," ;
separator  Term "," ;
terminator Exp "" ;
terminator String "" ;
separator  Variant "," ;

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


-- the following are needed if dependent types or HOAS or defs are present

Hyp. Hypo     ::= CId ":" Type ;
AV.  Atom     ::= "$" CId ;

EEq. Exp      ::= "{" [Equation] "}" ;  -- list of pattern eqs; primitive: []
Equ. Equation ::= [Exp] "->" Exp ;      -- patterns are encoded as exps

separator  Hypo "," ;
terminator Equation ";" ;

