111 lines
2.3 KiB
Go
111 lines
2.3 KiB
Go
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()
|
|
}
|