SYNX в коде
Перенесено из репозитория формата — docs/spec/SPECIFICATION_RU.md, SYNX 3.7.4. Правки вносятся там.
🚀 Главный принцип: SYNX читается вашим кодом напрямую. Никакой конвертации в JSON не нужно. Библиотека сама парсит
.synxфайл и возвращает готовый родной объект вашего языка —dictв Python,Objectв JavaScript. Вы работаете с данными сразу.
5.1 Установка
# JavaScript / TypeScript
npm install @aperturesyndicate/synx-format
# Python
pip install synx-format5.2 Python — чтение .synx напрямую
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) — парсит строку (если файл уже прочитан).
# Альтернативно — из строки:
with open('config.synx', 'r', encoding='utf-8') as f:
data = Synx.parse(f.read())5.3 JavaScript — чтение .synx напрямую
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) — парсит строку.
// Асинхронный вариант:
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 — с типизацией
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); // number5.5 Использование данных SYNX для CSS
SYNX возвращает обычный объект — Object в JS, dict в Python. Вы можете использовать эти данные для генерации CSS, CSS-переменных, или передавать в любую систему стилей.
Пример: CSS-переменные из SYNX в Node.js
# theme.synx
primary #5a6eff
secondary #ff5a8a
font_size 16
border_radius 8
spacing 12const 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
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)
// 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 — типобезопасный парсинг
# Добавить зависимость
cargo add synx-coreuse 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-парсер.
Сборка библиотеки (из корня репозитория):
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)Подключение:
#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.
Минимальный пример:
#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-core3.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).
Пример:
#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):
dotnet add package APERTURESyndicate.SynxКарточка пакета: nuget.org/packages/APERTURESyndicate.Synx. Пока пакета нет в ленте — ссылка на проект или локальный .nupkg, см. parsers/dotnet/README.md.
Пример:
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.
Пример:
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.
Пример:
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.
Пример:
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 в свой проект:
local synx = require("synx")Использование:
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)→SynxValuesynx.parse_full(text)→{ root, mode }synx.parse_file(path)→SynxValue, errSynxValue: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):
dependencies:
synx:
git:
url: https://github.com/APERTURESyndicate/synx-format.git
path: packages/synx-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:
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)→SynxValueSynx.parseFull(text)→SynxParseResult { root, mode }Synx.parseFile(path)→SynxValueSynxValue[key]— доступ по ключу или индексу.asBool,.asInt,.asFloat,.asStr.length,.keys,.type,.isNull
📌 Важно: Dart-парсер работает только в режиме
static— активные маркеры не вычисляются. Требуется Dart 3.0+.
5.16 PHP — нативный парсер
Установка:
Скопируйте Synx.php в свой проект:
require_once 'Synx.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)→SynxValueSynx::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+)
Установка:
source synx.shИспользование:
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)" # 3API:
synx_parse "$text"— парсинг текста SYNXsynx_parse_file "$path"— чтение и парсинг файлаsynx_get "$path"— значение по dot-notation путиsynx_type "$path"— тип значенияsynx_mode— режим документа
Примечание: Значения хранятся в плоских ассоциативных массивах с dot-notation ключами (например
server.host).
PowerShell (5.1+)
Установка:
. .\Synx.ps1Использование:
. .\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 # staticAPI:
ConvertFrom-Synx $text→PSCustomObject { Root, Mode }Read-SynxFile $path→ то же самое
Объекты — [ordered]@{}, массивы — нативные PowerShell-массивы, скаляры типизированы ([long], [double], [bool], [string], $null).
📌 Важно: Оба парсера для командных оболочек работают только в режиме
static— активные маркеры не вычисляются.
5.18 Сравнение: SYNX напрямую vs JSON
| JSON | SYNX | |
|---|---|---|
| Чтение (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.json | synx_get "key" |
| Чтение (PowerShell) | ConvertFrom-Json | ConvertFrom-Synx |
| Промежуточный формат | Нет | Нет — тоже нет! |
| Что получаете | Object / dict / Value | Object / dict / Value (то же самое) |
| Встроенная логика | Нет — пишете руками | :random, :calc, :env из коробки |
| Валидация | Нет — нужна отдельная библиотека | [min:3, type:int] прямо в файле |
| Размер файла | ~100% | ~40% меньше (нет кавычек/скобок) |
По языкам:
| Язык | Пакет | Метод | Примечание |
|---|---|---|---|
| JavaScript | @aperturesyndicate/synx-format | Synx.loadSync() | Полный движок (active + static) |
| Python | synx-format | Synx.load() | Полный движок (active + static) |
| Rust | synx-core (crates.io) | Synx::parse() | Без зависимостей, все режимы включая !active |
| C | synx.h + lib synx-c | synx_parse() → JSON | FFI к synx-core 3.6.x |
| C++ | synx/synx.hpp + та же lib | synx::parse() → optional<string> | Тонкая обёртка, тот же движок |
| C# | APERTURESyndicate.Synx (NuGet) | SynxFormat / API парсера | Библиотека .NET 8; идентификатор Synx.Core занят на nuget.org |
| Go | bindings/go (cgo) + synx-c | synx.Parse() → JSON | Тот же движок, что Rust |
| Mojo | bindings/mojo + CPython synx_native | parse_json() / parse_active_json() … | Паритет через PyO3; не чистый Mojo-парсер |
| Kotlin/JVM | bindings/kotlin + synx-c | SynxEngine.parse() → JSON String | JNA; сборка JDK 17+; тот же движок, что Rust |
| Swift | bindings/swift + synx-c | SynxEngine.parse() → JSON String | C interop; тот же движок, что Rust |
| Lua | synx.lua (копирование) | synx.parse() | Lua 5.1+, без зависимостей, static-only |
| Dart/Flutter | synx (pub.dev / git) | Synx.parse() | Dart 3.0+, static-only |
| PHP | Synx.php (копирование) | Synx::parse() | PHP 8.0+, без зависимостей, static-only |
| Bash | synx.sh (копирование) | synx_get() | Bash 4.0+, без зависимостей, static-only |
| PowerShell | Synx.ps1 (копирование) | ConvertFrom-Synx | PowerShell 5.1+, без зависимостей, static-only |