func ExampleParseString() { var r interface{} var ok bool prt := func() { if ok { fmt.Printf("Result: %c\n", r) } else { fmt.Printf("Error: %v\n", r) } } p := kern.Symbol(utf88.Codepoint('a')) t := "abc" r, ok = kern.ParseString(p, t) prt() u := "defg" r, ok = kern.ParseString(p, u) prt() // Output: // Result: a // Error: Unexpected d input. }
func ExampleSymbol() { p := kern.Symbol(utf88.Codepoint('a')) t := utf88.Text("abc") r, ok := kern.ParseText(p, t) if ok { fmt.Printf("Result: %c\n", r) } else { fmt.Printf("Error: %v\n", r) } // Output: // Result: a }
//================================================================================ func TestState(t *testing.T) { ts.LogAsserts("State", t, func(tt *ts.T) { incrIfNewline := func(x interface{}) Parser { if x.(u8.Codepoint) == u8.Codepoint('\n') { return ModifyState(func(n interface{}, _ ...interface{}) interface{} { return n.(int) + 1 }) } else { return Return(nil) } } p2 := SeqRight(PutState(21), Bind(AnyChar, incrIfNewline)) tt.AssertEqual(parseStr(p2, "\naa"), PState{input: "aa", pos: 1, value: u8.Codepoint('\n'), ok: true, user: 22}) tt.AssertEqual(parseStr(p2, "aaa"), PState{input: "aa", pos: 1, value: nil, ok: true, user: 21}) tt.AssertEqual(parseStr(p2, "aa\naa\na"), PState{input: "a\naa\na", pos: 1, value: nil, ok: true, user: 21}) p1 := SeqRight(PutState(21), Bind(AnyChar, incrIfNewline), GetState) tt.AssertEqual(parseStr(p1, "\naa"), PState{input: "aa", pos: 1, value: 22, ok: true, user: 22}) tt.AssertEqual(parseStr(p1, "aaa"), PState{input: "aa", pos: 1, value: 21, ok: true, user: 21}) tt.AssertEqual(parseStr(p1, "aa\naa\na"), PState{input: "a\naa\na", pos: 1, value: 21, ok: true, user: 21}) p3 := SeqRight(PutState(21), Bind(AnyChar, incrIfNewline), AnyChar) tt.AssertEqual(parseStr(p3, "\naa"), PState{input: "a", pos: 2, value: u8.Codepoint('a'), ok: true, user: 22}) tt.AssertEqual(parseStr(p3, "aaa"), PState{input: "a", pos: 2, value: u8.Codepoint('a'), ok: true, user: 21}) tt.AssertEqual(parseStr(p3, "aa\naa\na"), PState{input: "\naa\na", pos: 2, value: u8.Codepoint('a'), ok: true, user: 21}) tt.AssertEqual(parseStr(p3, "a\naa\na"), PState{input: "aa\na", pos: 2, value: u8.Codepoint('\n'), ok: true, user: 21}) }) }
//================================================================================ func TestStateMap(t *testing.T) { ts.LogAsserts("StateMap", t, func(tt *ts.T) { init := PutStateMapEntry("counter", 123) //-------------------------------------------------------------------------------- getB := func(x interface{}) Parser { if x.(u8.Codepoint) == u8.Codepoint('\n') { return GetStateMapEntry("counter") } else { return Return(nil) } } p1 := SeqRight(init, Bind(AnyChar, getB)) tt.AssertEqual(parseStr(p1, "\nbc"), PState{input: "bc", pos: 1, value: 123, ok: true, user: map[string]interface{}{"counter": 123}}) tt.AssertEqual(parseStr(p1, "abc"), PState{input: "bc", pos: 1, value: nil, ok: true, user: map[string]interface{}{"counter": 123}}) //-------------------------------------------------------------------------------- solePutB := func(x interface{}) (p Parser) { if x.(u8.Codepoint) == u8.Codepoint('\n') { return Return(nil) } else { return PutStateMapEntry("counter", 777) } } p2 := SeqRight(init, Bind(AnyChar, solePutB)) tt.AssertEqual(parseStr(p2, "\nbc"), PState{input: "bc", pos: 1, value: nil, ok: true, user: map[string]interface{}{"counter": 123}}) tt.AssertEqual(parseStr(p2, "abc"), PState{input: "bc", pos: 1, value: map[string]interface{}{"counter": 123}, ok: true, user: map[string]interface{}{"counter": 777}}) //-------------------------------------------------------------------------------- putB := func(x interface{}) (p Parser) { if x.(u8.Codepoint) == u8.Codepoint('\n') { return GetStateMapEntry("counter") } else { return Bind(PutStateMapEntry("counter", 777), func(_ interface{}) Parser { return GetStateMapEntry("counter") }) } } p3 := SeqRight(init, Bind(AnyChar, putB)) tt.AssertEqual(parseStr(p3, "\nbc"), PState{input: "bc", pos: 1, value: 123, ok: true, user: map[string]interface{}{"counter": 123}}) tt.AssertEqual(parseStr(p3, "abc"), PState{input: "bc", pos: 1, value: 777, ok: true, user: map[string]interface{}{"counter": 777}}) p4 := Bind(AnyChar, putB) tt.AssertEqual(parseStr(p4, "\nbc"), PState{input: "bc", pos: 1, value: nil, ok: true}) tt.AssertEqual(parseStr(p4, "abc"), PState{input: "bc", pos: 1, value: 777, ok: true, user: map[string]interface{}{"counter": 777}}) p5 := SeqRight(Return(nil), Bind(AnyChar, putB)) tt.AssertEqual(parseStr(p5, "\nbc"), PState{input: "bc", pos: 1, value: nil, ok: true}) tt.AssertEqual(parseStr(p5, "abc"), PState{input: "bc", pos: 1, value: 777, ok: true, user: map[string]interface{}{"counter": 777}}) //-------------------------------------------------------------------------------- soleIncrIfNewline := func(x interface{}) Parser { if x.(u8.Codepoint) == u8.Codepoint('\n') { return ModifyStateMapEntry("counter", func(n interface{}, _ ...interface{}) interface{} { return n.(int) + 1 }) } else { return Return(nil) } } p20 := SeqRight(init, Bind(AnyChar, soleIncrIfNewline)) tt.AssertEqual(parseStr(p20, "\nbc"), PState{input: "bc", pos: 1, value: map[string]interface{}{"counter": 123}, ok: true, user: map[string]interface{}{"counter": 124}}) tt.AssertEqual(parseStr(p20, "abc"), PState{input: "bc", pos: 1, value: nil, ok: true, user: map[string]interface{}{"counter": 123}}) //-------------------------------------------------------------------------------- incrIfNewline := func(x interface{}) Parser { if x.(u8.Codepoint) == u8.Codepoint('\n') { return Bind(ModifyStateMapEntry("counter", func(n interface{}, _ ...interface{}) interface{} { return n.(int) + 1 }), func(_ interface{}) Parser { return GetStateMapEntry("counter") }) } else { return GetStateMapEntry("counter") } } p21 := SeqRight(init, Bind(AnyChar, incrIfNewline)) tt.AssertEqual(parseStr(p21, "\nbc"), PState{input: "bc", pos: 1, value: 124, ok: true, user: map[string]interface{}{"counter": 124}}) tt.AssertEqual(parseStr(p21, "abc"), PState{input: "bc", pos: 1, value: 123, ok: true, user: map[string]interface{}{"counter": 123}}) }) }
//================================================================================ func TestLexer(t *testing.T) { ts.LogAsserts("Lexer", t, func(tt *ts.T) { u := NewUnicodeLexer() tt.AssertEqual(parseStr(u.Letter(), "defg"), PState{input: "efg", pos: 1, value: u8.Text("d"), ok: true}) tt.AssertEqual(parseStr(u.Letter(), ";efg"), PState{input: ";efg", empty: true, error: makeUnexpInp(";")}) tt.AssertEqual(parseStr(u.Lower(), "defg"), PState{input: "efg", pos: 1, value: u8.Text("d"), ok: true}) tt.AssertEqual(parseStr(u.Lower(), "Defg"), PState{input: "Defg", empty: true, error: makeUnexpInp("D")}) tt.AssertEqual(parseStr(u.Lower(), ";efg"), PState{input: ";efg", empty: true, error: makeUnexpInp(";")}) tt.AssertEqual(parseStr(u.Upper(), "Defg"), PState{input: "efg", pos: 1, value: u8.Text("D"), ok: true}) tt.AssertEqual(parseStr(u.Upper(), "defg"), PState{input: "defg", empty: true, error: makeUnexpInp("d")}) tt.AssertEqual(parseStr(u.Upper(), ";efg"), PState{input: ";efg", empty: true, error: makeUnexpInp(";")}) tt.AssertEqual(parseStr(u.Digit(), "6efg"), PState{input: "efg", pos: 1, value: u8.Text("6"), ok: true}) tt.AssertEqual(parseStr(u.Digit(), "defg"), PState{input: "defg", empty: true, error: makeUnexpInp("d")}) tt.AssertEqual(parseStr(u.Whitespace(), " efg"), PState{input: "efg", pos: 1, value: u8.Codepoint(' '), ok: true}) tt.AssertEqual(parseStr(u.Whitespace(), "\tefg"), PState{input: "efg", pos: 1, value: u8.Codepoint('\t'), ok: true}) tt.AssertEqual(parseStr(u.Whitespace(), "\refg"), PState{input: "efg", pos: 1, value: u8.Codepoint('\r'), ok: true}) tt.AssertEqual(parseStr(u.Whitespace(), "\nefg"), PState{input: "efg", pos: 1, value: u8.Codepoint('\n'), ok: true}) tt.AssertEqual(parseStr(u.Whitespace(), "\fefg"), PState{input: "efg", pos: 1, value: u8.Codepoint('\f'), ok: true}) tt.AssertEqual(parseStr(u.Whitespace(), "\vefg"), PState{input: "efg", pos: 1, value: u8.Codepoint('\v'), ok: true}) tt.AssertEqual(parseStr(u.Whitespace(), "defg"), PState{input: "defg", empty: true, error: makeUnexpInp("d")}) tt.AssertEqual(parseStr(u.Space(), " efg"), PState{input: "efg", pos: 1, value: u8.Text(" "), ok: true}) tt.AssertEqual(parseStr(u.Space(), "defg"), PState{input: "defg", empty: true, error: makeUnexpInp("d")}) // TitlecaseLetter() Parser{ return Regexp(`\p{Lt}`) // ModifyingLetter() Parser{ return Regexp(`\p{Lm}`) // OtherLetter() Parser{ return Regexp(`\p{Lo}`) // Number() Parser{ return Regexp(`\pN`) // LetterNumber() Parser{ return Regexp(`\p{Nl}`) // OtherNumber() Parser{ return Regexp(`\p{No}`) // Mark() Parser{ return Regexp(`\pM`) // SpacingMark() Parser{ return Regexp(`\p{Mc}`) // EnclosingMark() Parser{ return Regexp(`\p{Me}`) // NonspacingMark() Parser{ return Regexp(`\p{Mn}`) // Punct() Parser{ return Regexp(`\pP`) // StartPunct() Parser{ return Regexp(`\p{Ps}`) // EndPunct() Parser{ return Regexp(`\p{Pe}`) // InitialPunct() Parser{ return Regexp(`\p{Pi}`) // FinalPunct() Parser{ return Regexp(`\p{Pf}`) // ConnectorPunct() Parser{ return Regexp(`\p{Pc}`) // DashPunct() Parser{ return Regexp(`\p{Pd}`) // OtherPunct() Parser{ return Regexp(`\p{Po}`) // Symbol() Parser{ return Regexp(`\pS`) // CurrencySymbol() Parser{ return Regexp(`\p{Sc}`) // MathSymbol() Parser{ return Regexp(`\p{Sm}`) // ModifierSymbol() Parser{ return Regexp(`\p{Sk}`) // OtherSymbol() Parser{ return Regexp(`\p{So}`) // Spacing() Parser{ return Regexp(`\pZ`) // LineSeparator() Parser{ return Regexp(`\p{Zl}`) // ParagraphSeparator() Parser{ return Regexp(`\p{Zp}`) // OtherCategory() Parser{ return Regexp(`\pC`) // Control() Parser{ return Regexp(`\p{Cc}`) // Format() Parser{ return Regexp(`\p{Cf}`) // PrivateUse() Parser{ return Regexp(`\p{Co}`) // Nonchar() Parser{ return Regexp(`\p{Cn}`) // Surrogate() Parser{ return Regexp(`\p{Cs}`) // Graphical() Parser{ return len(cc) == 1 && unicode.IsGraphic(cc[0]) // Printable() Parser{ return len(cc) == 1 && unicode.IsPrint(cc[0]) // SpecialControl() Parser{ return len(cc) == 1 && unicode.IsControl(cc[0]) // CommonScript() Parser{ return len(cc) == 1 && unicode.In(cc[0], unicode.Common) // InheritedScript() Parser{ return len(cc) == 1 && unicode.In(cc[0], unicode.Inherited) // UnicodeIn(ranges ...*unicode.RangeTable) Parser { return len(cc) == 1 && unicode.In(cc[0], ranges...) }) }