// After I had the same problem one day and there was no help from sparxsystems,
// I created a grammar on my own... but I cannot support you, if you got problems with it... NO WARRANTY, USE IT ON YOUR OWN RISK. Please post any improvements to this thread
// Perhaps anyone of sparxsystems could quality-check and support it...
// 'till now, it works for me.
// -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Delphi.nBNF
caseInsensitive();
delimiters(<DELIMITER>);
lex(<TOKENS>);
parse(<Goal>);
<TOKENS> ::= <WHITESPACE> |
<COMMENT> |
token(<STRING_BODY>) |
// token(<RANGEOP>) |
token(<NUMBER>) |
token(<DELIMITER>) |
token(keywords()) |
token(<IDENTIFIER>);
//<RANGEOP> ::= "..";
<WHITESPACE> ::= " " | "\r" | "\n" | "\t";
<COMMENT> ::= <LINECOMMENT> |
<BLOCKCOMMENT>;
<LINECOMMENT> ::= "//" skip("\n") "\n" |
"//" skipEof();
<BLOCKCOMMENT> ::= ("{" skip("}") "}" | "(*" skip("*)") "*)");
<NUMBER> ::= <FLOAT_NUMBER> |
<INT_NUMBER>;
<FLOAT_NUMBER> ::=
// Trick, weil <NUMBER> ein Token ist und z.B. "1..4" als <ExpressionOrRange> sonst fehlschlägt:
// Error: Unexpected symbol '.4'. (Line 64 Column 16)
// der Fehler durch den Trick ist für dieses Parsing unbedeutend...
// bei <ExpressionOrRange>: aus '<NUMBER> ".." <NUMBER> wird <NUMBER>
"0".."9"+ ".." "0".."9"+ |
"0".."9" + "." ["0".."9"+] [("e" | "E") ["+" | "-"] "0".."9"+] |
"." "0".."9"+ [("e" | "E") ["+" | "-"] "0".."9"+] |
"0".."9" + ("e" | "E") ["+" | "-"] "0".."9"+ |
"0".."9" + [("e" | "E") ["+" | "-"] "0".."9"+];
<INT_NUMBER> ::= <HEX_NUMBER> |
<DEC_NUMBER> |
("#" <INT_NUMBER>)+;
<HEX_NUMBER> ::= "$" ("0".."9" | "a".."f")+;
<DEC_NUMBER> ::= "0".."9"+;
<STRING_BODY> ::= "'" skip("'", "''") "'";
<IDENTIFIER> ::= ("a".."z" | "_") ("a".."z" | "0".."9" | "_")*;
<DELIMITER> ::= (" " | "\n" | "\r" | "\t" |
"~" | "!" | "@" | "#" |
"$" | "%" | "^" |
"&" | "*" | "(" | ")" |
"-" | "+" | "{" |
"[" | "}" | "]" | ";" |
"\"" | "\'" | ":=" | ":" |
"," | "<=" | ">=" | "=" | "<>" | "<" | ">" | "/" |
"?" | "|" | ".." | ".");
<KEYWORD> ::= "AND" |
"ARRAY" |
"AS" |
"ASM" |
"BEGIN" |
"CASE" |
"CLASS" |
"CONST" |
"CONSTRUCTOR" |
"DESTRUCTOR" |
"DISPINTERFACE" |
"DIV" |
"DO" |
"DOWNTO" |
"ELSE" |
"END" |
"EXCEPT" |
"EXPORTS" |
"FILE" |
"FINALIZATION" |
"FINALLY" |
"FOR" |
"FUNCTION" |
"GOTO" |
"IF" |
"IMPLEMENTATION" |
"IN" |
"INHERITED" |
"INITIALIZATION" |
"INTERFACE" |
"IS" |
"LABEL" |
"LIBRARY" |
"MOD" |
"NIL" |
"NOT" |
"OBJECT" |
"OF" |
"OR" |
"PACKED" |
"PROCEDURE" |
"PROGRAM" |
"PROPERTY" |
"RAISE" |
"RECORD" |
"REPEAT" |
"RESOURCE" |
"SET" |
"SHL" |
"SHR" |
"STRING" |
"THEN" |
"THREADVAR" |
"TO" |
"TRY" |
"TYPE" |
"UNIT" |
"UNTIL" |
"USES" |
"VAR" |
"WHILE" |
"WITH" |
"XOR";
<SEMIKEYWORD> ::= "ABSOLUTE" |
"ABSTRACT" |
"ASSEMBLER" |
"AT" |
"AUTOMATED" |
"CDECL" |
"CONTAINS" |
"DEFAULT" |
"DELAYED" |
"DEPRECATED" |
"DISPID" |
"DYNAMIC" |
"EXPERIMENTAL" |
"EXPORT" |
"EXTERNAL" |
"FAR" |
"FINAL" |
"FORWARD" |
"HELPER" |
"IMPLEMENTS" |
"INDEX" |
"LOCAL" |
"MESSAGE" |
"NAME" |
"NEAR" |
"NODEFAULT" |
"ON" |
"OPERATOR" |
"OUT" |
"OVERLOAD" |
"OVERRIDE" |
"PACKAGE" |
"PASCAL" |
"PLATFORM" |
"PRIVATE" |
"PROTECTED" |
"PUBLIC" |
"PUBLISHED" |
"READ" |
"READONLY" |
"REGISTER" |
"REINTRODUCE" |
"REQUIRES" |
"RESIDENT" |
"SAFECALL" |
"SEALED" |
"STATIC" |
"STDCALL" |
"STORED" |
"STRICT" |
"UNSAFE" |
"VARARGS" |
"VIRTUAL" |
"WRITE" |
"WRITEONLY";
<AddOp> ::= "+" |
"-" |
"OR" |
"XOR";
<AnonymousMethod> ::= <AnonymousMethodHeading>
<FancyBlock>;
<AnonymousMethodHeading> ::= [<CodeAttribute>]
node("METHOD", node("DECLARATION",
("PROCEDURE"|"FUNCTION")
(
["(" (<Parameter> [";"])* ")"]
[":" node("TYPE", attribute("NAME", <MethodReturnType>))]
)));
<AnonProcedureOrFunctionType> ::= "REFERENCE TO" <AnonymousMethodHeading>;
<ArrayType> ::= ("ARRAY "|"ARRAY") ("[" <Expression> ".." <Expression> "]" "OF" <Type> |
["[" (<Type>[","])+ "]" ] "OF" <Type>);
<AssemblerStatement> ::= "ASM" skip("END") "END";
<AssemblyAttribute> ::= "[" "ASSEMBLY" ":" <Expression> "]";
<Atom> ::= <Particle> ("." <ExtendedIdent>
| "[" <ExpressionList> "]"
| "^"
| "(" (<ParameterExpression> [","])* ")"
)*;
<BareInherited> ::= "INHERITED";
<Block> ::= ("BEGIN" [<StatementList>] "END" |
<AssemblerStatement>);
<CaseSelector> ::= (<ExpressionOrRange> [","])+
":" [<Statement>] [";"];
<CaseStatement> ::= "CASE" <Expression> "OF"
(<CaseSelector>)+
["ELSE" [<StatementList>]]
"END";
<ClassHelperType> ::= "CLASS" "HELPER"
["(" <QualifiedIdent> ")"]
"FOR" <QualifiedIdent>
(<VisibilitySections>)
"END";
<ClassOfType> ::= "CLASS" "OF" <QualifiedIdent>;
<ClassType> ::= "CLASS"
node("BODY", ["ABSTRACT"|"SEALED"]
["(" (node("PARENT", attribute("NAME", node("TYPE", attribute("NAME", <GenericsType>)))) [","])+ ")"]
[(<VisibilitySections>) "END"] );
<CodeAttribute> ::= ("[" node("TAG", attribute("NAME", <QualifiedIdent>) ["(" attribute("VALUE", <ExpressionList>) ")"]) "]")+;
<ConstantDecl> ::= <Ident>
[":" <Type> ]
"=" <TypedConstant>
(<PortabilityDirective>)*
";";
<ConstSection> ::= ("CONST"|"RESOURCESTRING")
(<ConstantDecl>)+;
<Directive> ::= [";"] "ABSTRACT" |
[";"] "ASSEMBLER" |
[";"] "CDECL" |
[";"] "DEPRECATED" <Expression> |
[";"] "DELAYED" |
[";"] "DISPID" <Expression> |
[";"] "DYNAMIC" |
[";"] "EXPORT" |
[";"] "EXTERNAL" [<Expression> (<ExportsSpecifier>)*] |
[";"] "FAR" |
[";"] "FINAL" |
[";"] "FORWARD" |
[";"] "INLINE" |
[";"] "LOCAL" |
[";"] "MESSAGE" <Expression> |
[";"] "NEAR" |
[";"] "OVERLOAD" |
[";"] "OVERRIDE" |
[";"] "PASCAL" |
[";"] "REGISTER" |
[";"] "REINTRODUCE" |
[";"] "SAFECALL" |
[";"] "STATIC" |
[";"] "STDCALL" |
[";"] "VARARGS" |
[";"] "VIRTUAL" |
[";"] <PortabilityDirective>;
<EnumeratedType> ::= "(" (<EnumeratedTypeElement> [","])+ ")";
<EnumeratedTypeElement> ::= <Ident> ["=" <Expression>];
<ExceptionItem> ::= "ON"
[<Ident> ":"]
<QualifiedIdent> "DO"
[<Statement>]
[";"];
<ExportsItem> ::= <Ident> (<ExportsSpecifier>)*;
<ExportsSpecifier> ::= ("INDEX" | "NAME") <Expression>;
<ExportsStatement> ::= "EXPORTS" (<ExportsItem> [","])+ ";";
<Expression> ::= (<AnonymousMethod>|<SimpleExpression>|<BareInherited>) (<RelOp> (<AnonymousMethod>|<SimpleExpression>|<BareInherited>))*;
<ExpressionList> ::= (<Expression>[","])+;
<ExpressionOrAssignment> ::= <Expression> ":=" <Expression> |
<Expression>;
<ExpressionOrRange> ::= <SimpleExpression> [".." <SimpleExpression>];
<ExpressionOrRangeList> ::= (<ExpressionOrRange>[","])+;
<ExtendedIdent> ::= (<GenericsType> |
<Ident> |
<KEYWORD>);
<Factor> ::= (<Atom> |
<UnaryOperator> <Factor>);
<FancyBlock> ::= (<ImplementationDecl>)*
<Block>;
<FieldDecl> ::= ([<CodeAttribute>] node("ATTRIBUTE", (attribute("NAME", <Ident>)) ":" node("TYPE", attribute("NAME", <Type>))) (<PortabilityDirective>)* [";"] |
[<CodeAttribute>] node("ATTRIBUTE", (attribute("NAME", <Ident>)) ","+ ":" node("TYPE", attribute("NAME", <Type>))) (<PortabilityDirective>)* [";"]);
<FieldSection> ::= [("CLASS" "VAR" | "VAR")]
<FieldDecl>;
<FileType> ::= "FILE" |
"FILE OF" <QualifiedIdent>;
<ForStatement> ::= "FOR" <Ident> ":=" <Expression> ("TO" | "DOWNTO") <Expression> "DO" [<Statement>] |
"FOR" <Ident> "IN" <Expression> "DO" [<Statement>];
<GenericsParam> ::= ("STRING"|
<GenericsType>);
<GenericsType> ::= <QualifiedIdent> ("<" (<GenericsParam> [","])+ ">")*;
<GenericsIdent> ::= (<Ident> "<" "STRING" ">"|
<Ident> ("<" ((<GenericsType>
[<GenericsConstraint>] [","])+ [","])+ ">")*) ("." <ExtendedIdent>)*;
<GenericsConstraint> ::= ":" ("CLASS"|"CONSTRUCTOR"|"RECORD"|<QualifiedIdent>);
<Goal> ::= <Program> |
<Package> |
<Unit>;
<GotoStatement> ::= "GOTO" <LabelId>;
<Ident> ::= (<IDENTIFIER> |
<SEMIKEYWORD> |
"&" <IDENTIFIER> |
"&" <SEMIKEYWORD> |
"&" <KEYWORD>);
<IdentList> ::= (<Ident>[","])+;
<IfStatement> ::= "IF" <Expression> "THEN" [<Statement>]
["ELSE" [<Statement>]];
<ImplementationDecl> ::= <LabelDeclSection> |
<ConstSection> |
<TypeSection> |
<VarSection> |
<MethodImplementation> |
<ExportsStatement> |
<AssemblyAttribute>;
<ImplementationSection> ::= "IMPLEMENTATION"
[<UsesClause>]
(<ImplementationDecl>)*;
<InitSection> ::= "END" |
<Block> |
"INITIALIZATION"
[<StatementList>]
["FINALIZATION"
[<StatementList>]]
"END";
<InterfaceDecl> ::= <ConstSection> |
<TypeSection> |
<VarSection> |
node("METHOD", node("DECLARATION", <MethodHeading>));
<InterfaceSection> ::= "INTERFACE"
[<UsesClause>]
(<InterfaceDecl>)*;
<InterfaceType> ::= node("BODY", ("INTERFACE"|"DISPINTERFACE")
["(" <QualifiedIdent> ")"]
["[" <Expression> "]"]
(<MethodOrProperty>)*
"END");
<LabelDeclSection> ::= "LABEL" (<LabelId> [","])+ ";";
<LabelId> ::= <NUMBER> |
<Ident>;
<MethodHeading> ::= [<CodeAttribute>]
("PROCEDURE"|"FUNCTION"|"CONSTRUCTOR"|"DESTRUCTOR"|"OPERATOR"|"CLASS" "PROCEDURE"|"CLASS" "FUNCTION")
attribute("NAME", <GenericsIdent>)
(
["(" (<Parameter> [";"])* ")"]
[":" node("TYPE", attribute("NAME", <MethodReturnType>))]
(<Directive>)*
|"=" <Ident>
)
[";"];
<MethodImplementation> ::= node("METHOD", node("BODY", <MethodHeading>
<FancyBlock> ";")) |
node("METHOD", node("DECLARATION", <MethodHeading>));
<MethodOrProperty> ::= node("METHOD", node("DECLARATION", <MethodHeading>)) |
<Property>;
<MethodReturnType> ::= "STRING" |
<GenericsType>;
<MulOp> ::= "*" |
"/" |
"DIV" |
"MOD" |
"AND" |
"SHL" |
"SHR";
<OpenArray> ::= "ARRAY OF" (<QualifiedIdent> |
"STRING" |
"FILE" |
"CONST");
<Package> ::= "PACKAGE" <QualifiedIdent> ";"
[<RequiresClause>]
[<UsesClause>]
(<AssemblyAttribute>)*
"END" ".";
<PackedType> ::= "PACKED" <Type>;
<Parameter> ::= [<CodeAttribute>]
node("PARAMETER",
[attribute("KIND", "VAR"|"CONST"|"OUT")]
attribute("NAME", <IdentList>)
[":" attribute("TYPE", <ParameterType>)]
[node("DEFAULT", "=" <Expression>)]);
<ParameterExpression> ::= <Expression> [":" <Expression> [ ":" <Expression> ]];
<ParameterType> ::= <GenericsType> |
<QualifiedIdent> |
"STRING" |
"FILE" |
<OpenArray>;
<ParenthesizedExpression> ::= "(" <Expression> ")";
<Particle> ::= <NUMBER> |
<StringConst> |
<GenericsType> |
<Ident> |
"NIL" |
<ParenthesizedExpression> |
<SetLiteral> |
"STRING" |
"FILE";
<PointerType> ::= "^" <Type>;
<PortabilityDirective> ::= "PLATFORM" |
"DEPRECATED" |
"LIBRARY" |
"EXPERIMENTAL";
<ProcedureType> ::= ("PROCEDURE" | "FUNCTION")
["(" (<Parameter> [";"])* ")"]
[":" <MethodReturnType>]
(<Directive>)*
["OF" "OBJECT"]
(<Directive>)*;
<Program> ::= node("PACKAGE",("PROGRAM" | "LIBRARY") <Ident>) ["(" <IdentList> ")"] ";"
[<UsesClause>]
(<ImplementationDecl>)*
<InitSection> ".";
<Property> ::= [<CodeAttribute>]
["CLASS"]
"PROPERTY" node("PROPERTY", attribute("NAME", <Ident>)
["["(<Parameter> [";"])+ "]"]
[":" node("TYPE", attribute("NAME", <MethodReturnType>))]
(<PropertyDirective>)*
";");
<PropertyDirective> ::= ";" "DEFAULT" |
"DEFAULT" <Expression> |
"DISPID" <Expression> |
"IMPLEMENTS" (<QualifiedIdent> [","])+ |
"INDEX" <Expression> |
"NODEFAULT" |
"READ" <Expression> |
"READONLY" |
"STORED" <Expression> |
"WRITE" <Expression> |
"WRITEONLY";
<QualifiedIdent> ::= (<Ident> ("." <ExtendedIdent>)* |
<GenericsIdent>);
<RaiseStatement> ::= "RAISE" [<Expression> ["AT" <Expression>]];
<RecordHelperType> ::= "RECORD" "HELPER" "FOR" <QualifiedIdent>
(<VisibilitySections>)
"END";
<RecordType> ::= ["PACKED"] "RECORD"
(<VisibilitySections>)
[<VariantSection>]
"END";
<RelOp> ::= ("=" |
">" |
"<" |
"<=" |
">=" |
"<>" |
"IN" |
"IS" |
"AS");
<RepeatStatement> ::= "REPEAT" [<StatementList>] "UNTIL" <Expression>;
<RequiresClause> ::= "REQUIRES" (<QualifiedIdent> [","])+ ";";
<SetLiteral> ::= "[" [<ExpressionOrRangeList>] "]";
<SetType> ::= "SET" "OF" <Type>;
<SimpleExpression> ::= <Term> (<AddOp> <Term>)*;
<SimpleStatement> ::= (<BareInherited> |
<ExpressionOrAssignment> |
<GotoStatement> |
<Block> |
<IfStatement> |
<CaseStatement> |
<RepeatStatement> |
<WhileStatement> |
<ForStatement> |
<WithStatement> |
<TryStatement> |
<RaiseStatement>);
<Statement> ::= ( <LabelId> ":" [<SimpleStatement>] | <SimpleStatement> | ";");
<StatementList> ::= ((";")* <Statement> (";")*)+;
<StringType> ::= "STRING" |
"STRING" "[" <Expression> "]";
<StringConst> ::= (<STRING_BODY> |
"^" <Ident>)+;
<Term> ::= <Factor> (<MulOp> <Factor>)*;
<TryStatement> ::= "TRY"
[<StatementList>]
( "FINALLY" [<StatementList>]
| "EXCEPT"
(
((<ExceptionItem>)+ ["ELSE" [<StatementList>]]) |
([<StatementList>])
)
)
"END";
<Type> ::= (<EnumeratedType> |
<GenericsType> |
<ExpressionOrRange> |
<ArrayType> |
<OpenArray> |
<SetType> |
<FileType> |
<RecordHelperType> |
<RecordType> |
<PointerType> |
<StringType> |
<ProcedureType> |
<ClassHelperType> |
<ClassOfType> |
<ClassType> |
<AnonProcedureOrFunctionType> |
<PackedType>);
<TypedConstant> ::= <Expression> |
"(" (<QualifiedIdent> ":" <TypedConstant> [";"])+ ")" |
"(" (<TypedConstant> [","])+ ")" |
"(" ")";
<TypeDecl> ::= [<CodeAttribute>]
node("CLASS",
attribute("NAME", <GenericsIdent>) "=" ["TYPE"] <Type> (<PortabilityDirective>)*) ";" |
node("INTERFACE",
attribute("NAME", <GenericsIdent>) "=" ["TYPE"] <InterfaceType> (<PortabilityDirective>)*) ";" |
attribute("NAME", <GenericsIdent>) "=" "CLASS" ";" |
attribute("NAME", <GenericsIdent>) "=" "DISPINTERFACE" ";" |
attribute("NAME", <GenericsIdent>) "=" "INTERFACE" ";";
<TypeSection> ::= "TYPE" (<TypeDecl>)+;
<UnaryOperator> ::= "NOT" |
"+" |
"-" |
"@" |
"INHERITED";
<Unit> ::= node("PACKAGE",
"UNIT" attribute("NAME", <QualifiedIdent>)) (<PortabilityDirective>)* ";"
<InterfaceSection>
<ImplementationSection>
<InitSection> ".";
<UsedUnit> ::= <QualifiedIdent> "IN" <StringConst> |
<QualifiedIdent>;
<UsesClause> ::= ("USES" | "CONTAINS") (<UsedUnit>[","])+ ";";
<VarDecl> ::= <IdentList> ":" <Type>
(<PortabilityDirective>)*
["ABSOLUTE" <Expression> | "=" <TypedConstant>]
(<PortabilityDirective>)*
";";
<VariantGroup> ::= <ExpressionList> ":"
"("
(<FieldDecl>)*
[<VariantSection>]
")" [";"];
<VariantSection> ::= "CASE" [<Ident> ":"] <QualifiedIdent> "OF"
(<VariantGroup>)+;
<VarSection> ::= ("VAR"|"THREADVAR") (<VarDecl>)+;
<Visibility> ::= (attribute("NAME", "STRICT PRIVATE") |
attribute("NAME", "STRICT PROTECTED") |
attribute("NAME", "PRIVATE") |
attribute("NAME", "PROTECTED") |
attribute("NAME", "PUBLIC") |
attribute("NAME", "PUBLISHED"));
<VisibilitySections> ::= (<VisibilitySection>)+;
<VisibilitySection> ::= (node("SCOPE", <Visibility> (<VisibilitySectionContent>)+) |
node("SCOPE", attributeEx("NAME", "published") (<VisibilitySectionContent>)+) |
node("SCOPE", <Visibility>));
<VisibilitySectionContent> ::= (<FieldSection>|
<MethodOrProperty> |
<ConstSection> |
<TypeSection>);
<WhileStatement> ::= "WHILE" <Expression> "DO" [<Statement>];
<WithStatement> ::= "WITH" <ExpressionList> "DO" [<Statement>];
// -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------