EBNF
From The Oxygene Language Wiki
Contents |
Notes
- While parsing, Whitespace and Comments tokens are ignored.
- All keywords and identifiers are case-insensitive, but declarations are case-preserving.
- Also see the Oxygene Grammar.
Syntax - General
CodeFile = { XmlDocOrAttribute }, Namespace, [ InterfaceSection ], ImplementationSection, "END", Dot ;
Namespace = "NAMESPACE", [ Identifier, { Dot, Identifier } ], Semicolon ;
InterfaceSection = "INTERFACE", [ Uses ], { InterfaceSectionEntry } ;
ImplementationSection = "IMPLEMENTATION", [ Uses ], { ImplementationSectionEntry } [ MainBegin ];
Uses = "USES", UsesEntry, { Comma, UsesEntry } ;
UsesEntry = Identifier, { Dot, Identifier }, [ Dot, Star ] ;
XmlDocOrAttribute = { XmlDocComment | AttributeSection } ;
AttributeSection = OpenBlock, Attribute, { Comma, Attribute }, CloseBlock;
Attribute = [ ("global" | "module" | "assembly"), Colon ] TypeReference, [ Arguments ] ;
Arguments = OpenParenthesis, [ Argument, { Comma', Argument } ] ;
Argument = [ "out" | "var" ] [ Identifier, Assign ], Expression ;
InterfaceSectionEntry = [XmlDocOrAttribute], (TypeBlock, VarBlock, ConstBlock, MethodDefinition) ;
ImplementationSectionEntry = [XmlDocOrAttribute], (TypeBlock, VarBlock, ConstBlock, MethodImplementation) ;
MainBegin = "BEGIN", { Statement } ;
TypeBlock = "TYPE", TypeBlockEntry, { TypeBlockEntry } ;
ConstBlock = "CONST", ConstBlockEntry, { ConstBlockEntry } ;
VarBlock = "VAR", VarBlockEntry, { VarBlockEntry } ;
TypeBlockEntry = XmlDocOrAttribute, Identifier, { ".", Identifier }, ["NESTED", "IN", TypeReference], Equal, [AccessModifier], FullTypeReference, SemiColon;
VarBlockEntry = XmlDocOrAttribute, Identifier, [ Colon, TypeReference ], [ Assign, Expression ], SemiColon, { VarBlockEntryModifier, SemiColon };
VarBlockEntryModifier = "ASSEMBLY" | "PUBLIC" | "READONLY" | "VOLATILE" | "IMPLEMENTS" | "PINNED" | "UNSAFE" ;
ConstBlockEntry = XmlDocOrAttribute, Identifier, [ Colon, TypeReference ], [ Equl, Expression ], SemiColon ;
AccessModifier = "ASSEMBLY", "OR", "PROTECTED" | "ASSEMBLY", "AND", "PROTECTED" | "PROTECTED" | "ASSEMBLY" | "PUBLIC" | "PRIVATE" ;
WhereBlock = "WHERE", WhereElement, { Comma, WhereElement } ;
WhereElement = Identifier, ( "HAS", "CONSTRUCTOR" | "IS", WhereIs ) ;
WhereIs = "RECORD" | "CLASS" | TypeReference ;
ParameterDefinitions = [ OpenParenthesis, [ ParameterDefinition, { SemiColon, ParameterDefinition }, CloseParenthesis ] ;
ParameterDefinition = XmlDocOrAttribute, [ "VAR" | "OUT" | "CONST" | "PARAMS" ], Identifier, { Comma', Identifier }, [ Colon, TypeReerence], [Assign, Expression] ;
MethodDefinition = XmlDocOrAttribute, MethodHeader, { SemiColon, MethodModifier }, SemiColon;
MethodModifier = "ASSEMBLY" | "PUBLIC" | "ITERATOR" | "UNSAFE" | "REINTRODUCE" | "VIRTUAL" | "ASYNC" | "OVERRIDE" | "FINAL" | "ABSTRACT" | "EXTERNAL" | "EMPTY" | "PARTIAL" | "DEPRECATED" | "INLINE" | "STATIC" | "STDCALL" | "CDECL" | "PASCAL" | "REGISTER" | "SAFECALL" | "OVERLOAD" | "LIBRARY" | "PLATFORM" | "LOCKED" "ON" Expression | "IMPLEMENTS", [ AccessModifier], Expression
MethodHeader = ( "EXTENSION", "METHOD" | "CONSTRUCTOR" | "FINALIZER" | "METHOD" | "FUNCTION" | "PROCEDURE" | "DELEGATE" | "OPERATOR" ), TypeReference, [Dot, Identifier], ParameterDefinitions, [ Colon, TypeReference ];
MethodImplementation = XmlDocOrAttribute, MethodHeader, SemiColon, { NestedMethodMember }, RequireOrBeginStatement
NestedMethodMember = ConstBlock | VarBlock | MethodImplementation
Syntax - Statements
Statement = BeginStatement | BreakStatement | ContinueStatement | CaseStatement | ExitStatement | YieldStatement | RaiseStatement | IfStatement | RepeatStatement | WhileStatement | LockingStatement | UsingStatement | WithStatement | ForInStatement | ForStatement | TryStatement | EmptyStatement | LoopStatement | AssignmentStatement ;
BeginStatement = "BEGIN", BlockStatement, "END" ;
'BlockStatement = Statement | VarStatement, { SemiColon, ( Statement | VarStatement) };
BreakStatement = "BREAK" ;
ContinueStatement = "CONTINUE" ;
ExitStatement = "EXIT", [Expression] ;
YieldStatement = "YIELD", Expression ;
RaiseStatement = "RAISE", [Expression] ;
IfStatement = "IF", Expression, "THEN", STATEMENT, [ "ELSE", Statement ] ;
RepeatStatement = "REPEAT", BlockStatement, "UNTIL", Expression;
WhileStatement = "WHILE", Expression, "DO", Statement;
LoopStatement = "LOOP", Statement ;
AssignmentStatement = Expression, [ (Assignment | PlusIs, MinusIs), Expression];
EmptyStatement = ;
VarStatement = "VAR", Identifier, {Comma, Identifier }, [Colon, TypeReference], [Assignment, Expression], [Semicolon, "PINNED"] ;
TryStatement = "TRY", BlockStatement, ( FinallyBlock, [ExceptBlock] | ExceptBlock, [FinallyBlock] ), "END" ;
FinallyBlock = "FINALLY", BlockStatement;
ExceptBlock = "EXCEPT", ( { ExceptElement } | Statement ) ;
ExceptElement = "ON", [Identifier, Colon], TypeReference, ["WHERE", Expression], "DO", Statement ;
RequireOrBeginStatement = [RequireBlock], ( EnsureBlock, BeginStatement | BeginWithEnsureStatement);
BeginWithEnsureStatement = "BEGIN", BlockStatement, EnsureBlock, "END" ;
RequireBlock = "REQUIRE", { InvariantEntry };
EnsureBlock = "ENSURE", { InvariantEntry };
CaseStatement = "CASE", Expression, ["TYPE"], "OF", CaseElement, { SemiColon, CaseElement }, [SemiColon], ["ELSE", BlockStatement], "END" ;
CaseElement = CaseRange, { Comma, CaseRange }, Colon, Statement;
CaseRange = Expression, [TwoDots, Expression] ;
LockingStatement = "LOCKING", [Identifier, [ Colon, TypeReference], Assignment], Expression, "DO", Statement ;
UsingStatement = "USING", [Identifier, [ Colon, TypeReference], Assignment], Expression, "DO", Statement ;
WithStatement = "WITH", WithElement, {Comma, WithElement}, "DO", Statement ;
WithElement = [ "MATCHING" ], [Identifier, [ Colon, TypeReference], Assignment], Expression, ["PINNED"] ;
ForInStatement = "FOR", ["PARALLEL"], ( LinqFromExpression | ["EACH"], ["MATCHING"], Identifier, [ Colon, TypeReference], "IN", Expression ), ["INDEX", Identifier, [Colon, TypeReference]], "DO", Statement;
ForStatement = "FOR", ["PARALLEL"], (Identifier, Colon, TypeReference | Expression), Assignment, Expression, ( "TO" | "DOWNTO" ), Expression, ["STEP", Expression], "DO", Statement;
Syntax - Expressions
Expression = ComparisonExpression;
ComparisonExpression = AdditionExpression, [ ( GreaterEqual | LessEqual | Greater | Less | NotEqual | "IN" | "NOT", "IN" | "IS" | "IMPLIES" ), AdditionExpression ] ;
AdditionExpression = MultiplicationExpression, [ ( Plus | Minus | "OR" | "XOR" ), MultiplicationExpression ] ;
MultiplicationExpression = ElementExpression, [ ( Multiply | Divide | "DIV" | "MOD" | "AND" | "SHL" | "SHR" | "AS" ), ElementExpression ];
ElementExpression = ( ForExpresion | ForInExpression | IfExpression | CaseExpression | LinqFromExpression | "OLD", Expression | "INHERITED", Expression | ArrayExpression | "NOT", Expression | Minus, Expression | Plus, Expression | "NIL" | AddressOf, Expression | OpenParenthesis, Expression, CloseParenthesis | LambdaExpression | Char | String | Integer | BinInt | HexInt | Float | NewExpression | "TRUE" | "FALSE" | "CONSTRUCTOR" | "CREATE" | "SELF" | "RESULT" | AnonymousMethodExpression | Identifier, ['GenericArguments] | CastExpression ? lowest priority ? ), { ElementRest };
ElementRest = CalllExpression | IdentifierSubExpression | ArrayElementExpression | Dereference;
CalllExpression = Arguments;
IdentifierSubExpression = ( Dot | Colon ), Identifier, [ GenericArguments ];
ArrayElementExpression, OpenBlock, Expression, { Comma, Expression }, CloseBlock;
LambdaExpression = ( Identifier | OpenParenthesis, [ Identifier, { Comma, Identifier } ] ), Lambda, (Expression | Statement);
CastExpression = TypeReference, OpenParenthesis, Expression, CloseParenthesis;
AnonymousMethodExpression = ( "METHOD" | "FUNCTION" | "PROCEDURE"), ParameterDefinitions, [ Colon, TypeReference ], [SemiColon], BeginStatement;
NewExpression = "NEW", Expression, [Arguments];
ArrayExpression = OpenBlock, [Expression, { Comma, Expression}], CloseBlock;
IfExpression = "IF", Expression, "THEN", Expression, ["ELSE", Expression];
ForExpresion = "FOR", Identifier, [Colon, TypeReference], Assignment, Expression, ( "TO" | "DOWNTO" ), Expression, ["STEP", Expression], "DO", Expression;
ForInExpression = "FOR", ["EACH"], ["MATCHING"], Identifier, [ Colon, TypeReference], "IN", Expression ), ["INDEX", Identifier, [Colon, TypeReference]], "DO", Expression;
FutureExpression = "FUTURE", Statement ? types have precedence ?
AsyncExpression = "ASYNC", ["FUTURE"], ( Statement | Expression );
CaseExpression = "CASE", Expression, ["TYPE"], "OF", CaseExpressionElement, { SemiColon, CaseExpressionElement }, [SemiColon], ["ELSE", Expression], "END"
CaseExpressionElement = CaseRange, { Comma, CaseRange }, Colon, Expression;
LinqFromExpression = "FROM", Identfier, [Colon, TypeReference], "IN", Expression, LinqFromElement, { LinqFromElement } ;
LinqFromElement = LinqJoin | LinqFrom | LinqWhere | LinqOrderBy | LinqSelect | LinqGroupBy | LinqSkip | LinqWith | LinqTake | "DISTINCT" | "REVERSE" ;
LinqJoin = "JOIN", Identifier, "IN", Expression, "ON", Expression, "EQUALS", Expression", ["INTO", Identifier];
LinqGroupBy = "GROUP", [Expression, ]BY, Expression, ["INTO", Identifier] ;
LinqOrderBy = "ORDER", "BY", LinqOrderElement, { Comma, LinqOrderElement };
LinqOrderElement = Expression, [ "ASC" | "DESC" ];
LinqWith = "WITH", Identifier, Assignment, Expression;
LinqFrom = "FROM", Identifier, [Colon, TypeReference], "IN", Expression;
LinqWhere = "WHERE", Expression;
LinqSelect = "SELECT", Expression, ["INTO", Identifier];
LinqSkip = "SKIP", ["WHILE"], Expression;
'LinqTake = "TAKE", ["WHILE"], Expression;
Syntax - Types
TypeReference = PointerTypeRference | "DYNAMIC" | IdentifierTypeReference | IntegerRangeReference | NullableTypeReference | SequenceTypeReference | SetTypeReference | ClassOfTypeReference | FutureTypeReference;
ClassOfTypeReference = "CLASS", "OF", TypeReference ;
NullableTypeReference = "NULLABLE", TypeReference ;
SequenceTypeReference = [ "PARALLEL" | "QUERYABLE" ], "SEQUENCE", "OF", TypeReference ;
SetTypeReference = "SET", "OF", TypeReference;
PointerTypeRference = Dereference, TypeReference;
FutureTypeReference = "FUTURE", [ TypeReference ];
IntegerRangeReference = Expression, TwoDots, Expression;
IdentifierTypeReference = Identifier, { Dot, Identifier }, [ GenericArguments ] ;
GenericArguments = LessThan, TypeReference, { Comma, TypeReference }, GreaterThan ;
ArrayReference = [ "INLINE" ], "ARRAY", [ ArrayRangeArguments ], "OF", TypeReference ;
ArrayRangeArguments = OpenBlock, ArrayRangeArgument, { Comma, ArrayRangeArgument}, CloseBlock;
ArrayRangeArgument = Expression, TwoDots, [Expression] ;
FullTypeReference = TypeReference | TypeDefition;
TypeDefinition = DelegateDefinition | EnumDefinition | ClassDefinition;
EnumDefinition = [ "ENUM" | "FLAGS" ] OpenParenthesis, EnumEntry, CloseParenthesis, [ "OF", TypeReference] ;
EnumEntry = Identifier, [ Equal, Expression];
DelegateDefinition = ( "METHOD" | "DELEGATE" | "FUNCTION" | "PROCEDURE" ), ParameterDefinitions, [ Colon, TypeReference], ["OF", "OBJECT"], [SemiColon, WhereBlock] ;
ClassDefinition = ( "CLASS" | "RECORD" | "INTERFACE" ), [OpenParenthesis, TypeReference, { Comma, TypeReference }, CloseParenthesis], ( SemiColon | ClassBody );
ClassBody = [WhereBlock], { ClassMember }, "END" ;
ClassMember = ["CLASS"], (MethodDefinition | PropertyDefinition | EventDefinition | VarBlock | ConstBlock | VarBlockEntry'), AccessModifier | InvariantBlock ;
InvariantBlock = ("PRIVATE" | "PUBLIC" ), [ "CLASS" ], "INVARIANTS", { InvariantEntry };
InvariantEntry = Expression, [ Colon, Expression ];
PropertyDefinition = "PROPERTY", Identifier, [ PropertyArguments ], Colon, TypeReference, PropertyAccessors, { SemiColon, PropertyModifiers }, {'
PropertyArguments = OpenBlock, { PropertyArgument }, CloseBlock ;
PropertyArgument, ["VAR" | "PARAMS" | "CONST" | "OUT"], Identifier, Colon, TypeReference ;
PropertyAccessors = "READ", [Expression] | "WRITE", [Expression] | [AccessModifier] "READ", [Expression] [AccessModifier] "WRITE", [Expression] | Assignment, Expression ;
PropertyModifiers = "UNSAFE" | "REINTRODUCE" | "VIRTUAL" | "OVERRIDE" | "FINAL" | "ABSTRACT" | "DEPRECATED" | "READONLY" | "LOCKED" "ON" Expression | "IMPLEMENTS", [ AccessModifier ], Expression ;
EventDefinition = "EVENT", Identifier, Colon, TypeReference, [ EventAccessors ], [ "RAISE", [ Expression ]], { SemiColon, EventModifiers } ;
EventAccessors = "ADD", [ Expression], "REMOVE", Expression | "DELEGATE", Expression ;
EventModifiers = "UNSAFE" | "REINTRODUCE" | "VIRTUAL" | "OVERRIDE" | "FINAL" | "ABSTRACT" | "DEPRECATED" | "LOCKED" "ON" Expression | "IMPLEMENTS", [ AccessModifier ], Expression ;
Tokens
Identifier = ( (IdentifierStart, { IdentifierRest } ) - GlobalKeywords ) | '&' IdentifierStart, { IdentifierRest } ;
StringIdentifier = SpecialIdentifierStart, { SpecialIdentifierCharacter | ( SpecialIdentifierEnd, SpecialIdentifierEnd ) }, SpecialIdentifierEnd ;
Char = '#', ( Integer | HexInt ) ;
Equal = "=" ;
NotEqual = "<>" ;
GreaterEqual = ">=" ;
Greater = ">" ;
GreaterEqual = "<=" ;
Greater = "<" ;
OpenParenthesis = "(" ;
CloseParenthesis = ")" ;
OpenBlock = "[" ;
CloseBlock = "]" ;
GlobalKeywords = "AND" | "AS" | "ASSEMBLY" | "ASYNC" | "BEGIN" | "BREAK" | "CASE" | "CLASS" | "CONST" | "CONSTRUCTOR" | "CONTINUE" | "CREATE" | "DELEGATE" | "DIV" | "DO" | "DOWNTO" | "DYNAMIC" | "EACH" | "ELSE" | "END" | "ENSURE" | "EVENT" | "EXCEPT" | "EXIT" | "FALSE" | "FINALIZER" | "FINALLY" | "FOR" | "FORWARD" | "FROM" | "FUNCTION" | "FUTURE" | "IF" | "IMPLEMENTATION" | "IN" | "INHERITED" | "INTERFACE" | "INVARIANTS" | "IS" | "LOCKING" | "LOOP" | "MATCHING" | "METHOD" | "MOD" | "MODULE" | "NAMESPACE" | "NEW" | "NIL" | "NOT" | "NULLABLE" | "OF" | "OLD" | "ON" | "OPERATOR" | "OR" | "OUT" | "PRIVATE" | "PROCEDURE" | "PROPERTY" | "PROTECTED" | "PUBLIC" | "RAISE" | "RECORD" | "REPEAT" | "REQUIRE" | "RESULT" | "SELF" | "SET" | "SHL" | "SHR" | "THEN" | "TO" | "TRUE" | "TRY" | "TYPE" | "UNIT" | "UNTIL" | "USES" | "USING" | "VAR" | "WHERE" | "WHILE" | "WITH" | "XOR" | "YIELD" (* Context insensitive keywords *) ;
BinInt = "%", NumberBase2, { NumberBase2 } ;
HexInt = "$", NumberBase16, { NumberBase16 } ;
Integer = NumberBase10, { NumberBase10 } ;
Dot = "." ;
Comma = "," ;
TwoDots = ".." ;
AddressOf = "@" ;
Dereference = "^" ;
Semicolon = ";" ;
Assign = ":=" ;
Colon = ":" ;
PlusIs = "+=" ;
MinusIs = "-=" ;
Plus = "+" ;
Minus = "-" ;
Star = "*" ;
Divide = "/" ;
LambdaStart = "->" ;
Float = ( NumberBase10 { NumberBase10 } [ "." NumberBase10 { NumberBase10 } ] [ ( "E" | "e" ), [ "-" ], NumberBase10, { NumberBase10 } ] ) | ( "." NumberBase10 { NumberBase10 } [ ( "E" | "e" ), [ "-" ], NumberBase10, { NumberBase10 } ] );
String = ( PascalStringStart, { PascalStringCharacter }, PascalStringStart ) | ( CStringStart, { CStringCharacter }, CStringStart ) ;
XmlDocComment = "///" , AnyCharacterButEnter;
Comment = ( "(*", AnyCharacter, "*)" ) | ( "{", AnyCharacter, "}" ) | ( "//", AnyCharacterButEnter );
Whitespace = Tab | Space | Enter ;
Chars
AnyCharacter = ? Any thing ? ;
PascalStringCharacter = AnyCharacter - PascalStringStart - EOF ;
CStringCharacter = AnyCharacter - CStringStart - EOF ;
PascalStringStart = "'" ; CStringStart = '"' ;
EOF = ? Unicode char 0 ? ;
UnicodeIdentifierStart = ? Unicode character > 127 excluding chr 160, chr 171 ? ;
IdentifierStart = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" | "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" | "_" | UnicodeIdentifierStart;
IdentifierRest = IdentifierStart | NumberBase10;
NumberBase16 = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "A" | "a" | "B" | "b" | "C" | "c" | "D" | "d" | "E" | "e" | "F" | "f";
NumberBase10 = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9";
NumberBase2 = "0" | "1";
SpecialIdentifierStart = "«";
SpecialIdentifierEnd = "»";
SpecialIdentifierCharacter = AnyCharacter - "»";
Enter = ? Chr 10 or 13 ? ;
Tab = ? Chr 9 ? ;
Space = ? Chr 32 or 160 ? ;
AnyCharacterButEnter = AnyCharacter - Enter;