SYNX в коде

Last updated: 2026-10-14Чтение .synx напрямую из JavaScript, Python, Rust, Go, C#, Java, Swift, Dart, C++ и через C ABI.

SYNX в коде

Перенесено из репозитория формата — docs/spec/SPECIFICATION_RU.md, SYNX 3.7.4. Правки вносятся там.

🚀 Главный принцип: SYNX читается вашим кодом напрямую. Никакой конвертации в JSON не нужно. Библиотека сама парсит .synx файл и возвращает готовый родной объект вашего языка — dict в Python, Object в JavaScript. Вы работаете с данными сразу.

5.1 Установка

bash
# JavaScript / TypeScript
npm install @aperturesyndicate/synx-format

# Python
pip install synx-format

5.2 Python — чтение .synx напрямую

python
from synx import Synx

# Читаем .synx файл — и сразу получаем dict
data = Synx.load('config.synx')

# Всё. Данные готовы. Работайте как с обычным словарём:
print(data['app_name'])                # "TotalWario"
print(data['server']['port'])          # 8080
print(data['gameplay']['base_hp'])     # 100
print(data['gameplay']['boss_hp'])     # 500 (посчитано через :calc)
print(data['gameplay']['greeting'])    # "Wario time!" (выбрано :random)

# Списки — обычные list:
for map_name in data['map_rotation']:
    print(f'Загружаю карту: {map_name}')

# Вложенность — обычные dict:
if data['server']['ssl_enabled']:
    print('SSL включён')

Метод Synx.load(path) — читает файл и парсит за один вызов.
Метод Synx.parse(text) — парсит строку (если файл уже прочитан).

python
# Альтернативно — из строки:
with open('config.synx', 'r', encoding='utf-8') as f:
    data = Synx.parse(f.read())

5.3 JavaScript — чтение .synx напрямую

javascript
const Synx = require('@aperturesyndicate/synx-format');

// Читаем .synx файл — получаем обычный JS-объект
const data = Synx.loadSync('config.synx');

// Работайте как с обычным объектом через точку:
console.log(data.app_name);               // "TotalWario"
console.log(data.server.port);             // 8080
console.log(data.gameplay.base_hp);        // 100
console.log(data.gameplay.boss_hp);        // 500
console.log(data.gameplay.greeting);       // случайная фраза

// Списки — обычные Array:
data.map_rotation.forEach(map => {
    console.log(`Загружаю карту: ${map}`);
});

// Деструктуризация:
const { base_hp, boss_hp, greeting } = data.gameplay;
console.log(`HP босса: ${boss_hp}, приветствие: ${greeting}`);

Synx.loadSync(path) — читает файл и парсит синхронно.
Synx.load(path) — асинхронная версия (возвращает Promise).
Synx.parse(text) — парсит строку.

javascript
// Асинхронный вариант:
const data = await Synx.load('config.synx');

// Из строки:
const fs = require('fs');
const text = fs.readFileSync('config.synx', 'utf-8');
const data = Synx.parse(text);

5.4 TypeScript — с типизацией

typescript
import Synx from '@aperturesyndicate/synx-format';

// Опишите структуру вашего конфига:
interface GameConfig {
  app_name: string;
  version: string;
  server: {
    port: number;
    host: string;
    ssl_enabled: boolean;
  };
  gameplay: {
    base_hp: number;
    boss_hp: number;
    greeting: string;
    loot_tier: string;
  };
  map_rotation: string[];
}

// Парсер вернёт типизированный объект:
const data = Synx.loadSync<GameConfig>('config.synx');

console.log(data.gameplay.boss_hp);  // number, автодополнение работает
console.log(data.server.port);       // number

5.5 Использование данных SYNX для CSS

SYNX возвращает обычный объект — Object в JS, dict в Python. Вы можете использовать эти данные для генерации CSS, CSS-переменных, или передавать в любую систему стилей.

Пример: CSS-переменные из SYNX в Node.js

synx
# theme.synx
primary #5a6eff
secondary #ff5a8a
font_size 16
border_radius 8
spacing 12
javascript
const Synx = require('@aperturesyndicate/synx-format');
const fs = require('fs');

const theme = Synx.loadSync('theme.synx');

// Генерация CSS-переменных
const css = `:root {
  --color-primary: ${theme.primary};
  --color-secondary: ${theme.secondary};
  --font-size: ${theme.font_size}px;
  --border-radius: ${theme.border_radius}px;
  --spacing: ${theme.spacing}px;
}`;

fs.writeFileSync('theme.css', css);

Пример: Inline-стили в React

tsx
import Synx from '@aperturesyndicate/synx-format';

const theme = Synx.loadSync('theme.synx');

function Button({ children }) {
  return (
    <button style={{
      backgroundColor: theme.primary,
      borderRadius: `${theme.border_radius}px`,
      padding: `${theme.spacing}px`,
      fontSize: `${theme.font_size}px`,
    }}>
      {children}
    </button>
  );
}

Пример: CSS-in-JS (styled-components, Tailwind config)

javascript
// tailwind.config.js
const Synx = require('@aperturesyndicate/synx-format');
const theme = Synx.loadSync('theme.synx');

module.exports = {
  theme: {
    extend: {
      colors: {
        primary: theme.primary,
        secondary: theme.secondary,
      },
      spacing: {
        base: `${theme.spacing}px`,
      },
    },
  },
};

SYNX не заменяет CSS — он предоставляет данные (цвета, размеры, токены), которые ваш код использует для генерации стилей. Это особенно полезно для дизайн-систем и тематизации.


5.6 Rust — типобезопасный парсинг

bash
# Добавить зависимость
cargo add synx-core
rust
use synx::Synx;

fn main() {
    // Читаем .synx файл — парсер возвращает Value
    let data = Synx::load("config.synx").expect("Ошибка при чтении файла");
    
    // Доступ к полям через индексацию:
    println!("Имя приложения: {}", &data["app_name"]);
    println!("Порт сервера: {}", &data["server"]["port"]);
    println!("HP босса: {}", &data["gameplay"]["boss_hp"]);
    
    // Методы для типобезопасного доступа:
    if let Some(app_name) = data["app_name"].as_str() {
        println!("Приложение: {}", app_name);
    }
    
    if let Some(port) = data["server"]["port"].as_int() {
        println!("Порт: {}", port);
    }
    
    // Работа с массивами:
    if let Some(maps) = data["map_rotation"].as_array() {
        for map in maps {
            if let Some(name) = map.as_str() {
                println!("Карта: {}", name);
            }
        }
    }
    
    // Проверка типов:
    match &data["gameplay"]["ssl_enabled"] {
        synx::Value::Bool(b) => println!("SSL: {}", b),
        synx::Value::Null => println!("SSL не задан"),
        _ => println!("Неверный тип"),
    }
}

Методы Value:

  • as_str() -> Option<&str> — строка
  • as_int() -> Option<i64> — целое число
  • as_float() -> Option<f64> — число с плавающей точкой
  • as_bool() -> Option<bool> — булев
  • as_array() -> Option<&[Value]> — массив
  • as_object() -> Option<&Map<String, Value>> — объект (map)
  • is_null() -> bool — null-проверка

📌 Важно: крейт synx-core поддерживает все режимы, включая !active с маркерами (:random, :calc, :env и др.), а также !tool, .synxb и diff.


5.7 C — FFI к synx-core (строки JSON)

Поддерживаемая C-интеграция — bindings/c-header: заголовок include/synx.h и разделяемая или статическая библиотека, которую собирает Rust-крейт synx-c (cdylib / staticlib). Функции возвращают UTF-8 JSON (или байты .synxb); дерева SynxValue в C нет — для дерева используйте ваш JSON-парсер.

Сборка библиотеки (из корня репозитория):

bash
cargo build -p synx-c --release
# Linux: target/release/libsynx_c.so
# macOS: target/release/libsynx_c.dylib
# Windows: target/release/synx_c.dll (+ import .lib для MSVC)

Подключение:

c
#include "synx.h"

Память: каждый char* нужно один раз освободить через synx_free(). Буфер из synx_compile — через synx_free_bytes(ptr, len).

Функции (v3.6): synx_parse, synx_parse_active, synx_stringify, synx_format, synx_parse_tool, synx_compile, synx_decompile, synx_is_synxb, synx_diff — см. bindings/c-header/include/synx.h.

Минимальный пример:

c
#include "synx.h"
#include <stdio.h>

int main(void) {
    char *json = synx_parse("name John\nage 25\n");
    if (!json) {
        fputs("parse failed\n", stderr);
        return 1;
    }
    puts(json);
    synx_free(json);
    return 0;
}

Паритет: тот же движок, что у synx-core 3.6.x (!active, !tool, .synxb, канонический JSON).


5.8 C++ — тонкая обёртка (bindings/cpp)

Официальная C++-обвязка — bindings/cpp/include/synx/synx.hpp (пространство имён synx): тонкая обёртка C++17 над §5.7, с std::optional и std::vector<unsigned char> для .synxb. Нужна та же библиотека synx-c и оба include-пути (bindings/cpp/include, bindings/c-header/include).

Пример:

cpp
#include <synx/synx.hpp>
#include <iostream>

int main() {
    auto json = synx::parse("name Wario\nage 30\n");
    if (!json) return 1;
    std::cout << *json << '\n';
    return 0;
}

Обёртки: parse, parse_active, stringify, format, parse_tool, diff, compile, decompile, is_synxb — семантика как у synx.h.

Сборка: bindings/cpp/README.md, bindings/cpp/CMakeLists.txt (опциональный пример).

Паритет: поведение совпадает с Rust synx-core для всех операций, экспортируемых через FFI.


5.9 C# — библиотека для .NET 8 (parsers/dotnet)

Поддерживаемая реализация — parsers/dotnet/src/Synx.Core, целевой фреймворк .NET 8.0. NuGet: APERTURESyndicate.Synx (идентификатор Synx.Core на nuget.org занят другим пакетом).

Установка (NuGet):

bash
dotnet add package APERTURESyndicate.Synx

Карточка пакета: nuget.org/packages/APERTURESyndicate.Synx. Пока пакета нет в ленте — ссылка на проект или локальный .nupkg, см. parsers/dotnet/README.md.

Пример:

csharp
using Synx;

var map = SynxFormat.Parse("server\n  host 0.0.0.0\n  port 8080\n");
if (map["server"] is SynxValue.Obj server
    && server.Map["port"] is SynxValue.Int port)
    Console.WriteLine(port.Value);

var json = SynxFormat.ToJson(map);

// Разрешение !active (маркеры, ограничения, include)
var resolved = SynxFormat.ParseActive("!active\nport:env:default:8080 PORT\n");

Точки входа (SynxFormat): Parse, ParseActive, ParseFull, ParseFullActive, ParseTool, ToJson.

Значения: дискриминированные записи SynxValue — Null, Bool, Int, Float, Str, Secret, Arr, Obj.

Паритет: статический разбор и канонический JSON совпадают с synx-core на покрытых conformance-кейсах; ParseActive запускает управляемый движок !active. .synxb в C# пока нет (используйте synx-core или привязки к synx-c).


5.10 Go — cgo к synx-c (API через JSON)

Поддерживаемая интеграция — bindings/go: cgo оборачивает тот же synx.h / synx-c, что и C/C++. Функции возвращают UTF-8 строки (JSON или текст SYNX) или срезы байт (.synxb); дерево разбора — через encoding/json.

Требования: Go 1.21+, CGO_ENABLED=1, C-компилятор, собранный synx-c (cargo build -p synx-c --release). Linux/macOS: линковка по умолчанию -L../../target/release -lsynx_c относительно bindings/go. Windows: CGO_LDFLAGS на synx_c.dll.lib, synx_c.dll в PATH — см. bindings/go/README.md.

Пример:

go
package main

import (
    "fmt"
    synx "github.com/APERTURESyndicate/synx-format/bindings/go"
)

func main() {
    j, err := synx.Parse("name Wario\nage 30\n")
    if err != nil {
        panic(err)
    }
    fmt.Println(j)
}

API (v3.6): Parse, ParseActive, Stringify, Format, ParseTool, Compile, Decompile, IsSynxb, Diff — как в synx.h.

Паритет: тот же движок, что у synx-core (!active, !tool, .synxb, канонический JSON).


5.11 Mojo — Python interop (bindings/mojo)

Mojo вызывает CPython через Python.import_module. Чтобы получить паритет SYNX 3.6 с synx-core, используйте модуль synx_native (тот же PyO3 / maturin, что и pip install synx-format). Отдельная чистая реализация грамматики на Mojo в этом репозитории не поставляется — это был бы отдельный крупный порт (как поддерживать synx-js рядом с Rust).

Установка: Python-пакет с synx_native. При локальной сборке — maturin develop; при необходимости Python.add_to_path.

Строковые API на стороне Python: parse_to_json, parse_active_to_json, parse_tool_to_json, stringify_json, format, compile_hex, decompile_hex, is_synxb_hex, diff_json.

Пример: bindings/mojo/examples/demo.mojo, документация — bindings/mojo/README.md.

Паритет: как у synx-core, потому что выполняется synx_native (Rust).


5.12 Kotlin / JVM — bindings/kotlin (JNA + synx-c)

Поддерживаемая JVM-интеграция в этом репозитории — bindings/kotlin: SynxEngine подгружает synx_c через JNA. Результаты — канонический JSON в виде String (или ByteArray для .synxb), при необходимости декодируйте сами.

1. Сборка нативной библиотеки (корень репозитория): cargo build -p synx-c --release.

2. Сборка / тесты из bindings/kotlin: задайте SYNX_LIB_DIR на каталог с libsynx_c / synx_c.dll, затем ./gradlew test. См. bindings/kotlin/README.md.

Пример:

kotlin
import com.aperturesyndicate.synx.SynxEngine

val json = SynxEngine.parse("name Wario\nage 30\n")
val tool = SynxEngine.parseTool("!tool\nweb_search\n  query test\n")
val active = SynxEngine.parseActive("!active\nport:env:default:8080 PORT\n")

API (v3.6): SynxEngine.parse, parseActive, stringify, format, parseTool, diff, compile, decompile, isSynxb — как в bindings/c-header/include/synx.h.

Паритет: тот же движок, что synx-core (включая !active, !tool, .synxb, diff). Для Gradle нужен JDK 17+; артефакт com.aperturesyndicate:synx-kotlin на Maven Central может появиться позже; пока — publishToMavenLocal.


5.13 Swift — SwiftPM + synx-c (C interop)

Поддерживаемая Swift-интеграция — bindings/swift: пакет SwiftPM с модулем CSynx (synx.h, линковка -lsynx_c). На границе — String и Data; результаты парсинга в основном канонический JSON (при необходимости декодируйте сами).

Сборка C-библиотеки (корень репозитория): cargo build -p synx-c --release, затем swift build с -L / -lsynx_c. См. bindings/swift/README.md.

Пример:

swift
import Synx

let json = try SynxEngine.parse("name Wario\nage 30\n")
print(json)

API (v3.6): SynxEngine.parse, parseActive, stringify(json:), format, parseTool, diff, compile, decompile, isSynxb — как в synx.h.

Паритет: тот же движок, что synx-core. Файл Sources/CSynx/synx.h должен совпадать с bindings/c-header/include/synx.h.


5.14 Lua — парсер без зависимостей

Установка:

Скопируйте synx.lua в свой проект:

lua
local synx = require("synx")

Использование:

lua
local synx = require("synx")

-- Парсинг строки
local data = synx.parse(text)
print(data:get("server"):get("port"):as_int())  -- 8080

-- Парсинг файла
local data = synx.parse_file("config.synx")
print(data:get("server"):get("host"):as_str())  -- localhost

-- Полный парсинг (определение режима)
local result = synx.parse_full(text)
print(result.mode)  -- "static" или "active"

API:

  • synx.parse(text) → SynxValue
  • synx.parse_full(text) → { root, mode }
  • synx.parse_file(path) → SynxValue, err
  • SynxValue:get(key) — дочерний элемент по ключу или индексу (с 1)
  • SynxValue:as_bool(), :as_int(), :as_float(), :as_str()
  • SynxValue:len(), :keys(), :type(), :is_null()

📌 Важно: Lua-парсер работает только в режиме static — активные маркеры не вычисляются. Работает с Lua 5.1+ и LuaJIT.


5.15 Dart / Flutter — нативный парсер

Установка (pubspec.yaml):

yaml
dependencies:
  synx:
    git:
      url: https://github.com/APERTURESyndicate/synx-format.git
      path: packages/synx-dart

Использование:

dart
import 'package:synx/synx.dart';

// Парсинг строки
final data = Synx.parse(text);
print(data['server']['port'].asInt); // 8080

// Парсинг файла
final data = Synx.parseFile('config.synx');

// Полный парсинг (определение режима)
final result = Synx.parseFull(text);
print(result.mode); // SynxMode.active

Использование во Flutter:

dart
import 'package:synx/synx.dart';
import 'package:flutter/services.dart' show rootBundle;

Future<SynxValue> loadConfig() async {
  final text = await rootBundle.loadString('assets/config.synx');
  return Synx.parse(text);
}

API:

  • Synx.parse(text) → SynxValue
  • Synx.parseFull(text) → SynxParseResult { root, mode }
  • Synx.parseFile(path) → SynxValue
  • SynxValue[key] — доступ по ключу или индексу
  • .asBool, .asInt, .asFloat, .asStr
  • .length, .keys, .type, .isNull

📌 Важно: Dart-парсер работает только в режиме static — активные маркеры не вычисляются. Требуется Dart 3.0+.


5.16 PHP — нативный парсер

Установка:

Скопируйте Synx.php в свой проект:

php
require_once 'Synx.php';

Использование:

php
require_once 'Synx.php';

// Парсинг из строки
$data = Synx::parse($text);
echo $data->get('server')->get('port')->asInt(); // 8080

// Парсинг из файла
$data = Synx::loadFile('config.synx');

// Полный парсинг (определение режима)
$result = Synx::parseFull($text);
echo $result->mode; // "static" или "active"

API:

  • Synx::parse($text) → SynxValue
  • Synx::parseFull($text) → SynxParseResult { root, mode }
  • Synx::loadFile($path) → SynxValue
  • ->get($key) — дочерний элемент по строковому ключу или целочисленному индексу
  • ->asBool(), ->asInt(), ->asFloat(), ->asStr()
  • ->length(), ->keys(), ->type(), ->isNull()

📌 Важно: PHP-парсер работает только в режиме static — активные маркеры не вычисляются. Требуется PHP 8.0+.


5.17 Bash / PowerShell — парсеры для командных оболочек

Bash (4.0+)

Установка:

bash
source synx.sh

Использование:

bash
source synx.sh

synx_parse_file "config.synx"
echo "$(synx_get server.host)"     # localhost
echo "$(synx_get server.port)"     # 8080
echo "$(synx_type server.port)"    # int
echo "$(synx_mode)"                # static

# Массивы
echo "$(synx_get items.0)"         # Sword
echo "$(synx_get items.__length)"  # 3

API:

  • synx_parse "$text" — парсинг текста SYNX
  • synx_parse_file "$path" — чтение и парсинг файла
  • synx_get "$path" — значение по dot-notation пути
  • synx_type "$path" — тип значения
  • synx_mode — режим документа

Примечание: Значения хранятся в плоских ассоциативных массивах с dot-notation ключами (например server.host).

PowerShell (5.1+)

Установка:

powershell
. .\Synx.ps1

Использование:

powershell
. .\Synx.ps1

$result = Read-SynxFile "config.synx"
$result.Root.server.host           # localhost
$result.Root.server.port           # 8080 (int)
$result.Root.items[0]              # Sword
$result.Mode                       # static

API:

  • ConvertFrom-Synx $text → PSCustomObject { Root, Mode }
  • Read-SynxFile $path → то же самое

Объекты — [ordered]@{}, массивы — нативные PowerShell-массивы, скаляры типизированы ([long], [double], [bool], [string], $null).

📌 Важно: Оба парсера для командных оболочек работают только в режиме static — активные маркеры не вычисляются.


5.18 Сравнение: SYNX напрямую vs JSON

JSONSYNX
Чтение (JS)JSON.parse(fs.readFileSync(...))Synx.loadSync('file.synx')
Чтение (Python)json.load(open(...))Synx.load('file.synx')
Чтение (Rust)serde_json::from_str(...)Synx::parse_file(...)
Чтение (C)cJSON_Parse(...)synx_parse(text)
Чтение (C++)nlohmann::json::parse(...)synx::Synx::load(path)
Чтение (C#)JsonSerializer.Deserialize(...)SynxFormat.Parse(File.ReadAllText(path))
Чтение (Go)json.Unmarshal(...)synx.ParseFile(path)
Чтение (Java)new ObjectMapper().readTree(...)Synx.load(path)
Чтение (Swift)JSONDecoder().decode(...)Synx.load(path)
Чтение (Lua)cjson.decode(...)synx.parse(text)
Чтение (Dart)jsonDecode(...)Synx.parse(text)
Чтение (PHP)json_decode(...)Synx::parse($text)
Чтение (Bash)jq '.key' file.jsonsynx_get "key"
Чтение (PowerShell)ConvertFrom-JsonConvertFrom-Synx
Промежуточный форматНетНет — тоже нет!
Что получаетеObject / dict / ValueObject / dict / Value (то же самое)
Встроенная логикаНет — пишете руками:random, :calc, :env из коробки
ВалидацияНет — нужна отдельная библиотека[min:3, type:int] прямо в файле
Размер файла~100%~40% меньше (нет кавычек/скобок)

По языкам:

ЯзыкПакетМетодПримечание
JavaScript@aperturesyndicate/synx-formatSynx.loadSync()Полный движок (active + static)
Pythonsynx-formatSynx.load()Полный движок (active + static)
Rustsynx-core (crates.io)Synx::parse()Без зависимостей, все режимы включая !active
Csynx.h + lib synx-csynx_parse() → JSONFFI к synx-core 3.6.x
C++synx/synx.hpp + та же libsynx::parse() → optional<string>Тонкая обёртка, тот же движок
C#APERTURESyndicate.Synx (NuGet)SynxFormat / API парсераБиблиотека .NET 8; идентификатор Synx.Core занят на nuget.org
Gobindings/go (cgo) + synx-csynx.Parse() → JSONТот же движок, что Rust
Mojobindings/mojo + CPython synx_nativeparse_json() / parse_active_json() …Паритет через PyO3; не чистый Mojo-парсер
Kotlin/JVMbindings/kotlin + synx-cSynxEngine.parse() → JSON StringJNA; сборка JDK 17+; тот же движок, что Rust
Swiftbindings/swift + synx-cSynxEngine.parse() → JSON StringC interop; тот же движок, что Rust
Luasynx.lua (копирование)synx.parse()Lua 5.1+, без зависимостей, static-only
Dart/Fluttersynx (pub.dev / git)Synx.parse()Dart 3.0+, static-only
PHPSynx.php (копирование)Synx::parse()PHP 8.0+, без зависимостей, static-only
Bashsynx.sh (копирование)synx_get()Bash 4.0+, без зависимостей, static-only
PowerShellSynx.ps1 (копирование)ConvertFrom-SynxPowerShell 5.1+, без зависимостей, static-only
SYNX в коде | AS Docs