Example #1
0
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
}
Example #2
0
// 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
	}
}
Example #3
0
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.
}
Example #4
0
// 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
	}
}
Example #5
0
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
}
Example #6
0
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
}
Example #7
0
// 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
	}
}
Example #8
0
// 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 = ""
		})
	}
}
Example #9
0
// 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 = ""
		})
	}
}
Example #10
0
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
}
Example #11
0
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
}
Example #12
0
// 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
	}
}
Example #13
0
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
}
Example #14
0
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
}
Example #15
0
// 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
		}
	}
}
Example #16
0
// 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...))
	}
}
Example #17
0
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
}
Example #18
0
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
}