Enki - EBNF
( Back to Syntax Guide)
More on EBNF here: http://en.wikipedia.org/wiki/Extended_Backus-Naur_form
Enki is based on a combination of various EBNF representations in use online. The variant of EBNF used here is not the regex-friendly kind that some may be used to using. Future versions of Enki may support '*', '?' and '+' as postfix repetition operators, but for now these are unsupported. For more information, see the BNF enki.bnf in SVN for the explicit definition of Enki's grammar.
- Rules are defined via "::=" (not "="). A semicolon is required to properly terminate a rule.
- Optional expressions are delimited by "![]".
- Rule groups are delimited "()".
- Branching is performed by "|" between expressions.
- Repetition is denoted by "{}", and will terminate on the following predicate/terminal if defined.
- Terminals (strings) are delimited by 'single' or "double" quotes. C-style backslash expressions are used inside.
- Regular-expression terminals can be declared using the backtick "`" as a delimiter.
- Single-char Terminals can be declared by way of the '#xx' operator, where 'xx' is a hexidecimal number.
- Any expression may be any defined rule or
Grouping ::= (expr1 expr2);
OptionalExample ::= [OptionalRule];
Hi::= "hello" ws 'world';
Branches ::= expr1 | expr2 | expr3 | expr4;
BasicString::= "'" {any} "'" | '"' {any} '"';
Regex ::= `hello\s*world`;
Those familiar with EBNF and composing parsers may feel that the definition of 'BasicString?' is ambiguous. Technically this is correct, since the repetition of 'any' is unbounded - this should match all characters to the end of input.
In Enki, this is not the case as the repetition operator is defined as incorporating the following expression as a 'terminator' should it exist. For each iteration of a repetition expression, Enki attempts to match the terminating expression first, then the internal expression should the terminator not match. So by definition, unbounded repetition can only ocurr at the end of a given rule.
# matches zero or more of y until x or eoi is reached
# fails if x does not follow zero or more y
BoundedRepetition ::= {y} x;
# matches zero or more z until not z or eoi
UnboundedRepetition ::= {z};
Annotations and Extensions to EBNF
Annotations provide a way to tie back parser events like completing a rule or parsing a terminal to D code. This code is assumed to be developer supplied, so Enki will not perform any kind of semantic checking on such expressions. However, binding types, where not explicitly defined, are subject to semantic checking. Type conversion to and from bindings, where not implicit, is handled by a system of templates that attempts to convert between types as intellegently as possible.
A rule contains a predicate expression which is the most direct way to bind parsing events back to D code. A rule predicate can be any function, class, or variable. The result of the rule predicate is passed back from the rule to the calling rule, for further use and processing by way of binding expressions (see below).
