diff --git a/example/json/main.go b/example/json/main.go new file mode 100644 index 0000000..842ab82 --- /dev/null +++ b/example/json/main.go @@ -0,0 +1,99 @@ +// +build ignore + +package main + +import ( + "fmt" + + "github.com/neonxp/unilex" +) + +func main() { + testJson := ` + { + "key1": "value1", + "key2": { + "key3" : "value 3" + }, + "key4": 123.321 + }` + l := unilex.New(testJson) + go l.Run(initJson) + for ll := range l.Output { + fmt.Println(ll) + } +} + +const ( + lObjectStart unilex.LexType = "lObjectStart" + lObjectEnd unilex.LexType = "lObjectEnd" + lObjectKey unilex.LexType = "lObjectKey" + lObjectValueString unilex.LexType = "lObjectValueString" + lObjectValueNumber unilex.LexType = "lObjectValueNumber" +) + +func initJson(l *unilex.Lexer) unilex.StateFunc { + ignoreWhiteSpace(l) + switch { + case l.Accept("{"): + l.Emit(lObjectStart) + return stateInObject(true) + case l.Peek() == unilex.EOF: + return nil + } + return l.Errorf("Unknown token: %s", 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 + 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) + ignoreWhiteSpace(l) + if !l.Accept(":") { + return l.Errorf("Expected ':'") + } + 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") + } +} + +func ignoreWhiteSpace(l *unilex.Lexer) { + l.AcceptWhile(" \n\t") //ignore whitespaces + l.Ignore() +}