Skip to content

Commit

Permalink
Add example from the readme
Browse files Browse the repository at this point in the history
  • Loading branch information
askeladdk committed Jul 8, 2022
1 parent 85d89e1 commit 3bb74ec
Showing 1 changed file with 108 additions and 0 deletions.
108 changes: 108 additions & 0 deletions example_readme_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package prattle_test

import (
"fmt"
"strconv"
"unicode"

"github.com/askeladdk/prattle"
)

type driver struct {
stack []int
}

func (d *driver) push(i int) {
d.stack = append(d.stack, i)
}

func (d *driver) pop() (i int) {
n := len(d.stack)
i, d.stack = d.stack[n-1], d.stack[:n-1]
return
}

func (d *driver) number(p *prattle.Parser, t prattle.Token) error {
n, _ := strconv.Atoi(t.Text)
d.push(n)
return nil
}

func (d *driver) add(p *prattle.Parser, t prattle.Token) error {
// First parse the right hand operator.
if err := p.ParseExpression(d.Precedence(t.Kind)); err != nil {
return err
}

right := d.pop()
left := d.pop()
acc := left + right
fmt.Printf("%d + %d = %d\n", left, right, acc)
d.push(acc)
return nil
}

func (d *driver) Prefix(k int) prattle.ParseFunc {
if k == 2 {
return d.number
}
return nil
}

func (d *driver) Infix(k int) prattle.ParseFunc {
if k == 1 {
return d.add
}
return nil
}

func (d *driver) Statement(k int) prattle.ParseFunc {
return nil
}

func (d *driver) Precedence(k int) int {
return k
}

func (d *driver) ParseError(t prattle.Token) error {
return fmt.Errorf("%s", t)
}

// This example is described in the readme.
func Example_readme() {
scanner := prattle.Scanner{
Scan: func(s *prattle.Scanner) int {
// Skip whitespaces.
s.ExpectAny(unicode.IsSpace)
s.Skip()
switch {
case s.Done(): // Stop if the entire input has been consumed.
return 0
case s.Expect('+'):
return 1
case s.ExpectOne(unicode.IsDigit): // Read a number consisting of one or more digits.
s.ExpectAny(unicode.IsDigit)
return 2
}

s.Advance()
return -1
},
}

parser := prattle.Parser{
Driver: &driver{},
}

source := "1 + 23 + 456 + 7890"
scanner.InitWithString(source)
parser.Init(&scanner)
if err := parser.ParseExpression(0); err != nil {
fmt.Println(err)
}

// Output:
// 1 + 23 = 24
// 24 + 456 = 480
// 480 + 7890 = 8370
}

0 comments on commit 3bb74ec

Please sign in to comment.