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