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
}