Реализация парсера Links Notation для Rust с использованием библиотеки комбинаторов парсеров nom.
Добавьте это в ваш Cargo.toml:
[dependencies]
links-notation = { path = "." } # Для локальной разработки
# Или из реестра:
# links-notation = "0.9.0"Клонируйте репозиторий и соберите:
git clone https://github.com/link-foundation/links-notation.git
cd links-notation/rust
cargo buildСборка проекта:
cargo buildСборка с оптимизациями:
cargo build --releaseЗапуск тестов:
cargo testЗапуск тестов с выводом:
cargo test -- --nocaptureuse links_notation::{parse_lino, LiNo};
fn main() {
// Парсинг строки в формате Links Notation
let input = r#"папа (любитМаму: любит маму)
сын любитМаму
дочь любитМаму
все (любят маму)"#;
match parse_lino(input) {
Ok(parsed) => {
println!("Распарсено: {}", parsed);
// Обращение к структуре
if let LiNo::Link { values, .. } = parsed {
for link in values {
println!("Связь: {}", link);
}
}
}
Err(e) => eprintln!("Ошибка парсинга: {}", e),
}
}use links_notation::LiNo;
// Создание связей программно
let reference = LiNo::Ref("некоторое_значение".to_string());
let link = LiNo::Link {
id: Some("родитель".to_string()),
values: vec![
LiNo::Ref("ребенок1".to_string()),
LiNo::Ref("ребенок2".to_string()),
],
};
// Проверка типов связей
if link.is_link() {
println!("Это связь");
}
if reference.is_ref() {
println!("Это ссылка");
}use links_notation::parse_lino;
let input = "(родитель: ребенок1 ребенок2)";
let parsed = parse_lino(input).unwrap();
// Обычное форматирование (в скобках)
println!("Обычное: {}", parsed);
// Альтернативное форматирование (построчно)
println!("Альтернативное: {:#}", parsed);use links_notation::parse_lino;
// Формат одной строки
let single_line = "идентификатор: значение1 значение2";
let parsed = parse_lino(single_line)?;
// Формат в скобках
let parenthesized = "(идентификатор: значение1 значение2)";
let parsed = parse_lino(parenthesized)?;
// Многострочный с отступами
let indented = r#"родитель
ребенок1
ребенок2"#;
let parsed = parse_lino(indented)?;
// Кавычки в идентификаторах и значениях
let quoted = r#"("идентификатор с пробелами": "значение с пробелами")"#;
let parsed = parse_lino(quoted)?;папа (любитМаму: любит маму)
сын любитМаму
дочь любитМаму
все (любят маму)
папа имеет машину
мама имеет дом
(папа и мама) счастливы
(нотацияСвязей: нотация связей)
(Это тоже нотацияСвязей)
(нотацияСвязей поддерживает (неограниченное количество (ссылок) в каждой связи))
родитель
ребенок1
ребенок2
внук1
внук2
Представляет либо связь, либо ссылку:
Link { id: Option<T>, values: Vec<Self> }- Связь с опциональным ID и дочерними значениямиRef(T)- Ссылка на другую связь
is_ref() -> bool- Возвращает true, если это ссылкаis_link() -> bool- Возвращает true, если это связь
Парсит строку документа Links Notation и возвращает распарсенную структуру или ошибку.
Трейт Display реализован для LiNo<T> где T: ToString:
- Обычный формат:
format!("{}", lino)- Вывод в скобках - Альтернативный формат:
format!("{:#}", lino)- Построчный вывод
- nom (8.0) - Библиотека комбинаторов парсеров
Парсер возвращает описательные сообщения об ошибках для:
- Пустого ввода или ввода только из пробелов
- Неправильного синтаксиса
- Незакрытых скобок
- Недопустимых символов
match parse_lino("(недопустимо") {
Ok(parsed) => println!("Распарсено: {}", parsed),
Err(error) => eprintln!("Ошибка: {}", error),
}