summaryrefslogtreecommitdiffhomepage
path: root/mintages/parser.go
diff options
context:
space:
mode:
authorThomas Voss <mail@thomasvoss.com> 2024-08-10 20:16:48 +0200
committerThomas Voss <mail@thomasvoss.com> 2024-08-10 20:16:48 +0200
commit2e0d8c3889590253b091de5d1c12b1a4dadf1c8f (patch)
treef2854f3d4c0be012486721246f80ec55186b9403 /mintages/parser.go
parentd5c3c5f0f05e2f88dae1992c3269c01a0b924b49 (diff)
Do some renaming
Diffstat (limited to 'mintages/parser.go')
-rw-r--r--mintages/parser.go204
1 files changed, 0 insertions, 204 deletions
diff --git a/mintages/parser.go b/mintages/parser.go
deleted file mode 100644
index 9f0c66f..0000000
--- a/mintages/parser.go
+++ /dev/null
@@ -1,204 +0,0 @@
-package mintages
-
-import (
- "bufio"
- "fmt"
- "io"
- "strconv"
- "strings"
- "unicode"
-)
-
-const (
- _ = -iota
- Unknown // Unknown mintage
- Invalid // All mintages <= than this are invalid
-)
-
-type SyntaxError struct {
- expected, got string
- file string
- linenr int
-}
-
-func (e SyntaxError) Error() string {
- return fmt.Sprintf("%s:%d: syntax error: expected %s but got %s",
- e.file, e.linenr, e.expected, e.got)
-}
-
-type Row struct {
- Label string
- Cols [8]int
-}
-
-type Data struct {
- StartYear int
- Circ, BU, Proof []Row
-}
-
-func Parse(reader io.Reader, file string) (Data, error) {
- var (
- data Data // Our data struct
- slice *[]Row // Where to append mintages
- year int // The current year we are at
- )
-
- scanner := bufio.NewScanner(reader)
- for linenr := 1; scanner.Scan(); linenr++ {
- var mintmark struct {
- s string
- star bool
- }
-
- line := scanner.Text()
- tokens := strings.FieldsFunc(strings.TrimSpace(line), unicode.IsSpace)
-
- switch {
- case len(tokens) == 0:
- continue
- case tokens[0] == "BEGIN":
- if len(tokens)-1 != 1 {
- return Data{}, SyntaxError{
- expected: "single argument to ‘BEGIN’",
- got: fmt.Sprintf("%d arguments", len(tokens)-1),
- file: file,
- linenr: linenr,
- }
- }
-
- arg := tokens[1]
-
- switch arg {
- case "CIRC":
- slice = &data.Circ
- case "BU":
- slice = &data.BU
- case "PROOF":
- slice = &data.Proof
- default:
- if !isNumeric(arg, false) {
- return Data{}, SyntaxError{
- expected: "‘CIRC’, ‘BU’, ‘PROOF’, or a year",
- got: arg,
- file: file,
- linenr: linenr,
- }
- }
- data.StartYear, _ = strconv.Atoi(arg)
- }
-
- year = data.StartYear - 1
- case isLabel(tokens[0]):
- n := len(tokens[0])
- if n > 2 && tokens[0][n-2] == '*' {
- mintmark.star = true
- mintmark.s = tokens[0][:n-2]
- } else {
- mintmark.s = tokens[0][:n-1]
- }
- tokens = tokens[1:]
- if !isNumeric(tokens[0], true) && tokens[0] != "?" {
- return Data{}, SyntaxError{
- expected: "mintage row after label",
- got: tokens[0],
- file: file,
- linenr: linenr,
- }
- }
- fallthrough
- case isNumeric(tokens[0], true), tokens[0] == "?":
- switch {
- case slice == nil:
- return Data{}, SyntaxError{
- expected: "coin type declaration",
- got: tokens[0],
- file: file,
- linenr: linenr,
- }
- case data.StartYear == 0:
- return Data{}, SyntaxError{
- expected: "start year declaration",
- got: tokens[0],
- file: file,
- linenr: linenr,
- }
- }
-
- numcoins := len(Row{}.Cols)
- tokcnt := len(tokens)
-
- if tokcnt != numcoins {
- word := "entries"
- if tokcnt == 1 {
- word = "entry"
- }
- return Data{}, SyntaxError{
- expected: fmt.Sprintf("%d mintage entries", numcoins),
- got: fmt.Sprintf("%d %s", tokcnt, word),
- file: file,
- linenr: linenr,
- }
- }
-
- var row Row
- switch {
- case mintmark.s == "":
- year++
- row.Label = strconv.Itoa(year)
- case mintmark.star:
- year++
- fallthrough
- default:
- row.Label = fmt.Sprintf("%d %s", year, mintmark.s)
- }
-
- for i, tok := range tokens {
- if tok == "?" {
- row.Cols[i] = Unknown
- } else {
- row.Cols[i] = atoiWithDots(tok)
- }
- }
- *slice = append(*slice, row)
- default:
- return Data{}, SyntaxError{
- expected: "‘BEGIN’ directive or mintage row",
- got: fmt.Sprintf("invalid token ‘%s’", tokens[0]),
- file: file,
- linenr: linenr,
- }
- }
- }
-
- return data, nil
-}
-
-func isNumeric(s string, dot bool) bool {
- for _, ch := range s {
- switch ch {
- case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
- default:
- if ch != '.' || !dot {
- return false
- }
- }
- }
- return true
-}
-
-func isLabel(s string) bool {
- n := len(s)
- return (n > 2 && s[n-1] == ':' && s[n-2] == '*') ||
- (n > 1 && s[n-1] == ':')
-}
-
-func atoiWithDots(s string) int {
- n := 0
- for _, ch := range s {
- if ch == '.' {
- continue
- }
- n = n*10 + int(ch) - '0'
- }
- return n
-}