260 lines
14 KiB
Plaintext
260 lines
14 KiB
Plaintext
модуль джесон
|
||
|
||
импорт "исх/строка"
|
||
импорт "исх/спринтф"
|
||
|
||
фн парсить массив(токены: ДжесонТокены, старт: Цел64, использовано токенов := Цел64, ошибка := Строка): ДжесонМногоЗначений {
|
||
пусть массив = ДжесонМногоЗначений{значения: ДжесонЗначения[]}
|
||
пусть текущий индекс := старт
|
||
|
||
если текущий индекс >= длина(токены) {
|
||
ошибка := "неожиданный конец, ожидалась ["
|
||
вернуть ДжесонМногоЗначений{}
|
||
}
|
||
|
||
пусть токен := токены[текущий индекс]
|
||
|
||
выбор пусть т: тип токен {
|
||
когда ТокенКвадратнаяСкобка:
|
||
если т.закрывающая {
|
||
ошибка := спринтф.ф("ожидалась [, а получен $стр", токен.в строку())
|
||
вернуть ДжесонМногоЗначений{}
|
||
} иначе {
|
||
текущий индекс++
|
||
}
|
||
другое
|
||
ошибка := спринтф.ф("ожидалась [, а получен $стр", токен.в строку())
|
||
вернуть ДжесонМногоЗначений{}
|
||
}
|
||
|
||
пока текущий индекс < длина(токены) {
|
||
токен := токены[текущий индекс]
|
||
|
||
пусть значение: ДжесонЗначение := ДжесонЗначение{}
|
||
|
||
выбор пусть т: тип токен {
|
||
когда ТокенСтрока:
|
||
значение := ДжесонСтрока{значение: т.значение}
|
||
текущий индекс++
|
||
когда ТокенЧисло:
|
||
значение := ДжесонЧисло{значение: т.значение}
|
||
текущий индекс++
|
||
когда ТокенБульБуль:
|
||
значение := ДжесонЛог{значение: т.значение}
|
||
текущий индекс++
|
||
когда ТокенКвадратнаяСкобка:
|
||
если т.закрывающая {
|
||
текущий индекс++
|
||
использовано токенов := текущий индекс - старт
|
||
вернуть массив
|
||
} иначе {
|
||
ошибка := спринтф.ф("ожидалась значение или ], а получен $стр", токен.в строку())
|
||
вернуть ДжесонМногоЗначений{}
|
||
}
|
||
когда ТокенФигурнаяСкобка:
|
||
если ~т.закрывающая {
|
||
пусть использовано := 0
|
||
значение := парсить объект(токены, текущий индекс, использовано, ошибка)
|
||
|
||
если ошибка # "" { вернуть ДжесонМногоЗначений{} }
|
||
|
||
текущий индекс := текущий индекс + использовано
|
||
}
|
||
другое
|
||
ошибка := спринтф.ф("неожиданное значение: $стр", токен.в строку())
|
||
вернуть ДжесонМногоЗначений{}
|
||
}
|
||
|
||
массив.значения.добавить(значение)
|
||
|
||
если текущий индекс >= длина(токены) {
|
||
ошибка := "неожиданный конец, ожидался , или ]"
|
||
вернуть ДжесонМногоЗначений{}
|
||
}
|
||
|
||
токен := токены[текущий индекс]
|
||
|
||
выбор пусть т: тип токен {
|
||
когда ТокенКвадратнаяСкобка:
|
||
если т.закрывающая {
|
||
текущий индекс++
|
||
использовано токенов := текущий индекс - старт
|
||
вернуть массив
|
||
} иначе {
|
||
ошибка := спринтф.ф("ожидалась , или ], а получен $стр", токен.в строку())
|
||
вернуть ДжесонМногоЗначений{}
|
||
}
|
||
когда ТокенЗапятая:
|
||
текущий индекс++
|
||
другое
|
||
ошибка := спринтф.ф("ожидалась , или ], а получен $стр", токен.в строку())
|
||
вернуть ДжесонМногоЗначений{}
|
||
}
|
||
}
|
||
|
||
ошибка := "неожиданный конец во время парсинга массива"
|
||
вернуть ДжесонМногоЗначений{}
|
||
}
|
||
|
||
фн парсить объект(токены: ДжесонТокены, старт: Цел64, использовано токенов := Цел64, ошибка := Строка): ДжесонОбъект {
|
||
пусть объект = ДжесонОбъект{}
|
||
пусть текущий индекс := старт
|
||
|
||
если текущий индекс >= длина(токены) {
|
||
ошибка := "неожиданный конец, ожидалось {"
|
||
вернуть ДжесонОбъект{}
|
||
}
|
||
|
||
пусть токен := токены[текущий индекс]
|
||
|
||
выбор пусть т: тип токен {
|
||
когда ТокенФигурнаяСкобка:
|
||
если т.закрывающая {
|
||
ошибка := спринтф.ф("ожидалась {, а получен $стр", токен.в строку())
|
||
вернуть ДжесонОбъект{}
|
||
} иначе {
|
||
текущий индекс++
|
||
}
|
||
другое
|
||
ошибка := спринтф.ф("ожидалась {, а получен $стр", токен.в строку())
|
||
вернуть ДжесонОбъект{}
|
||
}
|
||
|
||
пока текущий индекс < длина(токены) {
|
||
токен := токены[текущий индекс]
|
||
пусть ключ := ""
|
||
|
||
выбор пусть т: тип токен {
|
||
когда ТокенСтрока:
|
||
ключ := т.значение
|
||
текущий индекс++
|
||
когда ТокенФигурнаяСкобка:
|
||
если т.закрывающая {
|
||
текущий индекс++
|
||
использовано токенов := текущий индекс - старт
|
||
вернуть объект
|
||
} иначе {
|
||
ошибка := спринтф.ф("ожидалась строка (ключ), а получен $стр", токен.в строку())
|
||
вернуть ДжесонОбъект{}
|
||
}
|
||
другое
|
||
ошибка := спринтф.ф("ожидалась строка (ключ), а получен $стр", токен.в строку())
|
||
вернуть ДжесонОбъект{}
|
||
}
|
||
|
||
если текущий индекс >= длина(токены) {
|
||
ошибка := "неожиданный конец, ожидалось :"
|
||
вернуть ДжесонОбъект{}
|
||
}
|
||
|
||
токен := токены[текущий индекс]
|
||
выбор пусть т: тип токен {
|
||
когда ТокенДвоеточие:
|
||
текущий индекс++
|
||
другое
|
||
ошибка := спринтф.ф("ожидался :, а получен $стр", токен.в строку())
|
||
вернуть ДжесонОбъект{}
|
||
}
|
||
|
||
если текущий индекс >= длина(токены) {
|
||
ошибка := "неожиданный конец, ожидалось значение"
|
||
вернуть ДжесонОбъект{}
|
||
}
|
||
|
||
токен := токены[текущий индекс]
|
||
|
||
пусть значение: ДжесонЗначение := ДжесонЗначение{}
|
||
выбор пусть т: тип токен {
|
||
когда ТокенСтрока:
|
||
значение := ДжесонСтрока{значение: т.значение}
|
||
текущий индекс++
|
||
когда ТокенЧисло:
|
||
значение := ДжесонЧисло{значение: т.значение}
|
||
текущий индекс++
|
||
когда ТокенБульБуль:
|
||
значение := ДжесонЛог{значение: т.значение}
|
||
текущий индекс++
|
||
когда ТокенФигурнаяСкобка:
|
||
если ~т.закрывающая {
|
||
пусть использовано := 0
|
||
значение := парсить объект(токены, текущий индекс, использовано, ошибка)
|
||
|
||
если ошибка # "" { вернуть ДжесонОбъект{} }
|
||
|
||
текущий индекс := текущий индекс + использовано
|
||
} иначе {
|
||
ошибка := спринтф.ф("ожидалось значение, а получен $стр", токен.в строку())
|
||
вернуть ДжесонОбъект{}
|
||
}
|
||
когда ТокенКвадратнаяСкобка:
|
||
если т.закрывающая {
|
||
ошибка := спринтф.ф("ожидалось значение, а получен $стр", токен.в строку())
|
||
вернуть ДжесонОбъект{}
|
||
} иначе {
|
||
пусть использовано := 0
|
||
значение := парсить массив(токены, текущий индекс, использовано, ошибка)
|
||
|
||
если ошибка # "" { вернуть ДжесонОбъект{} }
|
||
текущий индекс := текущий индекс + использовано
|
||
}
|
||
другое
|
||
ошибка := спринтф.ф("неожиданное значение: $стр", токен.в строку())
|
||
вернуть ДжесонОбъект{}
|
||
}
|
||
|
||
объект.значения.добавить(ДжесонКлючЗначение{ключ: ключ, значение: значение})
|
||
|
||
если текущий индекс >= длина(токены) {
|
||
ошибка := "неожиданный конец, ожидался , или }"
|
||
вернуть ДжесонОбъект{}
|
||
}
|
||
|
||
токен := токены[текущий индекс]
|
||
|
||
выбор пусть т: тип токен {
|
||
когда ТокенЗапятая:
|
||
текущий индекс++
|
||
когда ТокенФигурнаяСкобка:
|
||
если т.закрывающая {
|
||
текущий индекс++
|
||
использовано токенов := текущий индекс - старт
|
||
вернуть объект
|
||
} иначе {
|
||
ошибка := спринтф.ф("ожидалась , или }, а получен $стр", токен.в строку())
|
||
вернуть ДжесонОбъект{}
|
||
}
|
||
другое
|
||
ошибка := спринтф.ф("ожидалась , или }, а получен $стр", токен.в строку())
|
||
вернуть ДжесонОбъект{}
|
||
}
|
||
}
|
||
|
||
ошибка := "неожиданный конец во время парсинга объекта"
|
||
вернуть ДжесонОбъект{}
|
||
}
|
||
|
||
фн парсить токены(токены: ДжесонТокены, ошибка := Строка): ДжесонОбъект {
|
||
пусть использовано токенов := 0
|
||
вернуть парсить объект(токены, 0, использовано токенов, ошибка)
|
||
}
|
||
|
||
фн парсить*(строка: Строка, ошибка := Строка): ДжесонОбъект {
|
||
пусть токены = токенизировать(строка, ошибка)
|
||
|
||
если ошибка # "" {
|
||
вернуть ДжесонОбъект{}
|
||
}
|
||
|
||
пусть объект = парсить токены(токены, ошибка)
|
||
|
||
если ошибка # "" {
|
||
вернуть ДжесонОбъект{}
|
||
}
|
||
|
||
вернуть объект
|
||
}
|
||
|
||
фн сериализовать*(объект: ДжесонОбъект): Строка {
|
||
вернуть массив токенов в строку(объект.в токены())
|
||
}
|