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
=:
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'
=:
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 }
=: