Brought the examples up-to-date with the lateset code. All are working correctly now.
This commit is contained in:
parent
40bad51064
commit
05ae55c487
|
@ -70,7 +70,7 @@ type simpleCalculator struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// A definition of an int64, which conveniently drops surrounding blanks.
|
// A definition of an int64, which conveniently drops surrounding blanks.
|
||||||
var dropBlank = parsekit.M.Drop(parsekit.C.Opt(parsekit.A.Blank))
|
var dropBlank = parsekit.M.Drop(parsekit.C.Opt(parsekit.A.Blanks))
|
||||||
var bareInteger = parsekit.C.Seq(dropBlank, parsekit.A.Integer, dropBlank)
|
var bareInteger = parsekit.C.Seq(dropBlank, parsekit.A.Integer, dropBlank)
|
||||||
var int64Token = parsekit.T.Int64(nil, bareInteger)
|
var int64Token = parsekit.T.Int64(nil, bareInteger)
|
||||||
|
|
||||||
|
|
|
@ -53,9 +53,9 @@ func Example_basicCalculator2() {
|
||||||
// Input: "(3.05+2)*(4.3+5.12)", got outcome: 47.571000, correct = true
|
// Input: "(3.05+2)*(4.3+5.12)", got outcome: 47.571000, correct = true
|
||||||
// Input: "8.10 + 999/233", got outcome: 12.387554, correct = true
|
// Input: "8.10 + 999/233", got outcome: 12.387554, correct = true
|
||||||
// Input: " -10 + (10.8+ (3 *-20-3*(8 +-4.12)) + 10)/5 ", got outcome: -20.168000, correct = true
|
// Input: " -10 + (10.8+ (3 *-20-3*(8 +-4.12)) + 10)/5 ", got outcome: -20.168000, correct = true
|
||||||
// Input: "", got error: unexpected end of file at start of file
|
// Input: "", got error: unexpected end of file (expected factor or parenthesized expression) at start of file
|
||||||
// Input: "(", got error: unexpected end of file at line 1, column 2
|
// Input: "(", got error: unexpected end of file (expected factor or parenthesized expression) at line 1, column 2
|
||||||
// Input: "10+20-", got error: unexpected end of file at line 1, column 7
|
// Input: "10+20-", got error: unexpected end of file (expected factor or parenthesized expression) at line 1, column 7
|
||||||
// Input: "10+20-(4*10))", got error: unexpected input (expected end of file) at line 1, column 13
|
// Input: "10+20-(4*10))", got error: unexpected input (expected end of file) at line 1, column 13
|
||||||
// Input: "10+20-((4*10) + 17", got error: unexpected end of file (expected ')') at line 1, column 19
|
// Input: "10+20-((4*10) + 17", got error: unexpected end of file (expected ')') at line 1, column 19
|
||||||
}
|
}
|
||||||
|
@ -76,67 +76,67 @@ type calculator struct {
|
||||||
// value for the calculation. An error can be returned as well, in case the
|
// value for the calculation. An error can be returned as well, in case the
|
||||||
// calculation fails for some reason.
|
// calculation fails for some reason.
|
||||||
func Compute(input string) (float64, *parsekit.Error) {
|
func Compute(input string) (float64, *parsekit.Error) {
|
||||||
c := &calculator{}
|
calc := &calculator{}
|
||||||
parser := parsekit.NewParser(c.calculation)
|
parser := parsekit.NewParser(calc.calculation)
|
||||||
err := parser.Execute(input)
|
err := parser.Execute(input)
|
||||||
return c.result, err
|
return calc.result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// <calculation> = <expr> <EOF>
|
// <calculation> = <expr> <EOF>
|
||||||
func (c *calculator) calculation(p *parsekit.ParseAPI) {
|
func (calc *calculator) calculation(p *parsekit.ParseAPI) {
|
||||||
if p.Handle(c.expr) {
|
if p.Handle(calc.expr) {
|
||||||
p.ExpectEndOfFile()
|
p.ExpectEndOfFile()
|
||||||
c.result = c.interpreter.result
|
calc.result = calc.interpreter.result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// <expr> = (<term> | <term> (ADD|SUB) <term>)
|
// <expr> = (<term> | <term> (ADD|SUB) <term>)
|
||||||
func (c *calculator) expr(p *parsekit.ParseAPI) {
|
func (calc *calculator) expr(p *parsekit.ParseAPI) {
|
||||||
c.interpreter.push()
|
calc.interpreter.push()
|
||||||
|
|
||||||
var C, A = parsekit.C, parsekit.A
|
var C, A = parsekit.C, parsekit.A
|
||||||
if p.Handle(c.term) {
|
if p.Handle(calc.term) {
|
||||||
for p.On(C.Any(A.Add, A.Subtract)).Accept() {
|
for p.On(C.Any(A.Add, A.Subtract)).Accept() {
|
||||||
op := p.Result().Rune(0)
|
op := p.Result().Rune(0)
|
||||||
if !p.Handle(c.term) {
|
if !p.Handle(calc.term) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.interpreter.eval(op)
|
calc.interpreter.eval(op)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c.interpreter.pop()
|
calc.interpreter.pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
// <term> = (<factor> | <factor> (MUL|DIV) <factor>)
|
// <term> = (<factor> | <factor> (MUL|DIV) <factor>)
|
||||||
func (c *calculator) term(p *parsekit.ParseAPI) {
|
func (calc *calculator) term(p *parsekit.ParseAPI) {
|
||||||
c.interpreter.push()
|
calc.interpreter.push()
|
||||||
|
|
||||||
var C, A = parsekit.C, parsekit.A
|
var C, A = parsekit.C, parsekit.A
|
||||||
if p.Handle(c.factor) {
|
if p.Handle(calc.factor) {
|
||||||
for p.On(C.Any(A.Multiply, A.Divide)).Accept() {
|
for p.On(C.Any(A.Multiply, A.Divide)).Accept() {
|
||||||
op := p.Result().Rune(0)
|
op := p.Result().Rune(0)
|
||||||
if !p.Handle(c.factor) {
|
if !p.Handle(calc.factor) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.interpreter.eval(op)
|
calc.interpreter.eval(op)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c.interpreter.pop()
|
calc.interpreter.pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
// <space> = (<space> (SPACE|TAB) | "")
|
// <space> = (<space> (SPACE|TAB) | "")
|
||||||
// <factor> = <space> (FLOAT | LPAREN <expr> RPAREN) <space>
|
// <factor> = <space> (FLOAT | LPAREN <expr> RPAREN) <space>
|
||||||
func (c *calculator) factor(p *parsekit.ParseAPI) {
|
func (calc *calculator) factor(p *parsekit.ParseAPI) {
|
||||||
var A, T = parsekit.A, parsekit.T
|
var A, T = parsekit.A, parsekit.T
|
||||||
p.On(A.Blank).Skip()
|
p.On(A.Blanks).Skip()
|
||||||
switch {
|
switch {
|
||||||
case p.On(T.Float64(nil, A.Signed(A.Float))).Accept():
|
case p.On(T.Float64(nil, A.Signed(A.Float))).Accept():
|
||||||
value := p.Result().Value(0).(float64)
|
value := p.Result().Value(0).(float64)
|
||||||
c.interpreter.pushValue(value)
|
calc.interpreter.pushValue(value)
|
||||||
case p.On(A.LeftParen).Skip():
|
case p.On(A.LeftParen).Skip():
|
||||||
if !p.Handle(c.expr) {
|
if !p.Handle(calc.expr) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !p.On(A.RightParen).Skip() {
|
if !p.On(A.RightParen).Skip() {
|
||||||
|
@ -144,10 +144,10 @@ func (c *calculator) factor(p *parsekit.ParseAPI) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
p.UnexpectedInput("factor or (expression)")
|
p.UnexpectedInput("factor or parenthesized expression")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
p.On(A.Blank).Skip()
|
p.On(A.Blanks).Skip()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
|
@ -40,11 +40,11 @@ func Example_dutchPostcodeUsingTokenizer() {
|
||||||
// [1] Input: "2233Ab" Output: 2233 AB Tokens: PCD(2233) PCL(AB)
|
// [1] Input: "2233Ab" Output: 2233 AB Tokens: PCD(2233) PCL(AB)
|
||||||
// [2] Input: "1001\t\tab" Output: 1001 AB Tokens: PCD(1001) PCL(AB)
|
// [2] Input: "1001\t\tab" Output: 1001 AB Tokens: PCD(1001) PCL(AB)
|
||||||
// [3] Input: "1818ab" Output: 1818 AB Tokens: PCD(1818) PCL(AB)
|
// [3] Input: "1818ab" Output: 1818 AB Tokens: PCD(1818) PCL(AB)
|
||||||
// [4] Input: "1212abc" Error: unexpected input (expected a Dutch postcode) at start of file
|
// [4] Input: "1212abc" Error: unexpected input at start of file
|
||||||
// [5] Input: "1234" Error: unexpected input (expected a Dutch postcode) at start of file
|
// [5] Input: "1234" Error: unexpected input at start of file
|
||||||
// [6] Input: "huh" Error: unexpected input (expected a Dutch postcode) at start of file
|
// [6] Input: "huh" Error: unexpected input at start of file
|
||||||
// [7] Input: "" Error: unexpected end of file (expected a Dutch postcode) at start of file
|
// [7] Input: "" Error: unexpected end of file at start of file
|
||||||
// [8] Input: "\xcd2222AB" Error: unexpected input (expected a Dutch postcode) at start of file
|
// [8] Input: "\xcd2222AB" Error: unexpected input at start of file
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -65,7 +65,7 @@ func createPostcodeTokenizer() *parsekit.Tokenizer {
|
||||||
pcDigits := C.Seq(digitNotZero, C.Rep(3, A.Digit))
|
pcDigits := C.Seq(digitNotZero, C.Rep(3, A.Digit))
|
||||||
pcLetter := C.Any(A.ASCIILower, A.ASCIIUpper)
|
pcLetter := C.Any(A.ASCIILower, A.ASCIIUpper)
|
||||||
pcLetters := M.ToUpper(C.Seq(pcLetter, pcLetter))
|
pcLetters := M.ToUpper(C.Seq(pcLetter, pcLetter))
|
||||||
space := M.Replace(C.Opt(A.Blank), " ")
|
space := M.Replace(C.Opt(A.Blanks), " ")
|
||||||
postcode := C.Seq(T.Str("PCD", pcDigits), space, T.Str("PCL", pcLetters), A.EndOfFile)
|
postcode := C.Seq(T.Str("PCD", pcDigits), space, T.Str("PCL", pcLetters), A.EndOfFile)
|
||||||
|
|
||||||
// Create a Tokenizer that wraps the 'postcode' TokenHandler and allows
|
// Create a Tokenizer that wraps the 'postcode' TokenHandler and allows
|
||||||
|
|
|
@ -39,6 +39,7 @@ func Example_helloWorldUsingParser1() {
|
||||||
"hello , \t \t Droopy \t !",
|
"hello , \t \t Droopy \t !",
|
||||||
"Oh no!",
|
"Oh no!",
|
||||||
"hello,!",
|
"hello,!",
|
||||||
|
"hello, \t!",
|
||||||
} {
|
} {
|
||||||
name, err := (&helloparser1{}).Parse(input)
|
name, err := (&helloparser1{}).Parse(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -47,21 +48,22 @@ func Example_helloWorldUsingParser1() {
|
||||||
fmt.Printf("[%d] Input: %q Output: %s\n", i, input, name)
|
fmt.Printf("[%d] Input: %q Output: %s\n", i, input, name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Output:
|
// [0] Input: "Oh!" Error: unexpected input (expected hello)
|
||||||
// [0] Input: "Hello, world!" Output: world
|
// [1] Input: "Hello, world!" Output: world
|
||||||
// [1] Input: "HELLO ,Johnny!" Output: Johnny
|
// [2] Input: "HELLO ,Johnny!" Output: Johnny
|
||||||
// [2] Input: "hello , Bob123!" Output: Bob123
|
// [3] Input: "hello , Bob123!" Output: Bob123
|
||||||
// [3] Input: "hello Pizza!" Error: unexpected input (expected comma)
|
// [4] Input: "hello Pizza!" Error: unexpected input (expected comma)
|
||||||
// [4] Input: "" Error: unexpected end of file (expected hello)
|
// [5] Input: "" Error: unexpected end of file (expected hello)
|
||||||
// [5] Input: " " Error: unexpected input (expected hello)
|
// [6] Input: " " Error: unexpected input (expected hello)
|
||||||
// [6] Input: "hello" Error: unexpected end of file (expected comma)
|
// [7] Input: "hello" Error: unexpected end of file (expected comma)
|
||||||
// [7] Input: "hello," Error: unexpected end of file (expected name)
|
|
||||||
// [8] Input: "hello," Error: unexpected end of file (expected name)
|
// [8] Input: "hello," Error: unexpected end of file (expected name)
|
||||||
// [9] Input: "hello , Droopy" Error: unexpected end of file (expected exclamation)
|
// [9] Input: "hello , " Error: unexpected end of file (expected name)
|
||||||
// [10] Input: "hello , Droopy!" Output: Droopy
|
// [10] Input: "hello , Droopy" Error: unexpected end of file (expected exclamation mark)
|
||||||
// [11] Input: "hello , \t \t Droopy \t !" Output: Droopy
|
// [11] Input: "hello , Droopy!" Output: Droopy
|
||||||
// [12] Input: "Oh no!" Error: unexpected input (expected hello)
|
// [12] Input: "hello , \t \t Droopy \t !" Output: Droopy
|
||||||
// [13] Input: "hello,!" Error: unexpected input (expected name)
|
// [13] Input: "Oh no!" Error: unexpected input (expected hello)
|
||||||
|
// [14] Input: "hello,!" Error: The name cannot be empty
|
||||||
|
// [15] Input: "hello, \t!" Error: The name cannot be empty
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -90,7 +92,7 @@ func (h *helloparser1) start(p *parsekit.ParseAPI) {
|
||||||
func (h *helloparser1) comma(p *parsekit.ParseAPI) {
|
func (h *helloparser1) comma(p *parsekit.ParseAPI) {
|
||||||
a := parsekit.A
|
a := parsekit.A
|
||||||
switch {
|
switch {
|
||||||
case p.On(a.Blank).Skip():
|
case p.On(a.Blanks).Skip():
|
||||||
p.Handle(h.comma)
|
p.Handle(h.comma)
|
||||||
case p.On(a.Comma).Skip():
|
case p.On(a.Comma).Skip():
|
||||||
p.Handle(h.startName)
|
p.Handle(h.startName)
|
||||||
|
@ -100,13 +102,11 @@ func (h *helloparser1) comma(p *parsekit.ParseAPI) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *helloparser1) startName(p *parsekit.ParseAPI) {
|
func (h *helloparser1) startName(p *parsekit.ParseAPI) {
|
||||||
c, a := parsekit.C, parsekit.A
|
a := parsekit.A
|
||||||
switch {
|
p.On(a.Blanks).Skip()
|
||||||
case p.On(a.Blank).Skip():
|
if p.On(a.AnyRune).Stay() {
|
||||||
p.Handle(h.startName)
|
|
||||||
case p.On(c.Not(a.Excl)).Stay():
|
|
||||||
p.Handle(h.name)
|
p.Handle(h.name)
|
||||||
default:
|
} else {
|
||||||
p.UnexpectedInput("name")
|
p.UnexpectedInput("name")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,13 +114,13 @@ func (h *helloparser1) startName(p *parsekit.ParseAPI) {
|
||||||
func (h *helloparser1) name(p *parsekit.ParseAPI) {
|
func (h *helloparser1) name(p *parsekit.ParseAPI) {
|
||||||
a := parsekit.A
|
a := parsekit.A
|
||||||
switch {
|
switch {
|
||||||
case p.On(a.Excl).Skip():
|
case p.On(a.Excl).Stay():
|
||||||
p.Handle(h.exclamation)
|
p.Handle(h.exclamation)
|
||||||
case p.On(a.AnyRune).Accept():
|
case p.On(a.AnyRune).Accept():
|
||||||
h.greetee += p.Result().String()
|
h.greetee += p.Result().String()
|
||||||
p.Handle(h.name)
|
p.Handle(h.name)
|
||||||
default:
|
default:
|
||||||
p.UnexpectedInput("name")
|
p.UnexpectedInput("exclamation mark")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,9 +37,9 @@ func Example_helloWorldUsingTokenizer() {
|
||||||
// [1] Input: "HELLO ,Johnny!" Output: Johnny
|
// [1] Input: "HELLO ,Johnny!" Output: Johnny
|
||||||
// [2] Input: "hello , Bob123!" Output: Bob123
|
// [2] Input: "hello , Bob123!" Output: Bob123
|
||||||
// [3] Input: "hello Pizza!" Output: Pizza
|
// [3] Input: "hello Pizza!" Output: Pizza
|
||||||
// [4] Input: "Oh no!" Error: unexpected input (expected a friendly greeting) at start of file
|
// [4] Input: "Oh no!" Error: unexpected input at start of file
|
||||||
// [5] Input: "Hello, world" Error: unexpected input (expected a friendly greeting) at start of file
|
// [5] Input: "Hello, world" Error: unexpected input at start of file
|
||||||
// [6] Input: "Hello,!" Error: unexpected input (expected a friendly greeting) at start of file
|
// [6] Input: "Hello,!" Error: unexpected input at start of file
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in New Issue