|
|
|
@ -8,68 +8,96 @@ BPEGN can be 100% transpiled to and from the Parsing Expression Grammer
|
|
|
|
|
Notation (PEGN). Code in one and use "bonzai pegn" command to easily
|
|
|
|
|
generate the other. BPEGN is sometimes referred to informally as "Bonzai
|
|
|
|
|
Scanner Expect" language as well since it is passed directly to
|
|
|
|
|
scan.Expect or scan.Check. These structs are guaranteed never to have
|
|
|
|
|
their structure order change in any way allowing them to be used in
|
|
|
|
|
key-less, in-line composable syntax notation (which, despite the many
|
|
|
|
|
editor warnings, is entirely supported by Go and always will be).
|
|
|
|
|
scan.Expect or scan.Check.
|
|
|
|
|
|
|
|
|
|
Parameterized Struct and Set Slice Expressions
|
|
|
|
|
|
|
|
|
|
BPEGN uses Go structs and slices to represent scannable expressions with
|
|
|
|
|
obvious similarities to regular expressions. These expressions have
|
|
|
|
|
one-to-parity with PEGN expressions. Slices represent sets of
|
|
|
|
|
possibilities. Structs provide parameters for more complex expressions
|
|
|
|
|
and are are guaranteed never to change allowing them to be dependably
|
|
|
|
|
used in assignment without struct field names using Go's inline
|
|
|
|
|
composable syntax. Some editors may need configuring to allow this since
|
|
|
|
|
in general practice this can create subtle (but substantial) foot-guns
|
|
|
|
|
for maintainers.
|
|
|
|
|
|
|
|
|
|
Look-Ahead and Advancing Expressions
|
|
|
|
|
|
|
|
|
|
"Advancing" expressions will advance the scan to the end of the
|
|
|
|
|
expression match. "Look-ahead" expressions simply check for a match but
|
|
|
|
|
do not advance the scan. Developers should take careful note of the
|
|
|
|
|
difference in the documentation.
|
|
|
|
|
|
|
|
|
|
Composites
|
|
|
|
|
|
|
|
|
|
Composites are compound expressions composed of others. They represent
|
|
|
|
|
the tokens and classes from PEGN and other grammars and are designed to
|
|
|
|
|
simplify grammar development at a higher level. Pull requests are welcome for missing, commonly used composite candidates.
|
|
|
|
|
*/
|
|
|
|
|
package is
|
|
|
|
|
|
|
|
|
|
// Lk is a set of positive lookahead expressions. If any are seen at
|
|
|
|
|
// ------------------------------- sets -------------------------------
|
|
|
|
|
|
|
|
|
|
// Seq groups expressions into a sequence. It ensures that all
|
|
|
|
|
// expressions appears in that specific order. If any are not the scan
|
|
|
|
|
// fails.
|
|
|
|
|
type Seq []any
|
|
|
|
|
|
|
|
|
|
// Lk is a set of positive lookahead expressions. If any are seen at
|
|
|
|
|
// the current cursor position the scan will proceed without consuming
|
|
|
|
|
// them. Otherwise, it will fail.
|
|
|
|
|
// them (unlike is.Opt and is.Any). If none are found the scan fails.
|
|
|
|
|
type Lk []any
|
|
|
|
|
|
|
|
|
|
// Not is a set of negative lookahead expressions. If any are seen at
|
|
|
|
|
// the current cursor position the scan will fail.
|
|
|
|
|
// Not is a set of negative lookahead expressions. If any are seen at
|
|
|
|
|
// the current cursor position the scan will fail. Otherwise, the scan
|
|
|
|
|
// proceeds from that same position.
|
|
|
|
|
type Not []any
|
|
|
|
|
|
|
|
|
|
// In scannable slice represents a set group of scannables. If any
|
|
|
|
|
// scannable in the slice is found the Is scannable itself is true. If
|
|
|
|
|
// nothing is found the result is false. The search through the In
|
|
|
|
|
// scannable group is always linear allowing parser developers to
|
|
|
|
|
// establish the priority for common finds themselves.
|
|
|
|
|
type In []any
|
|
|
|
|
|
|
|
|
|
// Seq scannable slice represents a sequence group of scannables. It
|
|
|
|
|
// ensures that the slice of scannables always appears in that specific
|
|
|
|
|
// order. Avoid over use of Seq since Expect/Check already expect
|
|
|
|
|
// a sequence of scannables.
|
|
|
|
|
type Seq []any
|
|
|
|
|
// Any is a set of advancing expressions. If any scannable in the slice
|
|
|
|
|
// is found the scan advances to the end of that expression and
|
|
|
|
|
// continues. If none of the expressions is found the scan fails.
|
|
|
|
|
// Evaluation of expressions is always left to right allowing allowing
|
|
|
|
|
// parser developers to prioritize common expressions at the beginning
|
|
|
|
|
// of the slice.
|
|
|
|
|
type Any []any
|
|
|
|
|
|
|
|
|
|
// Opt scannable slice represents a set of optional positive look-ahead
|
|
|
|
|
// scannables much like In, except that if nothing is found no error is
|
|
|
|
|
// generated. This is the equivalent of the question mark on a set
|
|
|
|
|
// ([]?) from regular expressions.
|
|
|
|
|
// Opt is a set of optional advancing expressions. If any expression is
|
|
|
|
|
// found the scan is advanced (unlike Lk, which does not advance).
|
|
|
|
|
type Opt []any
|
|
|
|
|
|
|
|
|
|
// MMx scannable struct represents the inclusive minimum and maximum
|
|
|
|
|
// count of the give scannable item (This).
|
|
|
|
|
// --------------------------- parameterized --------------------------
|
|
|
|
|
|
|
|
|
|
// MMx parameterized advancing expression scans for the inclusive
|
|
|
|
|
// minimum and maximum count of the given expression (This). Use within
|
|
|
|
|
// is.Lk to disable advancement.
|
|
|
|
|
type MMx struct {
|
|
|
|
|
Min int
|
|
|
|
|
Max int
|
|
|
|
|
This any
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Min scannable struct represents the inclusive minimum (Min,) count
|
|
|
|
|
// of the given scannable item (This).
|
|
|
|
|
// Min parameterized advancing expression scans for the inclusive minimum
|
|
|
|
|
// number of the given expression item (This). Use within is.Lk to
|
|
|
|
|
// disable advancement.
|
|
|
|
|
type Min struct {
|
|
|
|
|
Min int
|
|
|
|
|
This any
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Mn1 scannable struct is shorthand for Min{1,This}.
|
|
|
|
|
// Mn1 parameterized advancing expression is shorthand for is.Min{1,This}.
|
|
|
|
|
type Mn1 struct{ This any }
|
|
|
|
|
|
|
|
|
|
// N scannable struct represents exactly X number of the given scannable
|
|
|
|
|
// items (This).
|
|
|
|
|
// N parameterized advancing expression scans for exactly N number of
|
|
|
|
|
// the given expression (This). Use within is.Lk to disable advancement.
|
|
|
|
|
type N struct {
|
|
|
|
|
N int
|
|
|
|
|
This any
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Rng scannable struct represents any single rune from an
|
|
|
|
|
// inclusive consecutive set from the First to Last (First,Last).
|
|
|
|
|
// Rng parameterized advancing expression scans for a single Unicode
|
|
|
|
|
// code point (rune, uint32) from an inclusive consecutive set from
|
|
|
|
|
// First to Last (First,Last). Use within is.Lk to disable advancement.
|
|
|
|
|
type Rng struct {
|
|
|
|
|
First rune
|
|
|
|
|
Last rune
|
|
|
|
|