aboutsummaryrefslogtreecommitdiff
path: root/parser/states.go
diff options
context:
space:
mode:
Diffstat (limited to 'parser/states.go')
-rw-r--r--parser/states.go110
1 files changed, 110 insertions, 0 deletions
diff --git a/parser/states.go b/parser/states.go
new file mode 100644
index 0000000..92c80dc
--- /dev/null
+++ b/parser/states.go
@@ -0,0 +1,110 @@
+package parser
+
+func initJson(l *lexer) stateFunc {
+ ignoreWhiteSpace(l)
+ switch {
+ case l.Accept("{"):
+ l.Emit(lObjectStart)
+ return stateInObject
+ case l.Accept("["):
+ l.Emit(lArrayStart)
+ case l.Peek() == eof:
+ return nil
+ }
+ return l.Errorf("Unknown token: %s", string(l.Peek()))
+}
+
+func stateInObject(l *lexer) 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 !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 scanQuotedString(l, '"'):
+ l.Emit(lString)
+ ignoreWhiteSpace(l)
+ l.Accept(",")
+ l.Ignore()
+ ignoreWhiteSpace(l)
+ return stateInObject
+ case scanNumber(l):
+ l.Emit(lNumber)
+ ignoreWhiteSpace(l)
+ l.Accept(",")
+ l.Ignore()
+ ignoreWhiteSpace(l)
+ return stateInObject
+ case l.AcceptAnyOf([]string{"true", "false"}, true):
+ l.Emit(lBoolean)
+ ignoreWhiteSpace(l)
+ l.Accept(",")
+ l.Ignore()
+ ignoreWhiteSpace(l)
+ return stateInObject
+ case l.AcceptString("null", true):
+ l.Emit(lNull)
+ ignoreWhiteSpace(l)
+ l.Accept(",")
+ l.Ignore()
+ ignoreWhiteSpace(l)
+ 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 *lexer) stateFunc {
+ ignoreWhiteSpace(l)
+ l.Accept(",")
+ ignoreWhiteSpace(l)
+ switch {
+ case scanQuotedString(l, '"'):
+ l.Emit(lString)
+ case scanNumber(l):
+ l.Emit(lNumber)
+ case l.AcceptAnyOf([]string{"true", "false"}, true):
+ l.Emit(lBoolean)
+ case l.AcceptString("null", true):
+ l.Emit(lNull)
+ 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 *lexer) {
+ l.AcceptWhile(" \n\t") // ignore whitespaces
+ l.Ignore()
+}