EBNF (The GNU Modula-2 Compiler)

## 3 EBNF of GNU Modula-2 ¶

This chapter contains the EBNF of GNU Modula-2. This grammar currently supports both PIM and ISO dialects. The rules here are automatically extracted from the crammer files in GNU Modula-2 and serve to document the syntax of the extensions described earlier and how they fit in with the base language.

Note that the first six productions are built into the lexical analysis phase.

    Ident := is a builtin and checks for an identifier
           =:

    Integer := is a builtin and checks for an integer
             =:

    Real := is a builtin and checks for an real constant
          =:

    string := is a builtin and checks for an string constant
            =:

    FileUnit := ( DefinitionModule  |
                  ImplementationOrProgramModule  )
              =:

    ProgramModule := 'MODULE' Ident [ Priority  ] ';' {
       Import  } Block Ident '.'
                   =:

    ImplementationModule := 'IMPLEMENTATION' 'MODULE' Ident
                            [ Priority  ] ';' { Import
                                                  } Block
                            Ident '.'
                          =:

    ImplementationOrProgramModule := ImplementationModule  |
                                     ProgramModule
                                   =:

    Number := Integer  | Real
            =:

    Qualident := Ident { '.' Ident  }
               =:

    ConstantDeclaration := Ident '=' ConstExpression
                         =:

    ConstExpression := SimpleConstExpr [ Relation SimpleConstExpr  ]
                     =:

    Relation := '='  | '#'  | '<>'  | '<'  | '<='  |
                '>'  | '>='  | 'IN'
              =:

    SimpleConstExpr := UnaryOrConstTerm { AddOperator
                                           ConstTerm  }
                     =:

    UnaryOrConstTerm := '+' ConstTerm  |
                        '-' ConstTerm  |
                        ConstTerm
                      =:

    AddOperator := '+'  | '-'  | 'OR'
                 =:

    ConstTerm := ConstFactor { MulOperator ConstFactor  }
               =:

    MulOperator := '*'  | '/'  | 'DIV'  | 'MOD'  |
                   'REM'  | 'AND'  | '&'
                 =:

    ConstFactor := Number  | ConstString  |
                   ConstSetOrQualidentOrFunction  |
                   '(' ConstExpression ')'  |
                   'NOT' ConstFactor  |
                   ConstAttribute
                 =:

    ConstString := string
                 =:

    ComponentElement := ConstExpression [ '..' ConstExpression  ]
                      =:

    ComponentValue := ComponentElement [ 'BY' ConstExpression  ]
                    =:

    ArraySetRecordValue := ComponentValue { ',' ComponentValue  }
                         =:

    Constructor := '{' [ ArraySetRecordValue  ] '}'
                 =:

    ConstSetOrQualidentOrFunction := Constructor  |
                                     Qualident [ Constructor  |
                                                 ConstActualParameters  ]
                                   =:

    ConstActualParameters := '(' [ ExpList  ] ')'
                           =:

    ConstAttribute := '__ATTRIBUTE__' '__BUILTIN__' '('
                      '(' ConstAttributeExpression ')'
                      ')'
                    =:

    ConstAttributeExpression := Ident  | '<' Qualident
                                ',' Ident '>'
                              =:

    ByteAlignment := '<*' AttributeExpression '*>'
                   =:

    Alignment := [ ByteAlignment  ]
               =:

    TypeDeclaration := Ident '=' Type Alignment
                     =:

    Type := SimpleType  | ArrayType  | RecordType  |
            SetType  | PointerType  | ProcedureType
          =:

    SimpleType := Qualident [ SubrangeType  ]  |
                  Enumeration  | SubrangeType
                =:

    Enumeration := '(' IdentList ')'
                 =:

    IdentList := Ident { ',' Ident  }
               =:

    SubrangeType := '[' ConstExpression '..' ConstExpression
                    ']'
                  =:

    ArrayType := 'ARRAY' SimpleType { ',' SimpleType  }
                 'OF' Type
               =:

    RecordType := 'RECORD' [ DefaultRecordAttributes  ]
                  FieldListSequence 'END'
                =:

    DefaultRecordAttributes := '<*' AttributeExpression
                               '*>'
                             =:

    RecordFieldPragma := [ '<*' FieldPragmaExpression {
       ',' FieldPragmaExpression  } '*>'  ]
                       =:

    FieldPragmaExpression := Ident [ '(' ConstExpression
                                     ')'  ]
                           =:

    AttributeExpression := Ident '(' ConstExpression ')'
                         =:

    FieldListSequence := FieldListStatement { ';' FieldListStatement  }
                       =:

    FieldListStatement := [ FieldList  ]
                        =:

    FieldList := IdentList ':' Type RecordFieldPragma  |
                 'CASE' CaseTag 'OF' Varient { '|' Varient  }
                 [ 'ELSE' FieldListSequence  ] 'END'
               =:

    TagIdent := [ Ident  ]
              =:

    CaseTag := TagIdent [ ':' Qualident  ]
             =:

    Varient := [ VarientCaseLabelList ':' FieldListSequence  ]
             =:

    VarientCaseLabelList := VarientCaseLabels { ',' VarientCaseLabels  }
                          =:

    VarientCaseLabels := ConstExpression [ '..' ConstExpression  ]
                       =:

    CaseLabelList := CaseLabels { ',' CaseLabels  }
                   =:

    CaseLabels := ConstExpression [ '..' ConstExpression  ]
                =:

    SetType := ( 'SET'  | 'PACKEDSET'  ) 'OF' SimpleType
             =:

    PointerType := 'POINTER' 'TO' Type
                 =:

    ProcedureType := 'PROCEDURE' [ FormalTypeList  ]
                   =:

    FormalTypeList := '(' ( ')' FormalReturn  |
                            ProcedureParameters ')' FormalReturn  )
                    =:

    FormalReturn := [ ':' OptReturnType  ]
                  =:

    OptReturnType := '[' Qualident ']'  |
                     Qualident
                   =:

    ProcedureParameters := ProcedureParameter { ',' ProcedureParameter  }
                         =:

    ProcedureParameter := '...'  | 'VAR' FormalType  |
                          FormalType
                        =:

    VarIdent := Ident [ '[' ConstExpression ']'  ]
              =:

    VariableDeclaration := VarIdentList ':' Type Alignment
                         =:

    VarIdentList := VarIdent { ',' VarIdent  }
                  =:

    Designator := Qualident { SubDesignator  }
                =:

    SubDesignator := '.' Ident  | '[' ExpList ']'  |
                     '^'
                   =:

    ExpList := Expression { ',' Expression  }
             =:

    Expression := SimpleExpression [ Relation SimpleExpression  ]
                =:

    SimpleExpression := [ '+'  | '-'  ] Term { AddOperator
                                                Term  }
                      =:

    Term := Factor { MulOperator Factor  }
          =:

    Factor := Number  | string  | SetOrDesignatorOrFunction  |
              '(' Expression ')'  |
              'NOT' Factor  | ConstAttribute
            =:

    SetOrDesignatorOrFunction := ( Qualident [ Constructor  |
                                               SimpleDes
                                               [ ActualParameters  ]  ]  |
                                   Constructor  )
                               =:

    SimpleDes := { '.' Ident  | '[' ExpList ']'  |
                    '^'  }
               =:

    ActualParameters := '(' [ ExpList  ] ')'
                      =:

    Statement := [ AssignmentOrProcedureCall  |
                   IfStatement  | CaseStatement  |
                   WhileStatement  | RepeatStatement  |
                   LoopStatement  | ForStatement  |
                   WithStatement  | AsmStatement  |
                   'EXIT'  | 'RETURN' [ Expression  ]  |
                   RetryStatement  ]
               =:

    RetryStatement := 'RETRY'
                    =:

    AssignmentOrProcedureCall := Designator ( ':=' Expression  |
                                              ActualParameters  |
                                               )
                               =:

    StatementSequence := Statement { ';' Statement  }
                       =:

    IfStatement := 'IF' Expression 'THEN' StatementSequence
                   { 'ELSIF' Expression 'THEN' StatementSequence  }
                   [ 'ELSE' StatementSequence  ] 'END'
                 =:

    CaseStatement := 'CASE' Expression 'OF' Case { '|'
                                                    Case  }
                     [ 'ELSE' StatementSequence  ] 'END'
                   =:

    Case := [ CaseLabelList ':' StatementSequence  ]
          =:

    WhileStatement := 'WHILE' Expression 'DO' StatementSequence
                      'END'
                    =:

    RepeatStatement := 'REPEAT' StatementSequence 'UNTIL'
                       Expression
                     =:

    ForStatement := 'FOR' Ident ':=' Expression 'TO' Expression
                    [ 'BY' ConstExpression  ] 'DO' StatementSequence
                    'END'
                  =:

    LoopStatement := 'LOOP' StatementSequence 'END'
                   =:

    WithStatement := 'WITH' Designator 'DO' StatementSequence
                     'END'
                   =:

    ProcedureDeclaration := ProcedureHeading ';' ( ProcedureBlock
                                                   Ident
                                                    )
                          =:

    DefineBuiltinProcedure := [ '__ATTRIBUTE__' '__BUILTIN__'
                                '(' '(' Ident ')' ')'  |
                                '__INLINE__'  ]
                            =:

    ProcedureHeading := 'PROCEDURE' DefineBuiltinProcedure
                        ( Ident [ FormalParameters  ] AttributeNoReturn  )
                      =:

    AttributeNoReturn := [ '<*' Ident '*>'  ]
                       =:

    AttributeUnused := [ '<*' Ident '*>'  ]
                     =:

    Builtin := [ '__BUILTIN__'  | '__INLINE__'  ]
             =:

    DefProcedureHeading := 'PROCEDURE' Builtin ( Ident
                                                 [ DefFormalParameters  ]
                                                 AttributeNoReturn  )

                         =:

    ProcedureBlock := { Declaration  } [ 'BEGIN' BlockBody  ]
                      'END'
                    =:

    Block := { Declaration  } InitialBlock FinalBlock
             'END'
           =:

    InitialBlock := [ 'BEGIN' BlockBody  ]
                  =:

    FinalBlock := [ 'FINALLY' BlockBody  ]
                =:

    BlockBody := NormalPart [ 'EXCEPT' ExceptionalPart  ]
               =:

    NormalPart := StatementSequence
                =:

    ExceptionalPart := StatementSequence
                     =:

    Declaration := 'CONST' { ConstantDeclaration ';'  }  |
                   'TYPE' { TypeDeclaration ';'  }  |
                   'VAR' { VariableDeclaration ';'  }  |
                   ProcedureDeclaration ';'  |
                   ModuleDeclaration ';'
                 =:

    DefFormalParameters := '(' [ DefMultiFPSection  ] ')'
                           FormalReturn
                         =:

    DefMultiFPSection := DefExtendedFP  |
                         FPSection [ ';' DefMultiFPSection  ]
                       =:

    FormalParameters := '(' [ MultiFPSection  ] ')' FormalReturn
                      =:

    MultiFPSection := ExtendedFP  | FPSection [ ';' MultiFPSection  ]
                    =:

    FPSection := NonVarFPSection  | VarFPSection
               =:

    DefExtendedFP := DefOptArg  | '...'
                   =:

    ExtendedFP := OptArg  | '...'
                =:

    VarFPSection := 'VAR' IdentList ':' FormalType [ AttributeUnused  ]
                  =:

    NonVarFPSection := IdentList ':' FormalType [ AttributeUnused  ]
                     =:

    OptArg := '[' Ident ':' FormalType [ '=' ConstExpression  ]
              ']'
            =:

    DefOptArg := '[' Ident ':' FormalType '=' ConstExpression
                 ']'
               =:

    FormalType := { 'ARRAY' 'OF'  } Qualident
                =:

    ModuleDeclaration := 'MODULE' Ident [ Priority  ] ';'
                         { Import  } [ Export  ] Block
                         Ident
                       =:

    Priority := '[' ConstExpression ']'
              =:

    Export := 'EXPORT' ( 'QUALIFIED' IdentList  |
                         'UNQUALIFIED' IdentList  |
                         IdentList  ) ';'
            =:

    Import := 'FROM' Ident 'IMPORT' IdentList ';'  |
              'IMPORT' IdentList ';'
            =:

    DefinitionModule := 'DEFINITION' 'MODULE' [ 'FOR' string
                                                 ] Ident
                        ';' { Import  } [ Export  ] {
       Definition  } 'END' Ident '.'
                      =:

    Definition := 'CONST' { ConstantDeclaration ';'  }  |
                  'TYPE' { Ident ( ';'  | '=' Type Alignment
                                    ';'  )  }  |
                  'VAR' { VariableDeclaration ';'  }  |
                  DefProcedureHeading ';'
                =:

    AsmStatement := 'ASM' [ 'VOLATILE'  ] '(' AsmOperands
                    ')'
                  =:

    NamedOperand := '[' Ident ']'
                  =:

    AsmOperandName := [ NamedOperand  ]
                    =:

    AsmOperands := string [ ':' AsmList [ ':' AsmList [
       ':' TrashList  ]  ]  ]
                 =:

    AsmList := [ AsmElement  ] { ',' AsmElement  }
             =:

    AsmElement := AsmOperandName string '(' Expression
                  ')'
                =:

    TrashList := [ string  ] { ',' string  }
               =: