func ExampleBind() { var r interface{} var ok bool prt := func() { if ok { fmt.Printf("Result: %s\n", r) } else { fmt.Printf("Error: %v\n", r) } } lower := kern.Regexp(`\p{Ll}`) intNum := kern.Regexp(`\p{Nd}*`) p := kern.Bind(lower, func(c interface{}) kern.Parser { return kern.Bind(intNum, func(d interface{}) kern.Parser { return kern.Bind(lower, func(e interface{}) kern.Parser { return kern.Return(utf88.Surr(c.(utf88.Text)) + "," + utf88.Surr(d.(utf88.Text)) + "," + utf88.Surr(e.(utf88.Text))) }) }) }) t := utf88.Text("e789fg") r, ok = kern.ParseText(p, t) prt() // Output: // Result: e,789,f }
// PrintState prints the parser state, along with the supplied message, // to the standard output. func PrintState(msg u8.Text) Parser { return func(s PState) (so PState) { fmt.Printf(u8.Surr(msg)+" %v\n", s) so = s.clone(func(e *PState) {}) return } }
func ExampleOption() { var r interface{} var ok bool prt := func() { if ok { fmt.Printf("Result: %s\n", utf88.Surr(r.(utf88.Text))) } else { fmt.Printf("Error: %v\n", r) } } letter := kern.Regexp(`\pL`) p := kern.Option(utf88.Text("None."), letter) t := utf88.Text("abc") u := utf88.Text("789") r, ok = kern.ParseText(p, t) prt() r, ok = kern.ParseText(p, u) prt() // Output: // Result: a // Result: None. }
// Print prints the parser state, along with the supplied message, // to the standard output before executing the enclosed parser. // It can be used for diagnostics. func Print(msg u8.Text, p Parser) Parser { return func(s PState) (so PState) { fmt.Printf(u8.Surr(msg)+" %v\n", s) so = p(s) return } }
func ExampleAlt() { var r interface{} var ok bool prt := func() { if ok { fmt.Printf("Result: %s\n", utf88.Surr(r.(utf88.Text))) } else { fmt.Printf("Error: %v\n", r) } } lower := kern.Regexp(`\p{Ll}`) upper := kern.Regexp(`\p{Lu}`) digit := kern.Regexp(`\p{Nd}`) p := kern.Alt(lower, digit) q := kern.Alt(lower, digit, upper) t := utf88.Text("7ef") u := utf88.Text(";ef") r, ok = kern.ParseText(p, t) prt() r, ok = kern.ParseText(p, u) prt() r, ok = kern.ParseText(q, t) prt() // Output: // Result: 7 // Error: No alternatives selected. // Result: 7 }
func ExampleTry() { p := kern.Flatten(kern.Regexp(`\pL`), kern.Regexp(`\pL`)) q := kern.Flatten(kern.Regexp(`\pL`), kern.Regexp(`\pN`)) t := utf88.Text("a7bcde") var r interface{} var ok bool prt := func() { if ok { fmt.Printf("Result: %s\n", utf88.Surr(r.(utf88.Text))) } else { fmt.Printf("Error: %v\n", r) } } r, ok = kern.ParseText(kern.Alt(p, q), t) prt() r, ok = kern.ParseText(kern.Alt(kern.Try(p), q), t) prt() // Output: // Error: Unexpected 7 input. // Result: a7 }
// ParseText accepts a Parser and some text, utf88-surrogates it to a string, // and applies the parser to it. It returns the value if it succeeds, // and returns the error if it fails. func ParseText(p Parser, tx u8.Text) (result interface{}, ok bool) { s := parseStr(p, u8.Surr(tx)) if s.ok { return s.value, true } else { return s.error, false } }
// SetInput sets the input stream in a parser state. func SetInput(in u8.Text) Parser { return func(s PState) PState { return s.clone(func(e *PState) { e.input = u8.Surr(in) e.ok = true e.empty = true e.error = "" }) } }
// SetInputAndPosition sets the input stream and current position in a parser state. func SetInputAndPosition(iap InputAndPosition) Parser { return func(s PState) PState { return s.clone(func(e *PState) { e.input = u8.Surr(iap.inp) e.pos = iap.pos e.ok = true e.empty = true e.error = "" }) } }
func ExampleRegexp() { p := kern.Regexp(`z|a|b`) t := utf88.Text("abc") r, ok := kern.ParseText(p, t) if ok { fmt.Printf("Result: %s\n", utf88.Surr(r.(utf88.Text))) } else { fmt.Printf("Error: %v\n", r) } // Output: // Result: a }
func ExampleToken() { p := kern.Token(utf88.Text("ab")) t := utf88.Text("abc") r, ok := kern.ParseText(p, t) if ok { fmt.Printf("Result: %s\n", utf88.Surr(r.(utf88.Text))) } else { fmt.Printf("Error: %v\n", r) } // Output: // Result: ab }
// Fail fails without consuming any input, having a single error message msg encoded as utf88 text. func Fail(msg u8.Text) Parser { return func(st PState) (so PState) { if log["Fail"] || (len(st.log) > 0 && st.log[len(st.log)-1] && loggingEnabled) { defer logFnEq("Fail", &so) } so = st.clone(func(e *PState) { e.value = nil e.ok = false e.empty = true e.error = u8.Surr(msg) }) return } }
func ExampleSeqRight() { digit := kern.Regexp(`\p{Nd}`) letter := kern.Regexp(`\pL`) p := kern.SeqRight(digit, letter) t := utf88.Text("7efg") r, ok := kern.ParseText(p, t) if ok { fmt.Printf("Result: %s\n", utf88.Surr(r.(utf88.Text))) } else { fmt.Printf("Error: %v\n", r) } // Output: // Result: e }
func ExampleApply() { letter := kern.Regexp(`\pL`) p := kern.Apply(func(c interface{}) interface{} { cs := utf88.Surr(c.(utf88.Text)) return cs + cs + cs }, letter) t := utf88.Text("abc") r, ok := kern.ParseText(p, t) if ok { fmt.Printf("Result: %s\n", r) } else { fmt.Printf("Error: %v\n", r) } // Output: // Result: aaa }
// Token succeeds if the next Codepoint/s equals the given Text, in which case it // advances the position of the input stream. It may fail on an unexpected end of input. func Token(t u8.Text) Parser { tok := u8.Surr(t) return func(st PState) (so PState) { if log["Token"] || (len(st.log) > 0 && st.log[len(st.log)-1] && loggingEnabled) { defer logFnBA("Token", &st, &so) } if len(tok) == 0 { so = st.clone(func(e *PState) { e.value = nil e.ok = false e.empty = true e.error = errEmptyStr }) return } else if st.input == "" || len(st.input) < len(tok) { so = st.clone(func(e *PState) { e.value = nil e.ok = false e.empty = true e.error = errUnexpEof }) return } else if st.input[:len(tok)] == tok { so = st.clone(func(e *PState) { e.input = st.input[len(tok):] e.pos = st.pos + uint64(len(tok)) e.value = t e.ok = true e.empty = false e.error = "" }) return } else { so = st.clone(func(e *PState) { e.value = nil e.ok = false e.empty = true e.error = makeUnexpInp(st.input[:len(tok)]) }) return } } }
// Flatten applies one or more parsers; flattens the result and // converts it to text. Same functionality as <+> in Clojure's kern. func Flatten(ps ...Parser) Parser { var f func(c interface{}) interface{} f = func(c interface{}) interface{} { s := "" for _, n := range c.([]interface{}) { if _, isText := n.(u8.Text); !isText { n = f(n) } s = s + u8.Surr(n.(u8.Text)) } return u8.Desur(s) } switch len(ps) { case 0: return Fail(u8.Desur(errNoParser)) case 1: return Apply(f, ps[0]) default: return Apply(f, Collect(ps...)) } }
func ExampleFwdWithParams() { var expr func(...interface{}) kern.Parser paren := func(as ...interface{}) kern.Parser { return kern.SeqRight(kern.Token(utf88.Text(string('('))), kern.SeqLeft(kern.FwdWithParams(expr, as...), // FwdWithParams will evaluate passed expression lazily kern.Token(utf88.Text(string(')'))))) } expr = func(as ...interface{}) kern.Parser { // will parse string enclosed in parenthesis pairs to any depth return kern.Alt(kern.Token(utf88.Text(string('a'))), paren(as...)) } t := utf88.Text("(((a)))") r, ok := kern.ParseText(expr(101, 102), t) // call expr with extra (unused in this e.g.) args if ok { fmt.Printf("Result: %s\n", utf88.Surr(r.(utf88.Text))) } else { fmt.Printf("Error: %v\n", r) } // Output: // Result: a }
func ExampleFwd() { var expr func() kern.Parser paren := func() kern.Parser { return kern.SeqRight(kern.Token(utf88.Text(string('('))), kern.SeqLeft(kern.Fwd(expr), // Fwd will evaluate passed expression lazily kern.Token(utf88.Text(string(')'))))) } expr = func() kern.Parser { // will parse string enclosed in parenthesis pairs to any depth return kern.Alt(kern.Token(utf88.Text(string('a'))), paren()) } t := utf88.Text("(((a)))") r, ok := kern.ParseText(expr(), t) if ok { fmt.Printf("Result: %s\n", utf88.Surr(r.(utf88.Text))) } else { fmt.Printf("Error: %v\n", r) } // Output: // Result: a }