mirror of
https://github.com/rwxrob/bonzai
synced 2024-11-16 21:25:44 +00:00
Add z name, z.N and z.X
This commit is contained in:
parent
44b50aa331
commit
47ee497b0d
@ -1,4 +1,4 @@
|
||||
package is
|
||||
package z
|
||||
|
||||
// keep only compound expressions here
|
||||
|
||||
|
@ -2,13 +2,19 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
/*
|
||||
Package is defines the Bonzai Parsing Expression Grammar Notation
|
||||
(BPEGN) implemented entirely using Go types (mostly slices and structs).
|
||||
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.
|
||||
Package z (often imported as "is") defines the Bonzai Parsing Expression
|
||||
Grammar Notation (BPEGN) (aka "Bonzai Scanner Expect" language)
|
||||
implemented entirely using Go types (mostly slices and structs). BPEGN
|
||||
can be 100% transpiled to and from the Parsing Expression Grammer
|
||||
Notation (PEGN). Code in one grammar and use the bonzai command to
|
||||
easily generate the other.
|
||||
|
||||
Nodes and Expressions
|
||||
|
||||
Nodes (z.N) indicate something to be captured as a part of the resulting
|
||||
abstract syntax tree. They are functionally equivalent to parenthesis in
|
||||
regular expressions but with the obvious advantage of capturing a rooted
|
||||
node tree instead of an array. Expressions (z.X) indicate a sequence to be scanned but not captured unless the expression itself is within a node (z.N).
|
||||
|
||||
Tokens
|
||||
|
||||
@ -49,15 +55,27 @@ a scan.R). A Hook is passed only the scanner struct and must return a bool
|
||||
indicating if the scan should proceed. See scan.Hook for more
|
||||
information.
|
||||
*/
|
||||
package is
|
||||
package z
|
||||
|
||||
// ------------------------------- core -------------------------------
|
||||
|
||||
// N ("node") is a named sequence of expressions that will be captured
|
||||
// into a node. The first string must always be the name which can be
|
||||
// any valid Go string. If any expression fails to match the scan fails.
|
||||
// Otherwise, a new tree.Node is added under the current node and the
|
||||
// scan proceeds. Nodes must either contain other nodes or no nodes at
|
||||
// all. If the first item in the sequence after the name is not also
|
||||
// a node (z.N) then the node is marked as "edge" (or "leaf") and any
|
||||
// nodes detected further in the sequence will cause the scan to fail
|
||||
// with a syntax error.
|
||||
type N []any
|
||||
|
||||
// X ("expression") is a sequence of expressions. If any are not the
|
||||
// scan fails. (Equal to (?foo) in regular expressions.)
|
||||
type X []any
|
||||
|
||||
// ------------------------------- sets -------------------------------
|
||||
|
||||
// X (the slice) groups expressions into a sequence. It ensures that all
|
||||
// expressions appears in that specific order. If any are not the scan
|
||||
// fails. (Equal to parenthesis in PEGN.)
|
||||
type X []any
|
||||
|
||||
// It (the slice) is a set of positive lookahead expressions. If any are
|
||||
// seen at the current cursor position the scan will proceed without
|
||||
// consuming them (unlike is.O and is.In). If none are found the scan
|
||||
@ -121,15 +139,15 @@ type Min struct {
|
||||
// Mn1 is shorthand for is.Min{1,This}.
|
||||
type Mn1 struct{ This any }
|
||||
|
||||
// N is a parameterized advancing expression that matches exactly
|
||||
// N number of the given expression (This). Use within is.It to disable
|
||||
// C is a parameterized advancing expression that matches an exact count
|
||||
// of the given expression (This). Use within is.It to disable
|
||||
// advancement.
|
||||
type N struct {
|
||||
type C struct {
|
||||
N int
|
||||
This any
|
||||
}
|
||||
|
||||
// Any is short for is.N{tk.ANY}.
|
||||
// Any is short for is.C{tk.ANY}.
|
||||
type Any struct {
|
||||
N int
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ import (
|
||||
"io"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/rwxrob/bonzai/scan/is"
|
||||
is "github.com/rwxrob/bonzai/scan/is"
|
||||
"github.com/rwxrob/bonzai/scan/tk"
|
||||
"github.com/rwxrob/bonzai/util"
|
||||
)
|
||||
@ -446,7 +446,7 @@ func (s *R) Expect(expr any) (*Cur, error) {
|
||||
}
|
||||
return last, nil
|
||||
|
||||
case is.N: // ------------------------------------------------------
|
||||
case is.C: // ------------------------------------------------------
|
||||
b := s.Mark()
|
||||
m, err := s.Expect(is.MMx{v.N, v.N, v.This})
|
||||
if err != nil {
|
||||
@ -539,7 +539,7 @@ func (s *R) ErrorExpected(this any, args ...any) error {
|
||||
case is.MMx:
|
||||
str := `expected min %v, max %v of %q`
|
||||
msg = fmt.Sprintf(str, v.Min, v.Max, v.This)
|
||||
case is.N:
|
||||
case is.C:
|
||||
str := `expected exactly %v of %q`
|
||||
msg = fmt.Sprintf(str, v.N, v.This)
|
||||
case is.Rng:
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/rwxrob/bonzai/scan"
|
||||
"github.com/rwxrob/bonzai/scan/is"
|
||||
is "github.com/rwxrob/bonzai/scan/is"
|
||||
"github.com/rwxrob/bonzai/scan/tk"
|
||||
)
|
||||
|
||||
@ -464,17 +464,17 @@ func ExampleExpect_mMx() {
|
||||
// expected min 1, max 3 of 'X' at U+006F 'o' 1,2-2 (2-2)
|
||||
}
|
||||
|
||||
func ExampleExpect_n() {
|
||||
func ExampleExpect_c() {
|
||||
s, _ := scan.New("sommme thing")
|
||||
s.Snap()
|
||||
s.ScanN(2)
|
||||
s.Print()
|
||||
s.Expect(is.N{3, 'm'}) // goggles up all three
|
||||
s.Expect(is.C{3, 'm'}) // goggles up all three
|
||||
s.Print()
|
||||
s.Back()
|
||||
s.Expect(is.N{1, 's'}) // yes, but silly since 's' is easier
|
||||
s.Expect(is.C{1, 's'}) // yes, but silly since 's' is easier
|
||||
s.Print()
|
||||
_, err := s.Expect(is.N{3, 'X'}) // nope
|
||||
_, err := s.Expect(is.C{3, 'X'}) // nope
|
||||
fmt.Println(err)
|
||||
// Output:
|
||||
// U+006D 'm' 1,3-3 (3-3)
|
||||
|
Loading…
Reference in New Issue
Block a user