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 ::= word-symbol | non-word-symbol
  
  word-symbol ::= word-start-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-symbol ::= 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 ::= word-symbol

Unit Identifiers.
  unit-identifier ::= swpath-based-path | relative-path
  
  swpath-based-path ::= / relative-path
  
  relative-path ::= { path-element / }* path-element [ # fragment-identifier ]
  
  path-element ::= word-symbol

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 ::= word-symbol
  
  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
  
  type-name-map-item ::= [ type ] name +-> name
  
  op-name-map-item ::= [ op ] annotable-name +-> annotable-name
  
  annotable-name ::= name [ : type-descriptor ]

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
    | definition
  
  definition ::=
      type-definition
    | op-definition
    | claim-definition
  
  equals ::= is | =

Import-declarations.
  import-declaration ::= import spec-term

Type-declarations.
  type-declaration ::= type type-name [ formal-type-parameters ]
  
  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 }*
  

Type-definitions.
  type-definition ::= type type-name [ formal-type-parameters ] equals type-descriptor

Op-declarations.
  op-declaration ::= op op-name [ fixity ] : type-scheme
  
  fixity ::= associativity priority
  
  associativity ::= infixl | infixr
  
  priority ::= nat-literal
  
  type-scheme ::= [ type-variable-binder ] type-descriptor
  
  type-variable-binder ::= `[ local-type-variable-list `]
  

Op-definitions.
  op-definition ::=
    def [ type-variable-binder ] formal-expression [ : type-descriptor ] equals
        expression
  
  formal-expression ::= op-name | formal-application
  
  formal-application ::= formal-application-head formal-parameter
  
  formal-application-head ::= op-name | formal-application
  
  formal-parameter ::= closed-pattern
  

Claim-definitions.
  claim-definition ::= claim-kind claim-name is claim
  
  claim-kind ::= axiom | theorem | conjecture
  
  claim-name ::= name
  
  claim ::= [ type-variable-binder ] expression

Type-descriptors.
  type-descriptor ::=
      type-sum
    | type-arrow
    | slack-type-descriptor
  
  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-quotient
    | ( 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-descriptor
  
  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
    | annotated-expression
    | tight-expression
  
  tight-expression ::=
      application
    | restrict-expression
    | closed-expression
  
  closed-expression ::=
      op-name
    | local-variable
    | literal
    | field-selection
    | tuple-display
    | record-display
    | sequential-expression
    | list-display
    | 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-descriptor ] 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
  
  local-variable-list ::= annotable-variable { , annotable-variable }*
  
  annotable-variable ::= local-variable [ : type-descriptor ]
  
  local-variable ::= simple-name
  

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

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

Restrict-expressions.
  restrict-expression ::= restrict closed-expression closed-expression

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 }*

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
  
  hexadecimal-digit ::=
      decimal-digit
    | a | b | c | d | e | f
    | A | B | C | D | E | F

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 }* ]
  

Structors.
  structor ::=
      projector
    | relaxator
    | quotienter
    | chooser
    | embedder
    | embedding-test
  projector ::= project field-selector
  relaxator ::= relax closed-expression
  quotienter ::= quotient closed-expression
  chooser ::= choose closed-expression
  embedder ::= [ embed ] constructor
  embedding-test ::= embed? constructor

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

Patterns.
  pattern ::=
      annotated-pattern
    | tight-pattern
  
  tight-pattern ::=
      aliased-pattern
    | cons-pattern
    | embed-pattern
    | quotient-pattern
    | relax-pattern
    | closed-pattern
  
  closed-pattern ::=
      variable-pattern
    | wildcard-pattern
    | literal-pattern
    | list-pattern
    | tuple-pattern
    | record-pattern
    | ( pattern )
  
  annotated-pattern ::= pattern : type-descriptor
  
  aliased-pattern ::= variable-pattern as tight-pattern
  
  cons-pattern ::= closed-pattern :: tight-pattern
  
  embed-pattern ::= constructor [ closed-pattern ]
  
  quotient-pattern ::= quotient closed-expression tight-pattern
  
  relax-pattern ::= relax closed-expression tight-pattern
  
  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 ]