Add scan.R.Parse*, z.P->z.Y, z.P for parse

This commit is contained in:
rwxrob 2022-03-04 21:20:54 -05:00
parent c4f7274e01
commit 78a8a6fb65
No known key found for this signature in database
GPG Key ID: 2B9111F33082AE77
4 changed files with 91 additions and 21 deletions

View File

@ -11,8 +11,12 @@ import (
"github.com/rwxrob/bonzai/comp"
"github.com/rwxrob/bonzai/filt"
"github.com/rwxrob/bonzai/maps"
"github.com/rwxrob/bonzai/term"
)
var OBracketed = term.Under
var CBracketed = term.Reset
// Cmd provides help documentation for the caller allowing the specific
// section of help wanted to be passed as a tab-completable parameter.
var Cmd = &bonzai.Cmd{
@ -58,3 +62,27 @@ func helpCompleter(x comp.Command, args ...string) []string {
return filt.HasPrefix(list, args[0])
}
// Render renders the incoming Help markup string for a curses terminal
// detecting if the terminal is interactive and if not rendering as
// plain text instead.
func Render(in string) string {
out := ""
for i := 0; i < len([]rune(in)); i++ {
cur := in[i]
switch cur {
// <bracketed>
case '<':
out += OBracketed
for {
}
out += CBracketed
}
}
return string(out)
}
func parseBracketed() {
}

View File

@ -60,17 +60,18 @@ package z
// ------------------------------- core -------------------------------
// Nd ("node") is a named sequence of expressions that will be captured
// as a new Node and added to the scan.R.Nodes field effectively turning
// the scan.R into a parser as well. 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.Nd) 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 Nd []any
// P ("parse") is a named sequence of expressions that will be parsed
// and captured as a new Node and added to the scan.R.Nodes field
// effectively turning the scan.R into a parser as well. 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
// scan.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.P)
// 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 P []any
// X ("expression") is a sequence of expressions. If any are not the
// scan fails. (Equal to (?foo) in regular expressions.)
@ -78,13 +79,12 @@ type X []any
// ------------------------------- sets -------------------------------
// P ("positive") is a set of positive lookahead expressions. If any are
// Y ("yes") is a set of positive lookahead expressions. If any are
// seen at the current cursor position the scan will proceed without
// consuming them (unlike z.O and z.I). If none are found the scan
// fails. This is useful when everything from one expression is wanted
// except for a few positive exceptions. (Equal to ampersand (&) in
// fails. (Equal to ampersand (&) in
// PEGN.)
type P []any
type Y []any
// N ("not") is a set of negative lookahead expressions. If any are seen
// at the current cursor position the scan will fail and the scan is

View File

@ -63,6 +63,10 @@ type R struct {
// added as more state-modifying single-token expressions are
// considered (like tk.IS and tk.NOT now).
State int
// Nodes contains a collection of Nodes parsed when a z.P expression
// is scanned by Expect.
Nodes []*Node
}
const (
@ -224,6 +228,21 @@ func (s *R) Peek(n uint) string {
return buf
}
// Parse creates a new Node reference from the string returned by Look.
func (s *R) Parse(to *Cur) *Node {
n := new(Node)
n.V = s.Look(to)
return n
}
// ParseSlice creates a new Node reference from the string returned by
// LookSlice.
func (s *R) ParseSlice(b *Cur, e *Cur) *Node {
n := new(Node)
n.V = s.LookSlice(b, e)
return n
}
// Look returns a string containing all the bytes from the current
// scanner cursor position ahead or behind to the passed cursor
// position. Neither the internal nor the passed cursor position is
@ -371,7 +390,7 @@ func (s *R) Expect(expr any) (*Cur, error) {
s.Jump(m)
return nil, s.ErrorExpected(v)
case z.P: // ----------------------------------------------------
case z.Y: // ----------------------------------------------------
var m *Cur
b := s.Mark()
for _, i := range v {
@ -547,7 +566,7 @@ func (s *R) ErrorExpected(this any, args ...any) error {
switch v := this.(type) {
case rune: // otherwise will use uint32
msg = fmt.Sprintf(`expected rune %q`, v)
case z.P:
case z.Y:
if len(v) > 1 {
msg = fmt.Sprintf(`expected one of %q`, v)
} else {

View File

@ -163,6 +163,29 @@ func ExampleNewLine() {
// U+0073 's' 2,1-1 (1-1)
}
func ExampleR_Parse() {
s, _ := scan.New("some thing")
s.Snap()
s.ScanN(5)
m := s.Mark()
s.Back()
n := s.Parse(m)
n.Print()
// Output:
// {"V":"some t"}
}
func ExampleR_ParseSlice() {
s, _ := scan.New("some thing")
b := s.Mark()
s.ScanN(5)
e := s.Mark()
n := s.ParseSlice(b, e)
n.Print()
// Output:
// {"V":"some t"}
}
func ExampleErrorExpected() {
s, _ := scan.New("some thing")
fmt.Println(s.ErrorExpected("foo"))
@ -226,7 +249,7 @@ func ExampleExpect_compound_Expr_Rune() {
func ExampleExpect_it_Success() {
s, _ := scan.New("some thing")
c, _ := s.Expect(z.P{"some"})
c, _ := s.Expect(z.Y{"some"})
c.Print() // even though true, not moved
s.Print() // scanner also not moved
// Output:
@ -236,7 +259,7 @@ func ExampleExpect_it_Success() {
func ExampleExpect_it_Success_Middle() {
s, _ := scan.New("some thing")
c, _ := s.Expect(z.X{"some", z.P{' '}})
c, _ := s.Expect(z.X{"some", z.Y{' '}})
c.Print() // advanced up to (but not including) ' '
s.Print() // scanner also not moved
// Output:
@ -246,7 +269,7 @@ func ExampleExpect_it_Success_Middle() {
func ExampleExpect_it_Fail() {
s, _ := scan.New("some thing")
_, err := s.Expect(z.X{"some", z.P{"thing"}})
_, err := s.Expect(z.X{"some", z.Y{"thing"}})
fmt.Println(err)
s.Print() // but scanner did get "some" so advanced
// Output:
@ -256,7 +279,7 @@ func ExampleExpect_it_Fail() {
func ExampleExpect_it_Fail_X() {
s, _ := scan.New("some thing")
_, err := s.Expect(z.X{"some", z.P{"thing"}})
_, err := s.Expect(z.X{"some", z.Y{"thing"}})
fmt.Println(err)
s.Print() // but scanner did get "some" so advanced
// Output: