diff options
author | Luke Shumaker <lukeshu@lukeshu.com> | 2023-01-29 02:15:13 -0700 |
---|---|---|
committer | Luke Shumaker <lukeshu@lukeshu.com> | 2023-01-29 02:15:13 -0700 |
commit | 0b57145421e7e4f165f64e73ee7c5d8102945569 (patch) | |
tree | 25584309e42bb53469959a3725393bdbc8b225c7 /internal/parse.go | |
parent | ffee5c8516f3f55f82ed5bb8f0a4f340d485fa92 (diff) | |
parent | 7e00adcf43b18a22ffbbadc79b8681a5d871f448 (diff) |
Merge branch 'lukeshu/quality'
This branch works to improve code quality, without making any
substantive changes.
Diffstat (limited to 'internal/parse.go')
-rw-r--r-- | internal/parse.go | 82 |
1 files changed, 49 insertions, 33 deletions
diff --git a/internal/parse.go b/internal/parse.go index 895c930..bb849e7 100644 --- a/internal/parse.go +++ b/internal/parse.go @@ -70,9 +70,14 @@ const ( RuneTypeNullL2 RuneTypeEOF + + // Not a real rune type, but used as a stack state. + runeTypeAny ) // GoString implements fmt.GoStringer. +// +//nolint:dupl // False positive due to similarly shaped AST. func (t RuneType) GoString() string { str, ok := map[RuneType]string{ RuneTypeError: "RuneTypeError", @@ -125,6 +130,8 @@ func (t RuneType) GoString() string { RuneTypeNullL2: "RuneTypeNullL2", RuneTypeEOF: "RuneTypeEOF", + + runeTypeAny: "runeTypeAny", }[t] if ok { return str @@ -133,6 +140,8 @@ func (t RuneType) GoString() string { } // String implements fmt.Stringer. +// +//nolint:dupl // False positive due to similarly shaped AST. func (t RuneType) String() string { str, ok := map[RuneType]string{ RuneTypeError: "x", @@ -148,7 +157,7 @@ func (t RuneType) String() string { RuneTypeArrayComma: "a", RuneTypeArrayEnd: "]", - RuneTypeStringBeg: "“", + RuneTypeStringBeg: "\"", RuneTypeStringChar: "c", RuneTypeStringEsc: "\\", RuneTypeStringEsc1: "b", @@ -157,7 +166,7 @@ func (t RuneType) String() string { RuneTypeStringEscUB: "B", RuneTypeStringEscUC: "C", RuneTypeStringEscUD: "D", - RuneTypeStringEnd: "”", + RuneTypeStringEnd: "»", RuneTypeNumberIntNeg: "-", RuneTypeNumberIntZero: "0", @@ -185,6 +194,8 @@ func (t RuneType) String() string { RuneTypeNullL2: "Ⓛ", // +uppercase RuneTypeEOF: "$", + + runeTypeAny: "?", }[t] if ok { return str @@ -226,15 +237,19 @@ type Parser struct { err error closed bool - // We reuse RuneTypes to store the stack. The base idea is - // that, stack items are "the most recently read - // stack-relevant RuneType". + // We reuse RuneTypes to store the stack. The base idea is: + // stack items are "the most recently read stack-relevant + // RuneType". // - // We treat RuneTypeError as a wildcard. + // The stack starts out with the special pseudo-RuneType + // `runeTypeAny` that means we're willing to accept any + // element type; an empty stack means that we have reached the + // end of the top-level element and should accept no more + // input except for whitespace. // - // The "normal"stack-relevant RuneTypes are: + // The "normal" stack-relevant RuneTypes are: // - // “\uABC for strings + // "\uABC for strings // -01.2e+3 for numbers // 𝕥𝕣𝕦 for "true" // 𝔣𝔞𝔩𝔰 for "false" @@ -244,8 +259,7 @@ type Parser struct { // rule; they need some special assignments: // // { object: waiting for key to start or '}' - // ” object: reading key / waiting for colon - // : object: waiting for value to start + // » object: reading key / waiting for colon // o object: reading value / waiting for ',' or '}' // // [ array: waiting for item to start or ']' @@ -261,22 +275,22 @@ type Parser struct { // The stack would be // // stack processed - // x + // ? // { { - // ”“ {" - // ”“ {"x - // ” {"x" - // : {"x": - // o“ {"x":" - // o“ {"x":"y + // »" {" + // »" {"x + // » {"x" + // o? {"x": + // o" {"x":" + // o" {"x":"y // o {"x":"y" // { {"x":"y", - // ”“ {"x":"y"," - // ”“ {"x":"y","a - // ” {"x":"y","a" - // : {"x":"y","a": - // o“ {"x":"y","a":" - // o“ {"x":"y","a":"b + // »" {"x":"y"," + // »" {"x":"y","a + // » {"x":"y","a" + // o? {"x":"y","a": + // o" {"x":"y","a":" + // o" {"x":"y","a":"b // o {"x":"y","a":"b" // {"x":"y","a":"b"} stack []RuneType @@ -286,10 +300,12 @@ func (par *Parser) pushState(state RuneType) RuneType { par.stack = append(par.stack, state) return state } + func (par *Parser) replaceState(state RuneType) RuneType { par.stack[len(par.stack)-1] = state return state } + func (par *Parser) popState() { par.stack = par.stack[:len(par.stack)-1] } @@ -303,7 +319,7 @@ func (par *Parser) stackString() string { } func (par *Parser) StackIsEmpty() bool { - return len(par.stack) == 0 || (len(par.stack) == 1 && par.stack[0] == RuneTypeError) + return len(par.stack) == 0 || (len(par.stack) == 1 && par.stack[0] == runeTypeAny) } // Reset all Parser state. @@ -337,7 +353,7 @@ func (par *Parser) HandleEOF() (RuneType, error) { } if !par.initialized { par.initialized = true - par.pushState(RuneTypeError) + par.pushState(runeTypeAny) } switch len(par.stack) { case 0: @@ -348,7 +364,7 @@ func (par *Parser) HandleEOF() (RuneType, error) { if _, err := par.HandleRune('\n'); err == nil { return RuneTypeEOF, nil } - case par.stack[0] == RuneTypeError: + case par.stack[0] == runeTypeAny: par.err = io.EOF return RuneTypeError, par.err } @@ -381,7 +397,7 @@ func (par *Parser) HandleRune(c rune) (RuneType, error) { } if !par.initialized { par.initialized = true - par.pushState(RuneTypeError) + par.pushState(runeTypeAny) } if len(par.stack) == 0 { switch c { @@ -393,7 +409,7 @@ func (par *Parser) HandleRune(c rune) (RuneType, error) { } switch par.stack[len(par.stack)-1] { // any ///////////////////////////////////////////////////////////////////////////////////// - case RuneTypeError: + case runeTypeAny: switch c { case 0x0020, 0x000A, 0x000D, 0x0009: return RuneTypeSpace, nil @@ -444,7 +460,7 @@ func (par *Parser) HandleRune(c rune) (RuneType, error) { return RuneTypeSpace, nil case ':': par.replaceState(RuneTypeObjectComma) - par.pushState(RuneTypeError) + par.pushState(runeTypeAny) return RuneTypeObjectColon, nil default: return RuneTypeError, fmt.Errorf("invalid character %q after object key", c) @@ -472,7 +488,7 @@ func (par *Parser) HandleRune(c rune) (RuneType, error) { return RuneTypeArrayEnd, nil default: par.replaceState(RuneTypeArrayComma) - par.pushState(RuneTypeError) + par.pushState(runeTypeAny) return par.HandleRune(c) } case RuneTypeArrayEnd: // waiting for item @@ -481,7 +497,7 @@ func (par *Parser) HandleRune(c rune) (RuneType, error) { return RuneTypeSpace, nil default: par.replaceState(RuneTypeArrayComma) - par.pushState(RuneTypeError) + par.pushState(runeTypeAny) return par.HandleRune(c) } case RuneTypeArrayComma: // waiting for ',' or ']' @@ -583,8 +599,8 @@ func (par *Parser) HandleRune(c rune) (RuneType, error) { // H = ExpSign // I = ExpDig // - // The 'A' state is part of the RuneTypeError "any" case - // above, and the remainder follow: + // The 'A' state is part of the runeTypeAny case above, and + // the remainder follow: case RuneTypeNumberIntNeg: // B switch c { case '0': |