summaryrefslogtreecommitdiff
path: root/internal/parse.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/parse.go')
-rw-r--r--internal/parse.go50
1 files changed, 31 insertions, 19 deletions
diff --git a/internal/parse.go b/internal/parse.go
index bb849e7..b11aae6 100644
--- a/internal/parse.go
+++ b/internal/parse.go
@@ -264,10 +264,11 @@ type Parser struct {
//
// [ array: waiting for item to start or ']'
// a array: reading item / waiting for ',' or ']'
- // ] array: waiting for item to start
//
// Within each element type, the stack item is replaced, not pushed.
//
+ // (Keep each of these examples in-sync with parse_test.go.)
+ //
// For example, given the input string
//
// {"x":"y","a":"b"}
@@ -293,9 +294,34 @@ type Parser struct {
// o" {"x":"y","a":"b
// o {"x":"y","a":"b"
// {"x":"y","a":"b"}
+ //
+ // Or, given the input string
+ //
+ // ["x","y"]
+ //
+ // The stack would be
+ //
+ // stack processed
+ // ?
+ // [ [
+ // a" ["
+ // a" ["x
+ // a ["x"
+ // a? ["x",
+ // a" ["x","
+ // a" ["x","y
+ // a ["x","y"
+ // ["x","y"]
stack []RuneType
}
+func (par *Parser) init() {
+ if !par.initialized {
+ par.initialized = true
+ par.pushState(runeTypeAny)
+ }
+}
+
func (par *Parser) pushState(state RuneType) RuneType {
par.stack = append(par.stack, state)
return state
@@ -311,6 +337,7 @@ func (par *Parser) popState() {
}
func (par *Parser) stackString() string {
+ par.init()
var buf strings.Builder
for _, s := range par.stack {
buf.WriteString(s.String())
@@ -351,10 +378,7 @@ func (par *Parser) HandleEOF() (RuneType, error) {
if par.err != nil {
return RuneTypeError, par.err
}
- if !par.initialized {
- par.initialized = true
- par.pushState(runeTypeAny)
- }
+ par.init()
switch len(par.stack) {
case 0:
return RuneTypeEOF, nil
@@ -395,10 +419,7 @@ func (par *Parser) HandleRune(c rune) (RuneType, error) {
if par.err != nil {
return RuneTypeError, par.err
}
- if !par.initialized {
- par.initialized = true
- par.pushState(runeTypeAny)
- }
+ par.init()
if len(par.stack) == 0 {
switch c {
case 0x0020, 0x000A, 0x000D, 0x0009:
@@ -491,21 +512,12 @@ func (par *Parser) HandleRune(c rune) (RuneType, error) {
par.pushState(runeTypeAny)
return par.HandleRune(c)
}
- case RuneTypeArrayEnd: // waiting for item
- switch c {
- case 0x0020, 0x000A, 0x000D, 0x0009:
- return RuneTypeSpace, nil
- default:
- par.replaceState(RuneTypeArrayComma)
- par.pushState(runeTypeAny)
- return par.HandleRune(c)
- }
case RuneTypeArrayComma: // waiting for ',' or ']'
switch c {
case 0x0020, 0x000A, 0x000D, 0x0009:
return RuneTypeSpace, nil
case ',':
- par.replaceState(RuneTypeArrayEnd)
+ par.pushState(runeTypeAny)
return RuneTypeArrayComma, nil
case ']':
par.popState()