Appendix A. Metaslang Grammar

This appendix lists the grammar rules of the Metaslang specification language. These rules are identical to those of the Chapter on Metaslang. They are brought together here, without additional text, for easy reference.

The Grammar Description Formalism.
  wiffle ::= waffle [ waffle-tail ] | piffle { + piffle }*
  piffle ::= 1 | M { piffle }*

Models.
  op ::= op-name
  spec ::= spec-form

Symbols and Names.
  symbol ::= simple-name | literal | special-symbol
  
  simple-name ::= first-syllable { _ next-syllable }*
  
  first-syllable ::= first-word-syllable | non-word-syllable
  
  next-syllable ::= next-word-syllable | non-word-syllable
  
  first-word-syllable ::= word-start-mark { word-continue-mark }*
  
  next-word-syllable ::= word-continue-mark { word-continue-mark }*
  
  word-start-mark ::= letter
  
  word-continue-mark ::= letter | decimal-digit | ' | ?
  
  letter ::=
    A | B | C | D | E | F | G | H | I | J | K | L | M
  | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
  | a | b | c | d | e | f | g | h | i | j | k | l | m
  | n | o | p | q | r | s | t | u | v | w | x | y | z
  
  decimal-digit ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
  
  non-word-syllable ::= non-word-mark { non-word-mark }*
  
  non-word-mark ::=
    ` | ~ | ! | @ | $ | ^ | & | * | -
  | = | + | \ | | | : | < | > | / | ' | ?
  
  special-symbol ::= _ | ( | ) | [ | ] | { | } | ; | , | .

Comments.
  comment ::= line-end-comment | block-comment
  
  line-end-comment ::= % line-end-comment-body
  
  line-end-comment-body ::=
  any-text-up-to-end-of-line
  
  block-comment ::= (* block-comment-body *)
  
  block-comment-body ::=
  any-text-including-newlines-and-nested-block-comments

Units.
  unit-definition ::= unit-identifier = unit-term
  
  unit-term ::=
    spec-term
  | morphism-term
  | diagram-term
  | target-code-term
  | proof-term
  
  specware-file-contents ::=
    unit-term
  | infile-unit-definition { infile-unit-definition }*
  
  infile-unit-definition ::= fragment-identifier = unit-term
  
  fragment-identifier ::= simple-name

Unit Identifiers.
  unit-identifier ::= swpath-based-path | relative-path
  
  swpath-based-path ::= / relative-path
  
  relative-path ::= { path-element / }* path-element [ # fragment-identifier ]
  
  path-element ::= path-mark { path-mark }*
  
  path-mark ::=
    letter | decimal-digit
  | ! | $ | & | ' | + | -
  | = | @ | ^ | ` | ~ | .

Specs.
  spec-term ::=
    unit-identifier
  | spec-form
  | spec-qualification
  | spec-translation
  | spec-substitution
  | diagram-colimit
  | obligator

Spec Forms.
  spec-form ::= spec { declaration }* endspec

Qualifications.
  spec-qualification ::=  qualifier qualifying spec-term
  
  qualifier ::= simple-name
  
  name ::= simple-name | qualified-name
  
  qualified-name ::= qualifier . simple-name

Translations.
  spec-translation ::= translate spec-term by name-map
  
  name-map ::= { [ name-map-item { , name-map-item }* ] }
  
  name-map-item ::=
    type-name-map-item
  | op-name-map-item
  | wildcard-map-item
  
  type-name-map-item ::= [ type ] name +-> name
  
  op-name-map-item ::= [ op ] annotable-name +-> annotable-name
  
  annotable-name ::= name [ type-annotation ]
  
  type-annotation ::= : type-descriptor
  
  wildcard-map-item ::= wildcard +-> wildcard
  
  wildcard ::= simple-wildcard | qualified-wildcard
  
  simple-wildcard ::= _
  
  qualified-wildcard ::= qualifier . simple-wildcard

Substitutions.
  spec-substitution ::= spec-term [ morphism-term ]

Diagram Colimits.
  diagram-colimit ::= colimit diagram-term

Obligators.
  obligator ::= obligations unit-term

Morphisms.
  morphism-term ::=
    unit-identifier
  | spec-morphism
  
  spec-morphism ::= morphism spec-term -> spec-term name-map

Diagrams.
  diagram-term ::=
    unit-identifier
  | diagram-form
  
  diagram-form ::= diagram { diagram-element { , diagram-element }* }
  
  diagram-element ::=
    diagram-node
  | diagram-edge
  
  diagram-node ::= simple-name +-> spec-term
  
  diagram-edge ::= simple-name : simple-name -> simple-name +-> morphism-term

Target Code Terms.
  target-code-term ::=
    generate target-language-name spec-term [ generate-option ]
  
  generate-option ::=
    in string-literal | with unit-identifier
  
  target-language-name ::= c | java | lisp

Proof Terms.
  proof-term ::=
    prove claim-name in spec-term
                    [ with prover-name ]
                    [ using claim-list ]
                    [ options prover-options ]
  
  prover-name ::= snark
  
  claim-list ::= claim-name { , claim-name }*
  
  prover-options ::= string-literal

Declarations.
  declaration ::=
    import-declaration
  | type-declaration
  | op-declaration
  | claim-declaration
  | definition
  
  definition ::=
    type-definition
  | op-definition
  
  equals ::= is | =

Import-declarations.
  import-declaration ::= import spec-term { , spec-term }*

Type-declarations.
  type-declaration ::=
   type type-name [ formal-type-parameters ] [ equals old-or-new-type-descriptor ]
  
  formal-type-parameters ::= local-type-variable | ( local-type-variable-list )
  
  local-type-variable ::= simple-name
  
  local-type-variable-list ::= local-type-variable { , local-type-variable }*
  
  old-or-new-type-descriptor ::= type-descriptor | new-type-descriptor

Type-definitions.
  type-definition ::=
    type-abbreviation
  | new-type-definition
  
  type-abbreviation ::=
  def [ type ] type-name [ formal-type-parameters ] equals type-descriptor
  
  new-type-definition ::=
  def [ type ] type-name [ formal-type-parameters ] equals new-type-descriptor

Op-declarations.
  op-declaration ::=
    op [ type-variable-binder ] formal-expression [ fixity ] type-annotation
      [ equals expression ]
  | op formal-expression [ fixity ] polytype-annotation
      [ equals expression ]
  
  polytype-annotation ::= : type-variable-binder type-descriptor
  
  type-variable-binder ::= [ local-type-variable-list ]
  
  formal-expression ::= op-name | formal-application
  
  formal-application ::= formal-application-head formal-parameter
  
  formal-application-head ::= op-name | formal-application
  
  formal-parameter ::= closed-pattern | ( pattern | expression )
  
  fixity ::= associativity priority
  
  associativity ::= infixl | infixr
  
  priority ::= nat-literal

Op-definitions.
  op-definition ::=
    def [ op ] [ type-variable-binder ] formal-expression [ type-annotation ]
      equals expression
  | def [ op ] formal-expression polytype-annotation
      equals expression

Claim-declarations.
  claim-declaration ::= claim-kind claim-name is claim [ proof-script ]
  
  claim-kind ::= axiom | theorem | conjecture
  
  claim-name ::= name
  
  claim ::= [ type-variable-binder ] expression

Type-descriptors.
  type-descriptor ::=
    type-arrow
  | slack-type-descriptor
  
  new-type-descriptor ::=
    type-sum
  | type-quotient
  
  slack-type-descriptor ::=
    type-product
  | tight-type-descriptor
  
  tight-type-descriptor ::=
    type-instantiation
  | closed-type-descriptor
  
  closed-type-descriptor ::=
    type-name
  | Boolean
  | local-type-variable
  | type-record
  | type-restriction
  | type-comprehension
  | ( type-descriptor )

Type-sums.
  type-sum ::= type-summand { type-summand }*
  
  type-summand ::= | constructor [ slack-type-descriptor ]
  
  constructor ::= simple-name

Type-arrows.
  type-arrow ::= arrow-source -> type-descriptor
  
  arrow-source ::= type-sum | slack-type-descriptor

Type-products.
  type-product ::= tight-type-descriptor * tight-type-descriptor { * tight-type-descriptor }*

Type-instantiations.
  type-instantiation ::= type-name actual-type-parameters
  
  actual-type-parameters ::= closed-type-descriptor | ( proper-type-list )
  
  proper-type-list ::= type-descriptor , type-descriptor { , type-descriptor }*

Type-names.
  type-name ::= name

Type-records.
  type-record ::= { [ field-typer-list ] } | ( )
  
  field-typer-list ::= field-typer { , field-typer }*
  
  field-typer ::= field-name type-annotation
  
  field-name ::= simple-name

Type-restrictions.
  type-restriction ::= ( slack-type-descriptor | expression )

Type-comprehensions.
  type-comprehension ::= { annotated-pattern | expression }

Type-quotients.
  type-quotient ::= closed-type-descriptor / closed-expression

Expressions.
  expression ::=
    lambda-form
  | case-expression
  | let-expression
  | if-expression
  | quantification
  | unique-solution
  | annotated-expression
  | tight-expression
  
  tight-expression ::=
    application
  | closed-expression
  
  closed-expression ::=
    op-name
  | local-variable
  | literal
  | field-selection
  | tuple-display
  | record-display
  | sequential-expression
  | list-display
  | monadic-expression
  | structor
  | ( expression )
  | ( inbuilt-op )
  
  inbuilt-op ::= inbuilt-prefix-op | inbuilt-infix-op
  
  inbuilt-prefix-op ::=  ~
  
  inbuilt-infix-op ::=  <=>  |  =>  |  ||  |  &&  |  =  |  ~=  |  <<

Lambda-forms.
  lambda-form ::= fn match

Case-expressions.
  case-expression ::= case expression of match

Let-expressions.
  let-expression ::= let let-bindings in expression
  
  let-bindings ::= recless-let-binding | rec-let-binding-sequence
  
  recless-let-binding ::= pattern equals expression
  
  rec-let-binding-sequence ::= rec-let-binding { rec-let-binding }*
  
  rec-let-binding ::=
  def simple-name formal-parameter-sequence [ type-annotation ] equals expression
  
  formal-parameter-sequence ::= formal-parameter { formal-parameter }*

If-expressions.
  if-expression ::= if expression then expression else expression

Quantifications.
  quantification ::= quantifier ( local-variable-list ) expression
  
  quantifier ::= fa | ex | ex1
  
  local-variable-list ::= annotable-variable { , annotable-variable }*
  
  annotable-variable ::= local-variable [ type-annotation ]
  
  local-variable ::= simple-name

Unique-solutions.
  unique-solution ::= the ( local-variable-list ) expression

Annotated-expressions.
  annotated-expression ::= tight-expression type-annotation

Applications.
  application ::= prefix-application | infix-application
  
  prefix-application ::= application-head actual-parameter
  
  application-head ::=
    closed-expression
  | inbuilt-prefix-op
  | prefix-application
  
  actual-parameter ::= closed-expression
  
  infix-application ::= operand infix-operator operand
  
  operand ::= tight-expression
  
  infix-operator ::= op-name | inbuilt-infix-op

Op-names.
  op-name ::= name

Literals.
  literal ::=
    boolean-literal
  | nat-literal
  | char-literal
  | string-literal

Boolean-literals.
  boolean-literal ::= true | false

Nat-literals.
  nat-literal ::=
        decimal-digit     { decimal-digit }*
  | 0 X hexadecimal-digit { hexadecimal-digit }*
  | 0 x hexadecimal-digit { hexadecimal-digit }*
  | 0 O octal-digit       { octal-digit  }*
  | 0 o octal-digit       { octal-digit  }*
  | 0 B binary-digit      { binary-digit }*
  | 0 b binary-digit      { binary-digit }*
  
  hexadecimal-digit ::=
    decimal-digit
  | a | b | c | d | e | f
  | A | B | C | D | E | F
  
  octal-digit ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
  
  binary-digit ::= 0 | 1

Char-literals.
  char-literal ::= #char-literal-glyph
  
  char-literal-glyph ::= char-glyph | "
  
  char-glyph ::=
    letter
  | decimal-digit
  | other-char-glyph
  
  other-char-glyph ::=
    ! | : | @ | # | $ | % | ^ | & | * | ( | ) | _ | - | + | =
  | | | ~ | ` | . | , | < | > | ? | / | ; | ' | [ | ] | { | }
  | \\ | \"
  | \a | \b | \t | \n | \v | \f | \r | \s
  | \x hexadecimal-digit hexadecimal-digit

String-literals.
  string-literal ::= " string-body "
  
  string-body ::= { string-literal-glyph }*
  
  string-literal-glyph ::= char-glyph | significant-whitespace
  
  significant-whitespace ::= space | tab | newline

Field-selections.
  field-selection ::= closed-expression . field-selector
  
  field-selector ::= nat-literal | field-name

Tuple-displays.
  tuple-display ::= ( tuple-display-body )
  
  tuple-display-body ::= [ expression , expression { , expression }* ]

Record-displays.
  record-display ::= { record-display-body }
  
  record-display-body ::= [ field-filler { , field-filler }* ]
  
  field-filler ::= field-name equals expression

Sequential-expressions.
  sequential-expression ::= ( open-sequential-expression )
  
  open-sequential-expression ::= void-expression ; sequential-tail
  
  void-expression ::= expression
  
  sequential-tail ::= expression | open-sequential-expression

List-displays.
  list-display ::= [ list-display-body ]
  
  list-display-body ::= [ expression { , expression }* ]

Monadic-expressions.
  monadic-expression ::= { open-monadic-expression }
  
  open-monadic-expression ::= monadic-statement ; monadic-tail
  
  monadic-statement ::= expression | monadic-binding
  
  monadic-binding ::= pattern <- expression
  
  monadic-tail ::= expression | open-monadic-expression

Structors.
  structor ::=
    projector
  | quotienter
  | chooser
  | embedder
  | embedding-test
  projector ::= project field-selector
  quotienter ::= quotient [ type-name ]
  chooser ::= choose [ type-name ]
  embedder ::= [ embed ] constructor
  embedding-test ::= embed? constructor

Matches.
  match ::= [ | ] branch { | branch }*
  
  branch ::= pattern [ guard ] -> expression
  
  guard ::= | expression

Patterns.
  pattern ::=
    annotated-pattern
  | tight-pattern
  
  tight-pattern ::=
    aliased-pattern
  | cons-pattern
  | embed-pattern
  | quotient-pattern
  | closed-pattern
  
  closed-pattern ::=
    variable-pattern
  | wildcard-pattern
  | literal-pattern
  | list-pattern
  | tuple-pattern
  | record-pattern
  | ( pattern )
  
  annotated-pattern ::= pattern type-annotation
  
  aliased-pattern ::= variable-pattern as tight-pattern
  
  cons-pattern ::= closed-pattern :: tight-pattern
  
  embed-pattern ::= constructor [ closed-pattern ]
  
  quotient-pattern ::= quotient [ type-name ]		
  	
  variable-pattern ::= local-variable
  
  wildcard-pattern ::= _
  
  literal-pattern ::= literal
  
  list-pattern ::= [ list-pattern-body ]
  
  list-pattern-body ::= [ pattern { , pattern }* ]
  
  tuple-pattern ::= ( tuple-pattern-body )
  
  tuple-pattern-body ::= [ pattern , pattern { , pattern }* ]
  
  record-pattern ::= { record-pattern-body }
  
  record-pattern-body ::= [ field-patterner { , field-patterner }* ]
  
  field-patterner ::= field-name [ equals pattern ]