From 7e00adcf43b18a22ffbbadc79b8681a5d871f448 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sun, 29 Jan 2023 00:08:22 -0700 Subject: parse: Add a runeTypeAny instead of overloading RuneTypeError It was confusing. --- internal/parse.go | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/internal/parse.go b/internal/parse.go index d917d9d..bb849e7 100644 --- a/internal/parse.go +++ b/internal/parse.go @@ -70,6 +70,9 @@ const ( RuneTypeNullL2 RuneTypeEOF + + // Not a real rune type, but used as a stack state. + runeTypeAny ) // GoString implements fmt.GoStringer. @@ -127,6 +130,8 @@ func (t RuneType) GoString() string { RuneTypeNullL2: "RuneTypeNullL2", RuneTypeEOF: "RuneTypeEOF", + + runeTypeAny: "runeTypeAny", }[t] if ok { return str @@ -189,6 +194,8 @@ func (t RuneType) String() string { RuneTypeNullL2: "Ⓛ", // +uppercase RuneTypeEOF: "$", + + runeTypeAny: "?", }[t] if ok { return str @@ -234,7 +241,11 @@ type Parser struct { // 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: // @@ -264,12 +275,12 @@ type Parser struct { // The stack would be // // stack processed - // x + // ? // { { // »" {" // »" {"x // » {"x" - // ox {"x": + // o? {"x": // o" {"x":" // o" {"x":"y // o {"x":"y" @@ -277,7 +288,7 @@ type Parser struct { // »" {"x":"y"," // »" {"x":"y","a // » {"x":"y","a" - // ox {"x":"y","a": + // o? {"x":"y","a": // o" {"x":"y","a":" // o" {"x":"y","a":"b // o {"x":"y","a":"b" @@ -308,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. @@ -342,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: @@ -353,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 } @@ -386,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 { @@ -398,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 @@ -449,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) @@ -477,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 @@ -486,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 ']' @@ -588,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': -- cgit v1.2.3-54-g00ecf