Command Palette

Search for a command to run...

danikvitek/mavka-did

wasi

Public
wasmer run danikvitek/mavka-did

Парсер формату Дід

Цей проект є реалізацією парсера формату Дід для WebAssembly. Сторінка на WASMER.io

Використання

JavaScript:

import {bindings} from "@danikvitek/mavka-did";

async function main() {
    const did = await bindings.api();
    const code =
`Людина(
  імʼя="Давид",
  прізвище="Когут",
  вік=0,
  параметри=(
    висота=175,
    вага=69
  ),
  зацікавлення=["творення", "життя"]
)`;
    const result = did.parse(code);
    console.log(did.display(result.val, true));
}

WAI API

/// Функція для розбору заданого вхідного рядка у форматі `Дід`.
///
/// Повертає помилку, якщо вхідний рядок не є коректним `Дід`.
parse: func(input: string) -> expected<ast-node, parse-error>

/// Функція для відображення абстрактного синтаксичного дерева
display: func(root: ast-node, pretty: bool) -> string

/// Помилка, видана розбирачем.
record parse-error {
    expectation: parse-error-expectation,
    line: u64,
    column: u64,
    index: u64,
    info: string,
}

/// Вид помилки розбирача.
enum parse-error-expectation {
    /// Очікувався вузол `пусто`
    empty-node,
    /// Очікувався логічний вузол (`так` або `ні`)
    logical-node,
    /// Очікувався числовий вузол
    number-node,
    /// Очікувався текстовий вузол. Явні перенесення рядків не дозволені
    text-node,
    /// Очікувався список
    list-node,
    /// Очікувався словник
    dictionary-node,
    /// Очікувався запис словника
    dictionary-entry-node,
    /// Очікувався ключ запису словника (ідентифікатор, текст або число)
    dictionary-entry-key,
    /// Очікувався об'єкт
    object-node,
    /// Очікувався запис об'єкта
    object-entry-node,
    /// Очікувався вузол формату `Дід`
    ast-node,
    /// Очікувався ідентифікатор запису (має починатися з літери або `_`)
    identifier,
    /// Очікувався знак рівності `=`
    equals-sign,
    /// Очікувалася ліва кругла дужка `(`
    left-parenthesis,
    /// Очікувалася права кругла дужка `)`
    right-parenthesis,
    /// Очікувалася ліва квадратна дужка `[`
    left-bracket,
    /// Очікувалася права квадратна дужка `]`
    right-bracket,
    /// Очікувалося значення запису
    entry-value,
    /// Очікувався кінець файлу
    eof,
}

/// Абстрактне синтаксичне дерево файлу `Дід`.
variant ast-node {
    empty(empty-node),
    logical(logical-node),
    number(number-node),
    text(text-node),
    %list(list-node),
    dictionary(dictionary-node),
    object(object-node),
}

/// Контекст вузла в абстрактному синтаксичному дереві.
record node-context {
    /// Номер рядка вхідного файлу, на якому знаходиться вузол.
    /// Нумерація рядків починається з 1.
    line: u64,
    /// Номер стовпця вхідного файлу, на якому знаходиться вузол.
    /// Нумерація стовпців починається з 1.
    column: u64,
    /// Індекс символу вхідного файлу, на якому починається вузол.
    /// Нумерація символів починається з 0.
    index: u64,
}

/// # Вузол, що представляє відсутність значення.
///
/// 'пусто'
record empty-node {
    context: node-context,
}

/// # Вузол, що представляє логічне значення.
///
/// 'так' або 'ні'
record logical-node {
    value: bool,
    context: node-context,
}

/// # Вузол, що представляє числове значення.
///
/// Число може бути цілим або дійсним.
///
/// ## Приклади
/// - `0`
/// - `-1`
/// - `3.14`
/// - `-2.71828`
record number-node {
    value: string,
    context: node-context,
}

/// # Вузол, що представляє текстове значення.
///
/// - Текстовий вузол є послідовністю символів, обмеженою подвійними лапками (якщо не ідентифікатор).
/// - Текст може містити escape-послідовності (`\n`, `\t`, `\r`, `\\`, `\"`).
/// - Текст не може містити явних перенесень рядків.
///
/// ## Приклади
/// - `""`
/// - `"привіт від Лесі"`
record text-node {
    value: string,
    context: node-context,
}

/// # Вузол, що представляє список вузлів.
///
/// Список це послідовність записів інших вузлів, обмежена квадратними дужками, розділених комами.
///
/// ## Приклади
/// - `[]`
/// - `[так, ні]`
/// - `[1, 2, 3]`
record list-node {
    entries: list<list-entry-node>,
    context: node-context,
}

type list-entry-node = boxed-ast-node

/// Вузол словника.
///
/// Словник це послідовність записів пара ключ-значення текстового/числового вузла та іншого вузла,
/// обмежена круглими дужками, розділених комами.
/// Ключі можуть бути без лапок, якщо вони є коректними ідентифікаторами.
/// 
/// ## Приклади
/// - `()`
/// - `(а=так, "б"=ні)`
/// - `(1=2)`
record dictionary-node {
    entries: list<dictionary-entry-node>,
    context: node-context,
}

/// Вузол запису словника.
///
/// Запис словника це пара ключ-значення текстового/числового вузла та іншого вузла.
/// Ключі можуть бути без лапок, якщо вони є коректними ідентифікаторами.
///
/// ## Приклади
/// - `а=так`
/// - `"б"=ні`
/// - `1=2`
record dictionary-entry-node {
    key: dictionary-entry-key,
    value: boxed-ast-node,
    context: node-context,
}

/// Ключ запису словника.
///
/// Ключ може бути текстовим або числовим вузлом.
/// Якщо ключ є текстовим вузлом, він може бути без лапок, якщо він є коректним ідентифікатором.
///
/// ## Приклади
/// - `а`
/// - `"б"`
/// - `1`
variant dictionary-entry-key {
    text(text-node),
    number(number-node),
}

/// Вузол об'єкту.
///
/// Об'єкт це іменована послідовність записів пара ключ-значення
/// текстового вузла та іншого вузла,
/// між круглими дужками, розділених комами.
/// Ключі мають бути коректними ідентифікаторами без лапок.
///
/// ## Приклади
/// - `Нічого()`
/// - `Людина(ім'я="Леся", вік=20)`
/// - `Координати(x=1, y=2, z=3)`
record object-node {
    name: text-node,
    entries: list<object-entry-node>,
    context: node-context,
}

/// Вузол запису об'єкту.
///
/// Запис об'єкту це пара ключ-значення текстового вузла та іншого вузла.
/// Ключі мають бути коректними ідентифікаторами без лапок.
///
/// ## Приклади
/// - `ім'я="Леся"`
/// - `вік=20`
/// - `x=1`
record object-entry-node {
    key: text-node,
    value: boxed-ast-node,
    context: node-context,
}

/// Запакований вузол абстрактного синтаксичного дерева.
///
/// Використовується для уникнення рекурсій типів.
resource boxed-ast-node {
    /// Створює копію внутрішнього вузла та повертає її.
    get: func() -> ast-node
}

Парсер для формату Дід


Github