Syntax of Miranda scripts and expressions

script:= decl*                          rhs:= simple_rhs(;)
                                              cases
decl:= def
       tdef                             simple_rhs:= exp whdefs?
       spec
       libdir                           cases:= alt(;) = cases
                                                lastcase(;)
def:= fnform = rhs
      pat = rhs                         alt:= exp , if? exp

tdef:= tform == type(;)                 lastcase:= lastalt whdefs?
       tform ::= constructs(;)
       abstype tform-list with sig(;)   lastalt:= exp , if? exp
                                                  exp , otherwise
spec:= var-list :: type(;)
       tform-list :: type(;)            whdefs:= where def def*

sig:= spec spec*                        exp:= e1
                                              prefix1
constructs:= construct | constructs           infix
             construct
                                        e1:= simple simple*
construct:= constructor argtype*             prefix e1
            type $constructor type           e1 infix e1
            ( construct ) argtype*
                                        simple:= var
type:= argtype                                   constructor
       typename argtype*                         literal
       type -> type                              readvals
       type $typename type                       show
                                                 ( infix1 e1 )
argtype:= typename                               ( e1 infix )
          typevar                                ( exp-list? )
          ( type-list? )                         [ exp-list? ]
          [ type-list ]                          [ exp .. exp? ]
                                                 [ exp , exp .. exp? ]
tform:= typename typevar*                        [ exp | qualifs ]
        typevar $typename typevar                [ exp // qualifs ]

fnform:= var formal*                    qualifs:= qualifier ; qualifs
         pat $var pat                             qualifier
         ( fnform ) formal*
                                        qualifier:= exp
pat:= formal                                        generator
      -numeral
      constructor formal*               generator:= pat-list <- exp
      pat : pat                                     pat <- exp , exp ..
      pat + nat
      pat $constructor pat              var:= identifier
      ( pat ) formal*
                                        constructor:= IDENTIFIER
formal:= var
         constructor                    typename:= identifier
         literal1
         ( pat-list? )
         [ pat-list? ]
