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
}
Exemple #3
0
//================================================================================
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})
	})
}
Exemple #4
0
//================================================================================
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}})
	})
}
Exemple #5
0
//================================================================================
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...)
	})
}