In this appendix the context-free syntax of CLEAN is given. Notice that the layout rule (see 2.3.3) permits the omission of the semi-colon (';') which ends a definition and of the braces ('{' and '}') which are used to group a list of definitions.
The following notational conventions are used in the context-free syntax descriptions:
[notion] | means that the presence of notion is optional | |
{notion} | means that notion can occur zero or more times | |
{notion}+ | means that notion occurs at least once | |
{notion}-list | means one or more occurrences of notion separated by commas | |
terminals | are printed in 9 pts courier bold brown | |
keywords | are printed in 9 pts courier bold red | |
terminals | that can be left out in layout mode are printed in 9 pts courier bold blue | |
{notion}/ str | means the longest expression not containing the string str |
CleanProgram | = | {Module}+ | ||
Module | = | DefinitionModule | ||
| | ImplementationModule | |||
DefinitionModule | = | definition module ModuleName ; | ||
{DefDefinition} | ||||
| | system module ModuleName ; | |||
{DefDefinition} | ||||
ImplementationModule | = | [implementation] module ModuleName ; | ||
{ImplDefinition} |
ImplDefinition | = | ImportDef | // see A.2 | |||
| | FunctionDef | // see A.3 | ||||
| | GraphDef | // see A.3 | ||||
| | MacroDef | // see A.4 | ||||
| | TypeDef | // see A.5 | ||||
| | ClassDef | // see A.6 | ||||
| | GenericsDef | // see A.7 | ||||
| | ForeignExportDef | // see A.8 |
DefDefinition | = | ImportDef | // see A.2 | |||
| | FunctionExportTypeDef | // see A.3 | ||||
| | MacroDef | // see A.4 | ||||
| | TypeDef | // see A.5 | ||||
| | ClassExportDef | // see A.6 | ||||
| | GenericExportDef | // see A.7 |
ImportDef | = | ImplicitImportDef | ||
| | ExplicitImportDef |
ImplicitImportDef | = | import [qualified] {ModuleName}-list ; |
ExplicitImportDef | = | from ModuleName import [qualified] {Imports}-list ; | ||
Imports | = | FunctionName | ||
| | ::TypeName [ConstructorsOrFields] | |||
| | class ClassName [Members] | |||
| | instance ClassName {SimpleType}+ | |||
| | generic FunctionName |
ConstructorsOrFields | = | (..) | ||
| | ({ConstructorName}-list) | |||
| | {..} | |||
| | {{FieldName}-list} | |||
Members | = | (..) | ||
| | ({MemberName}-list) |
FunctionDef | = | [FunctionTypeDef] | ||
DefOfFunction |
DefOfFunction | = | {FunctionAltDef ;}+ | ||
| | ABCCodeFunctionDef | |||
FunctionAltDef | = | Function {Pattern} | ||
{GuardAlt} {LetBeforeExpression} FunctionResult | ||||
[LocalFunctionAltDefs] | ||||
FunctionResult | = | =[>] FunctionBody | ||
| | | Guard GuardRhs | |||
GuardAlt | = | {LetBeforeExpression} | BooleanExpr GuardRhs | ||
GuardRhs | = | {GuardAlt} {LetBeforeExpression} = [>] FunctionBody | ||
| | {GuardAlt} {LetBeforeExpression} | otherwise GuardRhs |
Function | = | FunctionName | ||
| | (FunctionName) |
LetBeforeExpression | = | # {GraphDefOrUpdate}+ | ||
| | #!{GraphDefOrUpdate}+ | |||
GraphDefOrUpdate | = | GraphDef | ||
| | Variable & {FieldName {Selection} = GraphExpr}-list ; | |||
| | Variable & {ArrayIndex {Selection} = GraphExpr}-list [\\ {Qualifier}-list] ; |
GraphDef | = | Selector =[:] GraphExpr ; | ||
Selector | = | BrackPattern |
Guard | = | BooleanExpr | ||
| | otherwise | |||
BooleanExpr | = | GraphExpr |
FunctionBody | = | RootExpression ; | ||
[LocalFunctionDefs] |
RootExpression | = | GraphExpr |
LocalFunctionAltDefs | = | [where] { {LocalDef}+ } | ||
LocalDef | = | GraphDef | ||
| | FunctionDef | |||
LocalFunctionDefs | = | [with] { {LocalDef}+ } |
ABCCodeFunctionDef | = | Function {Pattern} = code [inline] { ABCInstructions } |
FunctionTypeDef | = | FunctionName :: FunctionType ; | ||
| | (FunctionName) [FixPrec] [:: FunctionType] ; | |||
FunctionType | = | [{ArgType}+ ->] Type [ClassContext] [UnqTypeUnEqualities] | ||
ClassContext | = | | ClassConstraints {& ClassConstraints} | ||
ClassConstraints | = | ClassOrGenericName-list {SimpleType}+ | ||
UnqTypeUnEqualities | = | [ {{UniqueTypeVariable}+ <= UniqueTypeVariable}-list ] | ||
ClassOrGenericName | = | QClassName | ||
| | FunctionName {|TypeKind|} |
FunctionExportTypeDef | = | FunctionName :: FunctionType [Special] ; | ||
| | (FunctionName) [FixPrec] :: FunctionType [Special] ; |
Pattern | = | [Variable =:] BrackPattern | ||
BrackPattern | = | PatternVariable | ||
| | QConstructor | |||
| | (GraphPattern) | |||
| | SpecialPattern | |||
| | DynamicPattern |
PatternVariable | = | Variable | ||
| | _ |
QConstructor | = | QConstructorName | ||
| | (QConstructorName) |
GraphPattern | = | QConstructor {Pattern} | ||
| | GraphPattern QConstructorName GraphPattern | |||
| | Pattern |
SpecialPattern | = | BasicValuePattern | ||
| | ListPattern | |||
| | TuplePattern | |||
| | ArrayPattern | |||
| | RecordPattern | |||
| | UnitPattern |
BasicValuePattern | = | BasicValue | ||||
BasicValue | = | IntDenotation | // see B.4 | |||
| | RealDenotation | // see B.4 | ||||
| | BoolDenotation | // see B.4 | ||||
| | CharDenotation | // see B.4 |
ListPattern | = | [[ListKind][{LGraphPattern}-list [: GraphPattern]] [SpineStrictness]] | ||||
ListKind | = | ! | // head strict list | |||
| | # | // head strict, unboxed list | ||||
| | | | // overloaded list | ||||
SpineStrictness | = | ! | // tail (spine) strict list | |||
LGraphPattern | = | GraphPattern | ||||
| | CharsDenotation | // see B.4 |
TuplePattern | = | (GraphPattern,{GraphPattern}-list) |
RecordPattern | = | {[QTypeName |] {FieldName [= GraphPattern]}-list} |
ArrayPattern | = | {{GraphPattern}-list} | ||
| | {{ArrayIndex = Variable}-list} | |||
| | StringDenotation |
UnitPattern | = | () |
DynamicPattern | = | (GraphPattern :: DynamicType) | ||
DynamicType | = | [UnivQuantVariables] {DynPatternType}+ [ClassContext] | ||
DynPatternType | = | Type | ||
| | TypePatternVariable | |||
| | OverloadedTypePatternVariable | |||
TypePatternVariable | = | Variable | ||
OverloadedTypeVariable | = | Variable^ |
GraphExpr | = | Application |
Application | = | {BrackGraph}+ | ||||
| | GraphExpr Operator GraphExpr | |||||
| | GenericAppExpr | |||||
Operator | = | QFunctionName | // see A.9 | |||
| | QConstructorName | // see A.9 |
BrackGraph | = | GraphVariable | ||
| | QConstructor | |||
| | QFunction | |||
| | (GraphExpr) | |||
| | LambdaAbstr | |||
| | CaseExpr | |||
| | LetExpression | |||
| | SpecialExpression | |||
| | DynamicExpression | |||
| | MatchesPatternExpr |
GraphVariable | = | Variable | // see A.9 | |||
| | SelectorVariable | // see A.9 |
QFunction | = | QFunctionName | // see A.9 | |||
| | (QFunctionName) | // see A.9 |
LambdaAbstr | = | \ {Pattern}+ {LambdaGuardAlt} {LetBeforeExpression} LambdaResult | ||
LambdaResult | = | = GraphExpr | ||
| | -> GraphExpr | |||
| | | Guard LambdaGuardRhs | |||
LambdaGuardAlt | = | {LetBeforeExpression} | BooleanExpr LambdaGuardRhs | ||
LambdaGuardRhs | = | {LambdaGuardAlt} {LetBeforeExpression} LambdaGuardResult | ||
LambdaGuardResult | = | = GraphExpr | ||
| | -> GraphExpr | |||
| | | otherwise LambdaGuardRhs |
CaseExpr | = | case GraphExpr of | ||
{ {CaseAltDef}+ } | ||||
| | if BrackGraph BrackGraph BrackGraph | |||
CaseAltDef | = | {Pattern} | ||
{CaseGuardAlt} {LetBeforeExpression} CaseResult | ||||
[LocalFunctionAltDefs] | ||||
CaseResult | = | = [>] FunctionBody | ||
| | -> FunctionBody | |||
| | | Guard CaseGuardRhs | |||
CaseGuardAlt | = | {LetBeforeExpression} | BooleanExpr CaseGuardRhs | ||
CaseGuardRhs | = | {CaseGuardAlt} {LetBeforeExpression} CaseGuardResult | ||
CaseGuardResult | = | = [>] FunctionBody | ||
| | -> FunctionBody | |||
| | | otherwise CaseGuardRhs |
LetExpression | = | let { {LocalDef}+ } in GraphExpr |
SpecialExpression | = | BasicValue | ||
| | List | |||
| | Tuple | |||
| | Array | |||
| | ArraySelection | |||
| | Record | |||
| | RecordSelection | |||
| | UnitConstructor |
List | = | ListDenotation | ||||
| | DotDotExpression | |||||
| | ZF-expression | |||||
ListDenotation | = | [[ListKind] [{LGraphExpr}-list [: GraphExpr]] [SpineStrictness] ] | ||||
LGraphExpr | = | GraphExpr | ||||
| | CharsDenotation | // see B.4 | ||||
DotDotExpression | = | [[ListKind] GraphExpr [,GraphExpr]..[GraphExpr] [SpineStrictness] ] | ||||
ZF-expression | = | [[ListKind] GraphExpr \\ {Qualifier}-list [SpineStrictness]] |
Qualifier | = | Generators {, let { {LocalDef}+ } } {|Guard} | ||||
Generators | = | Generator {& Generator} | ||||
Generator | = | Selector <- ListExpr | // select from a lazy list | |||
| | Selector <|- ListExpr | // select from an overloaded list | ||||
| | Selector <-: ArrayExpr | // select from an array | ||||
Selector | = | BrackPattern | // for brack patterns see 3.2 | |||
ListExpr | = | GraphExpr | ||||
ArrayExpr | = | GraphExpr |
Tuple | = | (GraphExpr,{GraphExpr}-list) |
Array | = | ArrayDenotation | ||||
| | ArrayUpdate | |||||
| | ArrayComprehension | |||||
| | ArraySelection | |||||
ArrayDenotation | = | {[ArrayKind] {GraphExpr}-list} | ||||
| | StringDenotation | // see B.4 | ||||
ArrayUpdate | = | { ArrayExpr & {ArrayIndex {Selection} = GraphExpr}-list [\\ {Qualifier}-list]} | ||||
ArrayComprehension | = | {[ArrayKind] GraphExpr \\ {Qualifier}-list} | ||||
ArraySelection | = | ArrayExpr.ArrayIndex {Selection} | ||||
| | ArrayExpr!ArrayIndex {Selection} | |||||
Selection | = | .FieldName | ||||
| | .ArrayIndex | |||||
ArrayExpr | = | GraphExpr | ||||
ArrayIndex | = | [{IntegerExpr}-list] | ||||
IntegerExpr | = | GraphExpr |
Record | = | RecordDenotation | ||
| | RecordUpdate | |||
RecordDenotation | = | {[QTypeName|] {FieldName = GraphExpr}-list]} | ||
RecordUpdate | = | {[QTypeName|][RecordExpr &][{FieldName {Selection} = GraphExpr}-list]} | ||
RecordExpr | = | GraphExpr | ||
RecordSelection | = | RecordExpr [.QTypeName].FieldName {Selection} | ||
| | RecordExpr [.QTypeName]!FieldName {Selection} |
UnitConstructor | = | () |
DynamicExpression | = | dynamic GraphExpr [:: [UnivQuantVariables] Type [ClassContext]] |
MatchesPatternExpr | = | GraphExpr =: QConstructorName { _ } | ||
| | GraphExpr =: BrackPattern |
MacroDef | = | [MacroFixityDef] | ||
DefOfMacro | ||||
MacroFixityDef | = | (FunctionName) [FixPrec] ; | ||
DefOfMacro | = | Function {Variable} :== FunctionBody ; | ||
[LocalFunctionAltDefs] |
TypeDef | = | AlgebraicTypeDef | ||
| | RecordTypeDef | |||
| | SynonymTypeDef | |||
| | AbstractTypeDef | |||
| | AbstractSynonymTypeDef | |||
| | ExtensibleAlgebraicTypeDef | |||
| | AlgebraicTypeDefExtension | |||
| | NewTypeDef |
AlgebraicTypeDef | = | ::TypeLhs | = ConstructorDef | |||||||||||||||
{| ConstructorDef} ; | ||||||||||||||||||
ConstructorDef | = | [ExistQuantVariables] ConstructorName {ArgType} {& ClassConstraints} | ||||||||||||||||
| | [ExistQuantVariables] (ConstructorName) [FixPrec] {ArgType} {& ClassConstraints} |
TypeLhs | = | [*] TypeConstructor {[*]TypeVariable} | ||||
TypeConstructor | = | TypeName | // see A.9 |
ExistQuantVariables | = | E.{TypeVariable }+: |
FixPrec | = | infixl [Prec] | ||||
| | infixr [Prec] | |||||
| | infix [Prec] | |||||
Prec | = | Digit | // see A.9 |
BrackType | = | [Strict] [UnqTypeAttrib] SimpleType |
Strict | = | ! |
UnqTypeAttrib | = | * | ||||
| | UniqueTypeVariable: | // see A.9 | ||||
| | . |
Type | = | {BrackType}+ | ||
ArgType | = | BrackType | ||
| | [Strict] [UnqTypeAttrib] (UnivQuantVariables Type [ClassContext]) |
UnivQuantVariables | = | A.{TypeVariable }+: |
RecordTypeDef | = | ::TypeLhs = [ExistQuantVariables] [Strict] {{FieldName :: FieldType}-list} ; | ||
FieldType | = | [Strict] Type | ||
| | UnivQuantVariables [Strict] Type | |||
| | [Strict] [UnqTypeAttrib] (UnivQuantVariables Type) |
SynonymTypeDef | = | ::TypeLhs :== Type ; |
AbstractTypeDef | = | :: [!][UnqOrCoercibleTypeAttrib] TypeConstructor {[*]TypeVariable}; | ||
UnqOrCoercibleTypeAttrib | = | * | ||
| | . |
AbstractSynonymTypeDef | = | AbstractTypeDef (:== Type ) ; |
ExtensibleAlgebraicTypeDef | = | ::TypeLhs = {ConstructorDef |} ..; |
AlgebraicTypeDefExtension | = | ::TypeLhs | ConstructorDef {| ConstructorDef} ; |
NewTypeDef | = | ::TypeLhs =: ConstructorName SimpleType ; |
SimpleType | = | TypeVariable | // see A.9 | |||
| | QTypeName | |||||
| | (Type) | |||||
| | PredefinedType | |||||
| | PredefinedTypeConstructor |
PredefinedType | = | BasicType | ||
| | ListType | |||
| | TupleType | |||
| | ArrayType | |||
| | ArrowType | |||
| | PredefType |
BasicType | = | Int | ||
| | Real | |||
| | Char | |||
| | Bool |
ListType | = | [[ListTypeKind] Type [SpineStrictness]] | ||||
ListTypeKind | = | ! | // head strict list | |||
| | # | // head strict, unboxed list |
TupleType | = | ([Strict] Type,{[Strict] Type}-list) |
ArrayType | = | {[ArrayKind] Type} | ||||
ArrayKind | = | ! | // strict array | |||
| | # | // unboxed array |
PredefType | = | World | // see StdWorld.dcl | |||
| | File | // see StdFileIO.dcl | ||||
| | String | // synonym for {#Char} | ||||
| | () | // unit type constructor |
PredefinedTypeConstructor | = | [] | // list type constructor | |||
| | [! ] | // head strict list type constructor | ||||
| | [ !] | // tail strict list type constructor | ||||
| | [!!] | // strict list type constructor | ||||
| | [#] | // unboxed head strict list type | ||||
| | [#!] | // unboxed strict list type | ||||
| | ({,}+) | // tuple type constructor (arity >= 2) | ||||
| | {} | // lazy array type constructor | ||||
| | {!} | // strict array type constructor | ||||
| | {#} | // unboxed array type constructor | ||||
| | (->) | // arrow type constructor |
ClassDef | = | TypeClassDef | ||
| | TypeClassInstanceDef |
TypeClassDef | = | class ClassName {[.]TypeVariable}+ [ClassContext] | ||
[[where] { {ClassMemberDef}+ }] ; | ||||
| | class FunctionName {[.]TypeVariable}+ :: FunctionType; | |||
| | class (FunctionName) [FixPrec] {[.]TypeVariable}+ :: FunctionType; |
ClassMemberDef | = | FunctionTypeDef | ||
[MacroDef] |
TypeClassInstanceDef | = | instance QClassName Type+ [ClassContext] | ||
[where] { {FunctionDef}+ } ; |
ClassExportDef | = | TypeClassDef | ||
| | TypeClassInstanceExportDef |
TypeClassInstanceExportDef | = | instance ClassName InstanceExportTypes ; | ||
InstanceExportTypes | = | {Type+ [ClassContext]}-list | ||
| | Type+ [ClassContext] [where] {{FunctionTypeDef}+ } | |||
| | Type+ [ClassContext] [Special] | |||
Special | = | special {{TypeVariable = Type}-list { ; {TypeVariable = Type}-list }} |
GenericsDef | = | GenericDef ; | ||
| | GenericCase; | |||
| | DeriveDef ; |
GenericDef | = | generic FunctionName TypeVariable+ [GenericDependencies] :: FunctionType | ||
GenericDependencies | = | | {FunctionName TypeVariable+ }-list |
GenericCase | = | FunctionName {|GenericTypeArg|} {Pattern}+ = FunctionBody | ||
GenericTypeArg | = | GenericMarkerType [of Pattern] | ||
| | TypeName | |||
| | TypeVariable | |||
GenericMarkerType | = | CONS | ||
| | OBJECT | |||
| | RECORD | |||
| | FIELD |
DeriveDef | = | derive FunctionName {DerivableType}-list | ||
| | derive class ClassName {DerivableType}-list | |||
DerivableType | = | TypeName | ||
| | PredefinedTypeConstructor |
GenericAppExpression | = | FunctionName {|TypeKind|} GraphExpr | ||
TypeKind | = | * | ||
| | TypeKind -> TypeKind | |||
| | IntDenotation | |||
| | (TypeKind) | |||
| | {|TypeKind|} |
GenericExportDef | = | GenericDef ; | ||
| | derive FunctionName {DeriveExportType [UsedGenericDependencies]}-list ; | |||
| | derive class ClassName {DerivableType}-list ; | |||
| | FunctionName {|GenericExportTypeArg|} {Pattern}+ = FunctionBody |
DeriveExportType | = | TypeName | ||
| | GenericMarkerType [of UsedGenericInfoFields] | |||
| | PredefinedTypeConstructor | |||
| | TypeVariable | |||
UsedGenericInfoFields | = | {[{FieldName}-list]} | ||
| | Variable |
UsedGenericDependencies | = | with {UsedGenericDependency} | ||
UsedGenericDependency | = | Variable | ||
| | _ |
GenericExportTypeArg | = | GenericMarkerType [of Pattern] | ||
| | UNIT | PAIR | EITHER |
ForeignExportDef | = | foreign export [ ccall | stdcall ] FunctionName ; |
ModuleName | = | LowerCaseId | | | UpperCaseId | | | ModuleDirectoryName . ModuleName | ||||||
ModuleDirectoryName | = | LowerCaseId | | | UpperCaseId | ||||||||
FunctionName | = | LowerCaseId | | | UpperCaseId | | | SymbolId | ||||||
ConstructorName | = | UpperCaseId | | | SymbolId | ||||||||
SelectorVariable | = | LowerCaseId | ||||||||||
Variable | = | LowerCaseId | ||||||||||
MacroName | = | LowerCaseId | | | UpperCaseId | | | SymbolId | ||||||
FieldName | = | LowerCaseId | ||||||||||
TypeName | = | UpperCaseId | | | SymbolId | ||||||||
TypeVariable | = | LowerCaseId | ||||||||||
UniqueTypeVariable | = | LowerCaseId | ||||||||||
ClassName | = | LowerCaseId | | | UpperCaseId | | | SymbolId | ||||||
MemberName | = | LowerCaseId | | | UpperCaseId | | | SymbolId |
QFunctionName | = | QLowerCaseId | | | QUpperCaseId | | | QSymbolId | ||||||
QConstructorName | = | QUpperCaseId | | | QSymbolId | ||||||||
QTypeName | = | QUpperCaseId | | | QSymbolId | ||||||||
QClassName | = | QLowerCaseId | | | QUpperCaseId | | | QSymbolId |