Добавить в корзинуПозвонить
Найти в Дзене
Цифровая Переплавка

💻🔥 Безумие или гениальность? Как написать JSON-парсер на чистом C с методами структур

C — язык, который славится своей простотой, скоростью и, конечно же, возможностью стрелять себе в ногу. Когда речь заходит о парсинге JSON, обычно представляются удобные библиотеки на Python или JavaScript. Но что, если совместить структурированность JSON с суровой прямотой языка C? Именно этим и занялся разработчик xnacly, создав удивительно дерзкий и творческий проект — JSON-парсер, реализованный на C с использованием методов структур. Автор проекта решил не просто написать очередной парсер JSON, а пойти нестандартным путём: Это амбициозная задача, ведь C по своей природе не предназначен для объектно-ориентированного подхода. В C структуры не имеют методов в привычном смысле, но их можно имитировать через указатели на функции. Автор применил такой подход: struct json {
char *input;
size_t pos;
size_t length;
// 🔧 Методы структуры через указатели на функции:
char (*cur)(struct json *);
bool (*is_eof)(struct json *);
void (*advance)(struct json *);
struct json_value
Оглавление

C — язык, который славится своей простотой, скоростью и, конечно же, возможностью стрелять себе в ногу. Когда речь заходит о парсинге JSON, обычно представляются удобные библиотеки на Python или JavaScript. Но что, если совместить структурированность JSON с суровой прямотой языка C? Именно этим и занялся разработчик xnacly, создав удивительно дерзкий и творческий проект — JSON-парсер, реализованный на C с использованием методов структур.

📌 Почему это интересно?

Автор проекта решил не просто написать очередной парсер JSON, а пойти нестандартным путём:

  • 🎯 Создать API, напоминающий методы структур из Go или Rust, используя указатели на функции в C.
  • 🛠️ Обеспечить полную безопасность (без ошибок сегментации, утечек памяти и переполнений стека).
  • 🧹 Предоставить удобный, эргономичный интерфейс для разработчиков.

Это амбициозная задача, ведь C по своей природе не предназначен для объектно-ориентированного подхода.

🎩 Как «оживить» структуры в C?

В C структуры не имеют методов в привычном смысле, но их можно имитировать через указатели на функции. Автор применил такой подход:

struct json {
char *input;
size_t pos;
size_t length;

// 🔧 Методы структуры через указатели на функции:
char (*cur)(struct json *);
bool (*is_eof)(struct json *);
void (*advance)(struct json *);
struct json_value (*parse)(struct json *);
};

Затем при инициализации структуры он явно назначает функции указателям, что и создаёт впечатление методов:

struct json json_new(char *input) {
struct json j = { .input = input, .length = strlen(input) - 1 };
j.cur = cur;
j.is_eof = is_eof;
j.advance = advance;
j.parse = parse;
return j;
}

Такой подход сильно напоминает Go или Rust, но реализован в старом-добром C.

⚡️ Интересные особенности реализации

В проекте использованы несколько необычных техник:

  • 🎲 Вариативные макросы
    Для упрощения написания JSON автор создал удобный макрос, позволяющий вставлять JSON прямо в код:
    #define JSON(...) #__VA_ARGS__

    // Использование:
    char *raw_json = JSON({ "array": [1, 2, 3] });

Это существенно упрощает тестирование и примеры кода.

  • 📦 Union-ы для экономии памяти
    JSON-значения представлены через структуры и union-ы, чтобы эффективно использовать память для разных типов данных (числа, строки, булевы значения):
    struct json_value {
    enum json_type type;
    union {
    bool boolean;
    char *string;
    double number;
    } value;
    struct json_value *values;
    char **object_keys;
    size_t length;
    };
  • 🔍 Обработка памяти и утечек
    Автор тщательно следит за утечками памяти и создал функцию для освобождения всех выделенных ресурсов:
    void json_free_value(struct json_value *json_value) { ... }

🧪 Компиляция и флаги безопасности

Для безопасности и стабильности автор использует строгие флаги компилятора GCC:

  • 🔒 -Wall, -Wextra, -Werror – максимально строгие проверки.
  • 🚦 -fsanitize=address,undefined – инструменты для выявления ошибок памяти и неопределённого поведения.
  • 🚨 -Wshadow, -Wstrict-prototypes, -Wcast-align – дополнительные проверки для чистоты и надёжности кода.

В итоге компиляция выглядит так:

gcc -std=c23 -O2 -Wall -Wextra -Werror -fsanitize=address,undefined main.c

🔥 Реализация парсера JSON

Парсер написан с нуля без использования сторонних библиотек. Он читает строку посимвольно, игнорируя пробелы и переводит символы в структурированные данные:

  • 🎯 Парсинг атомарных значений (null, true, false, числа и строки).
  • 📚 Парсинг массивов и объектов с динамическим выделением памяти и проверкой корректности структуры данных.

Особенно интересным моментом является использование assert-макроса для быстрого обнаружения ошибок во время парсинга:

#define ASSERT(EXP, context) \
if (!(EXP)) { \
fprintf(stderr, "Ошибка: " context "\n"); \
exit(EXIT_FAILURE); \
}

💡 Личное мнение автора статьи

Честно говоря, первоначально идея писать объектно-ориентированный код на C кажется слегка безумной. Но автор не просто «поигрался» с языком, а показал, как с помощью простых приёмов можно создать достаточно удобный и безопасный интерфейс.

Я считаю, что такой проект – это не просто забавный эксперимент, но и отличная демонстрация возможностей языка C, когда его используют творчески и осторожно. К тому же, подобные эксперименты могут вдохновить разработчиков на написание более безопасного и надёжного низкоуровневого кода.

🚧 Что можно улучшить?

  • 🚀 Оптимизация памяти
    Реализация постоянно использует realloc для каждого нового элемента массива или объекта. Можно улучшить, выделяя память с запасом.
  • 🔐 Поддержка полной спецификации JSON
    Сейчас поддержка строк и чисел ограничена (нет экранированных символов, научной нотации).
  • 🧪 Полноценное тестирование и бенчмарки
    Для надёжного использования в реальных проектах стоит добавить тесты и измерение производительности.

🎯 Кому и зачем это нужно?

Этот проект будет полезен:

  • 🛠️ Тем, кто изучает C и хочет понять тонкости реализации структур и работы с памятью.
  • 🔍 Разработчикам, ищущим вдохновение в реализации удобных API на низкоуровневых языках.
  • 🎓 Студентам и преподавателям, которым нужен хороший учебный пример работы с JSON и указателями на функции.

Итог: C — это мощно, весело и опасно. Но только если вы знаете, что делаете!

🔗 Ссылка:

🔥 Пробуйте, экспериментируйте и пишите красивый и безопасный код!