namespace Awtl.Modula.Grammar { syntax module Modula { using PrettyPrint; using Outline; using TokenNames; using StandardSpanClasses; using Whitespaces; using Identifiers; [StartRule] syntax CompilationModule { | ProgramModule | DefinitionModule | ImplementationModule } syntax ModuleIdentifier = Identifier; syntax ProgramModule = "MODULE" ModuleIdentifier InterruptProtection? ";" ImportLists ModuleBlock ModuleIdentifier "."; syntax DefinitionModule = "DEFINITION" "MODULE" ModuleIdentifier ";" ImportLists Definitions "END" ModuleIdentifier "."; syntax ImplementationModule = "IMPLEMENTATION" "MODULE" ModuleIdentifier InterruptProtection? ";" ImportLists ModuleBlock ModuleIdentifier "."; syntax InterruptProtection = "{" ProtectionExpression "}"; syntax ProtectionExpression = ConstantExpression; syntax ModuleBlock = Declarations ModuleBody? "END"; syntax ModuleBody = InitializationBody FinalizationBody?; syntax InitializationBody = "BEGIN" BlockBody; syntax FinalizationBody = "FINALLY" BlockBody; syntax BlockBody = NormalPart ("EXCEPT" ExceptionalPart)?; syntax NormalPart = StatementSequence; syntax ExceptionalPart = StatementSequence; syntax ImportLists = ImportList*; syntax ImportList { | SimpleImport = "IMPORT" IdentifierList ";"; | UnqualifiedImport = "FROM" ModuleIdentifier "IMPORT" IdentifierList ";"; } syntax ExportList { | UnqualifiedExport = "EXPORT" IdentifierList ";"; | QualifiedExport = "EXPORT" "QUALIFIED" IdentifierList ";"; } syntax QualifiedIdentifier = ( QualifyingIdentifier "." )* Identifier; syntax QualifyingIdentifier = ModuleIdentifier; syntax Definitions = ( Definition )*; syntax Definition { | ConstantDeclarations = "CONST" ( ConstantDeclaration ";" )* | TypeDefinitions = "TYPE" ( TypeDefinition ";" )* | VariableDeclarations = "VAR" ( VariableDeclaration ";" )* | ProcedureHeading = ProcedureHeading ";" } syntax ProcedureHeading { | ProperProcedureHeading = ProperProcedureHeading | FunctionProcedureHeading = FunctionProcedureHeading } syntax TypeDefinition { | TypeDeclaration | OpaqueTypeDefinition } syntax OpaqueTypeDefinition = Identifier ; syntax Declarations = ( Declaration )*; syntax Declaration { | ConstantDeclarations = "CONST" ( ConstantDeclaration ";" )* | TypeDefinitions = "TYPE" ( TypeDefinition ";" )* | VariableDeclarations = "VAR" ( VariableDeclaration ";" )* | ProcedureHeading = ProcedureHeading ";" | LocalModuleDeclaration = LocalModuleDeclaration ";" } syntax ConstantDeclaration = Identifier "=" ConstantExpression; syntax TypeDeclaration = Identifier "=" TypeDenoter; syntax VariableDeclaration = VariableIdentifierList ":" TypeDenoter; syntax VariableIdentifierList = Identifier MachineAddress? ( "," Identifier MachineAddress? )*; syntax MachineAddress = "{" ValueOfAddressType "}"; syntax ValueOfAddressType = ConstantExpression; syntax ProcedureDeclaration { | ProperProcedureDeclaration | FunctionProcedureDeclaration | ForwardProperProcedureDeclaration | ForwardFunctionProcedureDeclaration } syntax ProperProcedureDeclaration = ProperProcedureHeading ";" ProperProcedureBlock ProcedureIdentifier; syntax FunctionProcedureDeclaration = FunctionProcedureHeading ";" FunctionProcedureBlock ProcedureIdentifier; syntax ForwardProperProcedureDeclaration = ProperProcedureHeading ";" "FORWARD"; syntax ForwardFunctionProcedureDeclaration = FunctionProcedureHeading ";" "FORWARD"; syntax ProcedureIdentifier = Identifier; syntax ProperProcedureHeading = "PROCEDURE" ProcedureIdentifier FormalParameters?; syntax FormalParameters = "(" FormalParameterList? ")"; syntax FormalParameterList = FormalParameter ( ";" FormalParameter )*; syntax ProperProcedureBlock = Declarations ProcedureBody? "END"; syntax ProcedureBody = "BEGIN" BlockBody; syntax FunctionProcedureHeading = "PROCEDURE" ProcedureIdentifier FormalParameters ":" FunctionResultType; syntax FunctionResultType = TypeIdentifier; syntax FunctionProcedureBlock = Declarations FunctionBody "END"; syntax FunctionBody = "BEGIN" BlockBody; syntax FormalParameter { | ValueParameterSpecification | VariableParameterSpecification } syntax ValueParameterSpecification = IdentifierList ":" FormalType; syntax VariableParameterSpecification = "VAR" IdentifierList ":" FormalType; syntax LocalModuleDeclaration = "MODULE" ModuleIdentifier InterruptProtection? ";" ImportLists ExportList? ModuleBlock ModuleIdentifier; syntax TypeDenoter { | TypeIdentifier | NewType } syntax OrdinalTypeDenoter { | OrdinalTypeIdentifier | NewOrdinalType } syntax TypeIdentifier = QualifiedIdentifier; syntax OrdinalTypeIdentifier = TypeIdentifier; syntax NewType { | NewOrdinalType | SetType | PackedSetType | PointerType | ProcedureType | ArrayType | RecordType } syntax NewOrdinalType { | EnumerationType | SubrangeType } syntax EnumerationType = "(" IdentifierList ")"; syntax IdentifierList = Identifier ( "," Identifier )*; syntax SubrangeType = RangeType? "{" ConstantExpression ".." ConstantExpression "}"; syntax RangeType = OrdinalTypeIdentifier; syntax SetType = "SET" "OF" BaseType; syntax BaseType = OrdinalTypeDenoter; syntax PackedSetType = "PACKEDSET" "OF" BaseType; syntax PointerType = "POINTER" "TO" BoundType; syntax BoundType = TypeDenoter; syntax ProcedureType { | ProperProcedureType | FunctionProcedureType } syntax ProperProcedureType = "PROCEDURE" ( "(" FormalParameterTypeList? ")" )? ; syntax FunctionProcedureType = "PROCEDURE" "(" FormalParameterTypeList? ")" ":" FunctionResultType ; syntax FormalParameterTypeList = FormalParameterType ( "," FormalParameterType )* ; syntax FormalParameterType { | VariableFormalType | ValueFormalType } syntax VariableFormalType = "VAR" FormalType; syntax ValueFormalType = FormalType; syntax FormalType { | TypeIdentifier | OpenArrayFormalType } syntax OpenArrayFormalType = "ARRAY" "OF" OpenArrayComponentType; syntax OpenArrayComponentType = FormalType; syntax ArrayType = "ARRAY" IndexType ( "," IndexType )* "OF" ComponentType; syntax IndexType = OrdinalTypeDenoter; syntax ComponentType = TypeDenoter; syntax RecordType = "RECORD" FieldList "END"; syntax FieldList = Fields? ( ";" Fields? )*; syntax Fields { | FixedFields | VariantFields } syntax FixedFields = IdentifierList ":" FieldType; syntax FieldType = TypeDenoter; syntax VariantFields = "CASE" TagField "OF" VariantList "END"; syntax TagField = TagIdentifier? ":" TagType; syntax TagIdentifier = Identifier; syntax TagType = OrdinalTypeIdentifier; syntax VariantList = Variant ( CaseSeparator Variant )* VariantElsePart?; syntax VariantElsePart = "ELSE" FieldList; syntax Variant = ( VariantLabelList ":" FieldList )?; syntax VariantLabelList = VariantLabel ( "," VariantLabel )*; syntax VariantLabel = ConstantExpression ( ".." ConstantExpression )?; syntax Statement { | EmptyStatement | AssignmentStatement | ProcedureCall | ReturnStatement | RetryStatement | WithStatement | IfStatement | CaseStatement | WhileStatement | RepeatStatement | LoopStatement | ExitStatement | ForStatement } syntax StatementSequence = Statement ( ";" Statement )*; syntax EmptyStatement = ; syntax AssignmentStatement = VariableDesignator "=" Expression; syntax ProcedureCall = ProcedureDesignator ActualParameters?; syntax ProcedureDesignator = ValueDesignator; syntax ActualParameters = "(" ActualParameterList? ")"; syntax ActualParameterList = ActualParameter ( "," ActualParameter )* ; syntax ActualParameter { | VariableDesignator | Expression | TypeParameter } syntax TypeParameter = TypeIdentifier; syntax ReturnStatement { | SimpleReturnStatement | FunctionReturnStatement } syntax SimpleReturnStatement = "RETURN"; syntax FunctionReturnStatement = "RETURN" Expression; syntax RetryStatement = "RETRY"; syntax WithStatement = "WITH" RecordDesignator "DO" StatementSequence "END"; syntax RecordDesignator { | VariableDesignator | ValueDesignator } syntax IfStatement = GuardedStatements IfElsePart? "END"; syntax GuardedStatements = "IF" BooleanExpression "THEN" StatementSequence ( "ELSIF" BooleanExpression "THEN" StatementSequence )*; syntax IfElsePart = "ELSE" StatementSequence; syntax BooleanExpression = Expression; syntax CaseStatement = "CASE" CaseSelector "OF" CaseList "END"; syntax CaseSelector = OrdinalExpression; syntax CaseList = CaseAlternative ( CaseSeparator CaseAlternative )* CaseElsePart?; syntax CaseElsePart = "ELSE" StatementSequence; syntax CaseAlternative = (CaseLabelList ":" StatementSequence)?; syntax CaseLabelList = CaseLabel ( "," CaseLabel )*; syntax CaseLabel = ConstantExpression ( ".." ConstantExpression )*; syntax WhileStatement = "WHILE" BooleanExpression "DO" StatementSequence "END"; syntax RepeatStatement = "REPEAT" StatementSequence "UNTIL" BooleanExpression; syntax LoopStatement = "LOOP" StatementSequence "END"; syntax ExitStatement = "EXIT"; syntax ForStatement = "FOR" ControlVariableIdentifier "=" InitialValue "TO" FinalValue ( "BY" StepSize)? "DO" StatementSequence "END"; syntax ControlVariableIdentifier = Identifier; syntax InitialValue = OrdinalExpression; syntax FinalValue = OrdinalExpression; syntax StepSize = ConstantExpression; syntax VariableDesignator = EntireDesignator | IndexedDesignator | SelectedDesignator | DereferencedDesignator ; syntax EntireDesignator = QualifiedIdentifier ; syntax IndexedDesignator = ArrayVariableDesignator, "{", IndexExpression, { ",", IndexExpression }, "}" ; syntax ArrayVariableDesignator = VariableDesignator ; syntax IndexExpression = OrdinalExpression ; syntax SelectedDesignator = RecordVariableDesignator, ".", FieldIdentifier ; syntax RecordVariableDesignator = VariableDesignator ; syntax FieldIdentifier = Identifier ; syntax DereferencedDesignator = PointerVariableDesignator, DereferencingOperator ; syntax PointerVariableDesignator = VariableDesignator ; expression = simple expression, [relational operator, simple expression] ; simple expression = [sign], term, { term operator, term } ; term = factor, { factor operator, factor } ; factor = "(", expression, ")" | logical negation operator, factor | value designator | function call | value constructor | constant literal ; relational operator = "=" operator | inequality operator | less than operator | greater than operator | less than or equal operator | subset operator | greater than or equal operator | superset operator | set membership operator ; term operator = plus operator | set union operator | minus operator | set difference operator | logical disjunction operator | string catenate symbol ; factor operator = multiplication operator | set intersection operator | division operator | symmetric set difference operator | rem operator | div operator | mod operator | logical conjunction operator ; value designator = entire value | indexed value | selected value | dereferenced value ; entire value = QualifiedIdentifier ; indexed value = array value, "{", index expression, { ",", index expression }, "}" ; array value = value designator ; selected value = record value, ".", field identifier ; record value = value designator ; dereferenced value = pointer value, dereferencing operator ; pointer value = value designator ; function call = function designator, actual parameters ; function designator = value designator ; value constructor = array constructor | record constructor | set constructor ; array constructor = ArrayTypeIdentifier, array constructed value ; ArrayTypeIdentifier = TypeIdentifier ; array constructed value = left brace, repeated structure component, { ",", repeated structure component }, right brace ; repeated structure component = structure component, ["BY", repetition factor] ; repetition factor = ConstantExpression ; structure component = expression | array constructed value | record constructed value | set constructed value ; record constructor = RecordTypeIdentifier, record constructed value ; RecordTypeIdentifier = TypeIdentifier ; record constructed value = left brace, [structure component, { ",", structure component }], right brace ; set constructor = SetTypeIdentifier, set constructed value ; SetTypeIdentifier = TypeIdentifier ; set constructed value = left brace, [member, { ",", member }], right brace ; member = interval | singleton ; interval = ordinal expression, "..", ordinal expression ; singleton = ordinal expression ; constant literal = whole number literal | real literal | string literal ; ordinal expression = expression ; ConstantExpression = expression ; } }