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