// -------------------------------------------------------------------------
// TODOTXT PARSER GRAMMAR
// Офіційна граматика для todo.txt, реалізована за допомогою Pest.
// Ця граматика підтримує всі основні компоненти: статус, пріоритет, дати та теги.
// -------------------------------------------------------------------------
// Базове правило: Пробіл є "тихим" (`_`) і поглинається автоматично між правилами.
WHITESPACE = _{ " " | "\t" }
// ---------------------- АТОМАРНІ ПРАВИЛА ----------------------
// Будь-який символ, що не є пробілом або кінцем вводу. Використовується для тегів.
non_whitespace_char = _{ !(WHITESPACE | EOI) ~ ANY }
// Правило `date`: Парсить дату у форматі YYYY-MM-DD (Правило 5).
date = @{ ASCII_DIGIT{4} ~ "-" ~ ASCII_DIGIT{2} ~ "-" ~ ASCII_DIGIT{2} }
// Просте слово або послідовність символів, що не є пробілами.
word = @{ non_whitespace_char+ }
// Правило `priority`: Пріоритет, напр. (A), (B). Вимагає однієї великої літери.
priority_tag = @{ "(" ~ ASCII_ALPHA_UPPER ~ ")" }
// Правило `completion`: Маркер завершення завдання "x ".
completion_marker = @{ "x" }
// ---------------------- ПРАВИЛА ТЕГІВ І ОПИСУ ----------------------
// Правило `project`: Парсить теги проєктів (напр., "+Work", "+Family").
project = @{ "+" ~ non_whitespace_char+ }
// Правило `context`: Парсить теги контексту (напр., "@home", "@office").
context = @{ "@" ~ non_whitespace_char+ }
// Правило `due_date`: Парсить тег дати виконання "due:YYYY-MM-DD".
due_date = @{ "due:" ~ date }
// Правило `text_part`: Парсить будь-яке слово, що не є тегом (`+`, `@`, `due:`).
text_part = @{ !("+" | "@" | "due:") ~ word }
// ---------------------- СТРУКТУРНІ ПРАВИЛА ----------------------
// Ці правила НЕ використовують явний WHITESPACE, оскільки він тихий (див. WHITESPACE).
// Правило `completion`: Розпізнає статус завершення "x " (Правило 1).
completion = { completion_marker }
// Правило `priority`: Розпізнає пріоритет "(A) " (Правило 2).
priority = { priority_tag }
// Правило `creation_date`: Розпізнає дату створення "YYYY-MM-DD " (Правило 6).
creation_date = { date }
// ---------------------- ГОЛОВНЕ ПРАВИЛО ----------------------
// Правило `task_line` (Фінальна структура рядка завдання)
// Виконує обробку рядка у суворому порядку:
// 1. SOI: Початок вводу.
// 2. completion?: Опціональний статус "x".
// 3. priority?: Опціональний пріоритет "(A)".
// 4. creation_date?: Опціональна дата створення.
// 5. (project | context | due_date | text_part)*: Нуль або більше частин опису (Правило 3).
// 6. EOI: Кінець вводу.
task_line = { SOI ~ completion? ~ priority? ~ creation_date? ~ (project | context | due_date | text_part)* ~ EOI }