diff options
Diffstat (limited to 'example/json/main.go')
-rw-r--r-- | example/json/main.go | 140 |
1 files changed, 89 insertions, 51 deletions
diff --git a/example/json/main.go b/example/json/main.go index 842ab82..745e5aa 100644 --- a/example/json/main.go +++ b/example/json/main.go @@ -15,7 +15,19 @@ func main() { "key2": { "key3" : "value 3" }, - "key4": 123.321 + "key4": 123.321, + "key5": [ + 1, + 2, + [ + 3, + 4, + 5, + { + "key6": "value6" + } + ] + ] }` l := unilex.New(testJson) go l.Run(initJson) @@ -25,11 +37,14 @@ func main() { } const ( - lObjectStart unilex.LexType = "lObjectStart" - lObjectEnd unilex.LexType = "lObjectEnd" - lObjectKey unilex.LexType = "lObjectKey" - lObjectValueString unilex.LexType = "lObjectValueString" - lObjectValueNumber unilex.LexType = "lObjectValueNumber" + lObjectStart unilex.LexType = iota + lObjectEnd + lObjectKey + lObjectValue + lArrayStart + lArrayEnd + lString + lNumber ) func initJson(l *unilex.Lexer) unilex.StateFunc { @@ -37,60 +52,83 @@ func initJson(l *unilex.Lexer) unilex.StateFunc { switch { case l.Accept("{"): l.Emit(lObjectStart) - return stateInObject(true) + return stateInObject case l.Peek() == unilex.EOF: return nil } - return l.Errorf("Unknown token: %s", l.Peek()) + return l.Errorf("Unknown token: %s", string(l.Peek())) } -func stateInObject(initial bool) unilex.StateFunc { - return func(l *unilex.Lexer) unilex.StateFunc { - // we in object, so we expect field keys and values +func stateInObject(l *unilex.Lexer) unilex.StateFunc { + // we in object, so we expect field keys and values + ignoreWhiteSpace(l) + if l.Accept("}") { + l.Emit(lObjectEnd) + // If meet close object return to previous state (including initial) + return l.PopState() + } + ignoreWhiteSpace(l) + l.Accept(",") + ignoreWhiteSpace(l) + if !unilex.ScanQuotedString(l, '"') { + return l.Errorf("Unknown token: %s", string(l.Peek())) + } + l.Emit(lObjectKey) + ignoreWhiteSpace(l) + if !l.Accept(":") { + return l.Errorf("Expected ':'") + } + ignoreWhiteSpace(l) + l.Emit(lObjectValue) + switch { + case unilex.ScanQuotedString(l, '"'): + l.Emit(lString) + ignoreWhiteSpace(l) + l.Accept(",") + l.Ignore() ignoreWhiteSpace(l) - if l.Accept("}") { - l.Emit(lObjectEnd) - if initial { - return initJson - } - ignoreWhiteSpace(l) - l.Accept(",") - ignoreWhiteSpace(l) - return stateInObject(initial) - } - if l.Peek() == unilex.EOF { - return nil - } - if !unilex.ScanQuotedString(l, '"') { - return l.Errorf("Unknown token: %s", l.Peek()) - } - l.Emit(lObjectKey) + return stateInObject + case unilex.ScanNumber(l): + l.Emit(lNumber) ignoreWhiteSpace(l) - if !l.Accept(":") { - return l.Errorf("Expected ':'") - } + l.Accept(",") + l.Ignore() ignoreWhiteSpace(l) - switch { - case unilex.ScanQuotedString(l, '"'): - l.Emit(lObjectValueString) - ignoreWhiteSpace(l) - l.Accept(",") - l.Ignore() - ignoreWhiteSpace(l) - return stateInObject(initial) - case unilex.ScanNumber(l): - l.Emit(lObjectValueNumber) - ignoreWhiteSpace(l) - l.Accept(",") - l.Ignore() - ignoreWhiteSpace(l) - return stateInObject(initial) - case l.Accept("{"): - l.Emit(lObjectStart) - return stateInObject(false) - } - return l.Errorf("Unknown token") + return stateInObject + case l.Accept("{"): + l.Emit(lObjectStart) + l.PushState(stateInObject) + return stateInObject + case l.Accept("["): + l.Emit(lArrayStart) + l.PushState(stateInObject) + return stateInArray + } + return l.Errorf("Unknown token: %s", string(l.Peek())) +} + +func stateInArray(l *unilex.Lexer) unilex.StateFunc { + ignoreWhiteSpace(l) + l.Accept(",") + ignoreWhiteSpace(l) + switch { + case unilex.ScanQuotedString(l, '"'): + l.Emit(lString) + case unilex.ScanNumber(l): + l.Emit(lNumber) + case l.Accept("{"): + l.Emit(lObjectStart) + l.PushState(stateInArray) + return stateInObject + case l.Accept("["): + l.Emit(lArrayStart) + l.PushState(stateInArray) + return stateInArray + case l.Accept("]"): + l.Emit(lArrayEnd) + return l.PopState() } + return stateInArray } func ignoreWhiteSpace(l *unilex.Lexer) { |