aboutsummaryrefslogtreecommitdiff
path: root/example
diff options
context:
space:
mode:
authorAlexander Kiryukhin <a.kiryukhin@mail.ru>2021-03-10 00:47:58 +0300
committerAlexander Kiryukhin <a.kiryukhin@mail.ru>2021-03-10 00:47:58 +0300
commitff198abd8fc9e2019c2f3ef9b7e74206ecdb99b7 (patch)
tree3ea7c05e54d00bf2d70cec7c88442402f9916a55 /example
parent521e6da1f6c9c964abca5bac22ce62823c276c1f (diff)
Push/pop state, full json examplev0.0.2
Diffstat (limited to 'example')
-rw-r--r--example/json/main.go140
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) {