Example extended.

This commit is contained in:
Maurice Makaay 2019-05-24 23:53:04 +00:00
parent 723e2a0c38
commit e9c618580d
1 changed files with 68 additions and 6 deletions

View File

@ -7,7 +7,7 @@ import (
"git.makaay.nl/mauricem/go-parsekit"
)
func Example_minimal() {
func Example_minimalAnnotated() {
// Let's write a small example for parsing a really basic calculator.
// The calculator understands input that looks like:
//
@ -65,15 +65,15 @@ func Example_minimal() {
}
// All is ready for our parser. We now can create a new Parser struct.
// We need to tell it what the start state is. In our case, it's the
// of course the number state.
// We need to tell it what the start state is. In our case, it is
// the number state, since the calculation must start with a number.
parser := parsekit.NewParser(numberHandler)
// Let's fee the parser some input to work with.
// Let's feed the parser some input to work with.
run := parser.Parse("153+ 22+31 - 4- 6+42")
// We can step through the results of the parsing process by repeated
// calls to run.Next(). Next() returns the next parse item, a parse
// We can now step through the results of the parsing process by repeated
// calls to run.Next(). Next() returns either the next parse item, a parse
// error or an end of file. Let's dump the parse results and handle the
// computation while we're at it.
sum := 0
@ -118,6 +118,68 @@ func Example_minimal() {
// Outcome of computation: 238
}
func Example_minimal() {
var c, a, m = parsekit.C, parsekit.A, parsekit.M
var number = c.OneOrMore(a.Digit)
var whitespace = m.Drop(c.Opt(a.Whitespace))
var operator = c.Seq(whitespace, c.Any(a.Plus, a.Minus), whitespace)
const (
numberType parsekit.ItemType = iota
operatorType
)
var operatorHandler parsekit.StateHandler
numberHandler := func(p *parsekit.P) {
p.Expects("a number")
if p.On(number).Accept().End() {
p.EmitLiteral(numberType)
p.RouteTo(operatorHandler)
}
}
operatorHandler = func(p *parsekit.P) {
if p.On(operator).Accept().End() {
p.EmitLiteral(operatorType)
p.RouteTo(numberHandler)
} else {
p.ExpectEndOfFile()
}
}
parser := parsekit.NewParser(numberHandler)
run := parser.Parse("153+ 22+31 - 4- 6+42")
sum := 0
op := +1
for {
item, err, ok := run.Next()
switch {
case !ok && err == nil:
fmt.Println("Outcome of computation:", sum)
return
case !ok:
fmt.Printf("Error: %s\n", err)
return
default:
switch {
case item.Type == operatorType && item.Value == "+":
op = +1
case item.Type == operatorType && item.Value == "-":
op = -1
default:
nr, _ := strconv.Atoi(item.Value)
sum += op * nr
}
}
}
// Output:
// Outcome of computation: 238
}
func ExampleItemType() {
// Make use of positive values. Ideally, define your ItemTypes using
// iota for easy automatic value management like this: