76 lines
2.8 KiB
Go
76 lines
2.8 KiB
Go
// In this example, a Parser is created that can parse and normalize Dutch postcodes
|
|
// The implementation uses only Handler functions and does not implement a
|
|
// full-fledged state-based Parser for it.
|
|
|
|
package examples
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"git.makaay.nl/mauricem/go-parsekit/tokenize"
|
|
)
|
|
|
|
func Example_dutchPostcodeUsingTokenizer() {
|
|
tokenizer := createPostcodeTokenizer()
|
|
|
|
for i, input := range []string{
|
|
"1234 AB",
|
|
"2233Ab",
|
|
"1001\t\tab",
|
|
"1818ab",
|
|
"1212abc",
|
|
"1234",
|
|
"huh",
|
|
"",
|
|
"\xcd2222AB",
|
|
} {
|
|
result, err := tokenizer(input)
|
|
if err != nil {
|
|
fmt.Printf("[%d] Input: %q Error: %s\n", i, input, err)
|
|
} else {
|
|
fmt.Printf("[%d] Input: %q Output: %s Tokens:", i, input, result)
|
|
for _, t := range result.Tokens() {
|
|
fmt.Printf(" %s(%s)", t.Type, t.Value)
|
|
}
|
|
fmt.Printf("\n")
|
|
}
|
|
}
|
|
// Output:
|
|
// [0] Input: "1234 AB" Output: 1234 AB Tokens: PCD(1234) 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)
|
|
// [3] Input: "1818ab" Output: 1818 AB Tokens: PCD(1818) PCL(AB)
|
|
// [4] Input: "1212abc" Error: mismatch at start of file
|
|
// [5] Input: "1234" Error: mismatch at start of file
|
|
// [6] Input: "huh" Error: mismatch at start of file
|
|
// [7] Input: "" Error: mismatch at start of file
|
|
// [8] Input: "\xcd2222AB" Error: mismatch at start of file
|
|
}
|
|
|
|
// ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
|
|
// Implementation of the parser
|
|
// ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
|
|
|
|
func createPostcodeTokenizer() tokenize.Func {
|
|
// Easy access to the tokenize definitions.
|
|
a, m, t := tokenize.A, tokenize.M, tokenize.T
|
|
|
|
// Handler functions are created and combined to satisfy these rules:
|
|
// • A Dutch postcode consists of 4 digits and 2 letters (1234XX).
|
|
// • The first digit is never a zero.
|
|
// • A space between letters and digits is optional.
|
|
// • It is good form to write the letters in upper case.
|
|
// • It is good form to use a single space between digits and letters.
|
|
pcDigits := a.DigitNotZero.Then(a.Digit.Times(3))
|
|
tokDigits := t.Str("PCD", pcDigits)
|
|
pcLetter := a.ASCIILower.Or(a.ASCIIUpper)
|
|
pcLetters := m.ToUpper(pcLetter.Times(2))
|
|
tokLetters := t.Str("PCL", pcLetters)
|
|
space := m.Replace(a.Blanks.Optional(), " ")
|
|
postcode := tokDigits.Then(space).Then(tokLetters).Then(a.EndOfFile)
|
|
|
|
// Create a Tokenizer that wraps the 'postcode' Handler and allows
|
|
// us to match some input against that handler.
|
|
return tokenize.New(postcode)
|
|
}
|