Files
srab/исх/форматы/джесон/парсер.tri
2025-11-26 21:32:41 +03:00

260 lines
14 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
модуль джесон
импорт "исх/строка"
импорт "исх/спринтф"
фн парсить массив(токены: ДжесонТокены, старт: Цел64, использовано токенов := Цел64, ошибка := Строка): ДжесонМногоЗначений {
пусть массив = ДжесонМногоЗначений{значения: ДжесонЗначения[]}
пусть текущий индекс := старт
если текущий индекс >= длина(токены) {
ошибка := "неожиданный конец, ожидалась ["
вернуть ДжесонМногоЗначений{}
}
пусть токен := токены[текущий индекс]
выбор пусть т: тип токен {
когда ТокенКвадратнаяСкобка:
если т.закрывающая {
ошибка := спринтф.ф("ожидалась [, а получен $стр", токен.в строку())
вернуть ДжесонМногоЗначений{}
} иначе {
текущий индекс++
}
другое
ошибка := спринтф.ф("ожидалась [, а получен $стр", токен.в строку())
вернуть ДжесонМногоЗначений{}
}
пока текущий индекс < длина(токены) {
токен := токены[текущий индекс]
пусть значение: ДжесонЗначение := ДжесонЗначение{}
выбор пусть т: тип токен {
когда ТокенСтрока:
значение := ДжесонСтрока{значение: т.значение}
текущий индекс++
когда ТокенЧисло:
значение := ДжесонЧисло{значение: т.значение}
текущий индекс++
когда ТокенБульБуль:
значение := ДжесонЛог{значение: т.значение}
текущий индекс++
когда ТокенКвадратнаяСкобка:
если т.закрывающая {
текущий индекс++
использовано токенов := текущий индекс - старт
вернуть массив
} иначе {
ошибка := спринтф.ф("ожидалась значение или ], а получен $стр", токен.в строку())
вернуть ДжесонМногоЗначений{}
}
когда ТокенФигурнаяСкобка:
если ~т.закрывающая {
пусть использовано := 0
значение := парсить объект(токены, текущий индекс, использовано, ошибка)
если ошибка # "" { вернуть ДжесонМногоЗначений{} }
текущий индекс := текущий индекс + использовано
}
другое
ошибка := спринтф.ф("неожиданное значение: $стр", токен.в строку())
вернуть ДжесонМногоЗначений{}
}
массив.значения.добавить(значение)
если текущий индекс >= длина(токены) {
ошибка := "неожиданный конец, ожидался , или ]"
вернуть ДжесонМногоЗначений{}
}
токен := токены[текущий индекс]
выбор пусть т: тип токен {
когда ТокенКвадратнаяСкобка:
если т.закрывающая {
текущий индекс++
использовано токенов := текущий индекс - старт
вернуть массив
} иначе {
ошибка := спринтф.ф("ожидалась , или ], а получен $стр", токен.в строку())
вернуть ДжесонМногоЗначений{}
}
когда ТокенЗапятая:
текущий индекс++
другое
ошибка := спринтф.ф("ожидалась , или ], а получен $стр", токен.в строку())
вернуть ДжесонМногоЗначений{}
}
}
ошибка := "неожиданный конец во время парсинга массива"
вернуть ДжесонМногоЗначений{}
}
фн парсить объект(токены: ДжесонТокены, старт: Цел64, использовано токенов := Цел64, ошибка := Строка): ДжесонОбъект {
пусть объект = ДжесонОбъект{}
пусть текущий индекс := старт
если текущий индекс >= длина(токены) {
ошибка := "неожиданный конец, ожидалось {"
вернуть ДжесонОбъект{}
}
пусть токен := токены[текущий индекс]
выбор пусть т: тип токен {
когда ТокенФигурнаяСкобка:
если т.закрывающая {
ошибка := спринтф.ф("ожидалась {, а получен $стр", токен.в строку())
вернуть ДжесонОбъект{}
} иначе {
текущий индекс++
}
другое
ошибка := спринтф.ф("ожидалась {, а получен $стр", токен.в строку())
вернуть ДжесонОбъект{}
}
пока текущий индекс < длина(токены) {
токен := токены[текущий индекс]
пусть ключ := ""
выбор пусть т: тип токен {
когда ТокенСтрока:
ключ := т.значение
текущий индекс++
когда ТокенФигурнаяСкобка:
если т.закрывающая {
текущий индекс++
использовано токенов := текущий индекс - старт
вернуть объект
} иначе {
ошибка := спринтф.ф("ожидалась строка (ключ), а получен $стр", токен.в строку())
вернуть ДжесонОбъект{}
}
другое
ошибка := спринтф.ф("ожидалась строка (ключ), а получен $стр", токен.в строку())
вернуть ДжесонОбъект{}
}
если текущий индекс >= длина(токены) {
ошибка := "неожиданный конец, ожидалось :"
вернуть ДжесонОбъект{}
}
токен := токены[текущий индекс]
выбор пусть т: тип токен {
когда ТокенДвоеточие:
текущий индекс++
другое
ошибка := спринтф.ф("ожидался :, а получен $стр", токен.в строку())
вернуть ДжесонОбъект{}
}
если текущий индекс >= длина(токены) {
ошибка := "неожиданный конец, ожидалось значение"
вернуть ДжесонОбъект{}
}
токен := токены[текущий индекс]
пусть значение: ДжесонЗначение := ДжесонЗначение{}
выбор пусть т: тип токен {
когда ТокенСтрока:
значение := ДжесонСтрока{значение: т.значение}
текущий индекс++
когда ТокенЧисло:
значение := ДжесонЧисло{значение: т.значение}
текущий индекс++
когда ТокенБульБуль:
значение := ДжесонЛог{значение: т.значение}
текущий индекс++
когда ТокенФигурнаяСкобка:
если ~т.закрывающая {
пусть использовано := 0
значение := парсить объект(токены, текущий индекс, использовано, ошибка)
если ошибка # "" { вернуть ДжесонОбъект{} }
текущий индекс := текущий индекс + использовано
} иначе {
ошибка := спринтф.ф("ожидалось значение, а получен $стр", токен.в строку())
вернуть ДжесонОбъект{}
}
когда ТокенКвадратнаяСкобка:
если т.закрывающая {
ошибка := спринтф.ф("ожидалось значение, а получен $стр", токен.в строку())
вернуть ДжесонОбъект{}
} иначе {
пусть использовано := 0
значение := парсить массив(токены, текущий индекс, использовано, ошибка)
если ошибка # "" { вернуть ДжесонОбъект{} }
текущий индекс := текущий индекс + использовано
}
другое
ошибка := спринтф.ф("неожиданное значение: $стр", токен.в строку())
вернуть ДжесонОбъект{}
}
объект.значения.добавить(ДжесонКлючЗначение{ключ: ключ, значение: значение})
если текущий индекс >= длина(токены) {
ошибка := "неожиданный конец, ожидался , или }"
вернуть ДжесонОбъект{}
}
токен := токены[текущий индекс]
выбор пусть т: тип токен {
когда ТокенЗапятая:
текущий индекс++
когда ТокенФигурнаяСкобка:
если т.закрывающая {
текущий индекс++
использовано токенов := текущий индекс - старт
вернуть объект
} иначе {
ошибка := спринтф.ф("ожидалась , или }, а получен $стр", токен.в строку())
вернуть ДжесонОбъект{}
}
другое
ошибка := спринтф.ф("ожидалась , или }, а получен $стр", токен.в строку())
вернуть ДжесонОбъект{}
}
}
ошибка := "неожиданный конец во время парсинга объекта"
вернуть ДжесонОбъект{}
}
фн парсить токены(токены: ДжесонТокены, ошибка := Строка): ДжесонОбъект {
пусть использовано токенов := 0
вернуть парсить объект(токены, 0, использовано токенов, ошибка)
}
фн парсить*(строка: Строка, ошибка := Строка): ДжесонОбъект {
пусть токены = токенизировать(строка, ошибка)
если ошибка # "" {
вернуть ДжесонОбъект{}
}
пусть объект = парсить токены(токены, ошибка)
если ошибка # "" {
вернуть ДжесонОбъект{}
}
вернуть объект
}
фн сериализовать*(объект: ДжесонОбъект): Строка {
вернуть массив токенов в строку(объект.в токены())
}