Материал FTS in Russian and English: syntax without brackets
0%

FTS in Russian and English: syntax without brackets

FTS in Russian and English: syntax without brackets

This chapter closes the question that usually comes first: if a model is written by a Russian-speaking analyst and a developer who is more accustomed to reading English texts, does this mean two different languages and two parsers? No — the same result, two surfaces.

Minimal example

категория «Продажи»

  объект Покупка
    сумма является деньгами
    «постоянный клиент» является признаком

  утилита «Рассчитать скидку»
    принимает Покупка
    возвращает деньги
    начинает с 0

    правило «Большая покупка»
      если сумма не меньше 10000
      и сумма не больше 100000
      то добавить 10 процентов от поля сумма

    правило «Постоянный клиент»
      если «постоянный клиент» равен да
      и сумма больше 0
      и сумма не больше 100000
      то добавить 5 процентов от поля сумма

    правило «Очень крупная покупка»
      если сумма больше 100000
      то добавить 15000

    свойство «Скидка ограничена»
      результат не больше 15000

    пример «Обычная покупка»
      дано сумма равна 5000
      дано «постоянный клиент» равен нет
      ожидается результат равен 0

    пример «Постоянный клиент на пять тысяч»
      дано сумма равна 5000
      дано «постоянный клиент» равен да
      ожидается результат равен 250

    пример «Большая покупка постоянного клиента»
      дано сумма равна 20000
      дано «постоянный клиент» равен да
      ожидается результат равен 3000

    пример «Покупка на потолок скидки»
      дано сумма равна 100000
      дано «постоянный клиент» равен да
      ожидается результат равен 15000

    пример «Очень крупная покупка»
      дано сумма равна 200000
      дано «постоянный клиент» равен нет
      ожидается результат равен 15000

What the compiler does

Before parsing, the compiler looks at the first non-empty, non-comment line of the file. If it starts with категория or category and does not contain {, the entire file is passed to the indented parser of natural syntax (looksLikeNaturalSurface). If the line starts with category, the compiler first line-by-line replaces reserved phrases with Russian ones — if into если, then add into то добавить, is at least into не меньше, percent of field into процентов от поля» и так далее — и только потом отдаёт получившийся текст тому же самому parseNaturalSurface. Это не второй интерпретатор и не перевод через LLM: фиксированный набор regex-подстановок по позиции в строке, который не трогает содержимое кавычек и сохраняет отступы и номера строк — поэтому ошибка в английской записи указывает на ту же строку файла, что и в русской. Если первая строка не подходит ни под одно из условий (например, в файле остался старый скобочный category “X” { … }`), the compiler switches to the legacy parser with curly braces — it is accepted for backward compatibility but is not the recommended authoring format.

English surface

category "Sales"

  object Purchase
    amount is money
    "loyal customer" is boolean

  utility "Calculate discount"
    accepts Purchase
    returns money
    starts with 0

    rule "Large purchase"
      if amount is at least 10000
      and amount is at most 100000
      then add 10 percent of field amount

    rule "Loyal customer"
      if "loyal customer" equals true
      and amount is greater than 0
      and amount is at most 100000
      then add 5 percent of field amount

    rule "Very large purchase"
      if amount is greater than 100000
      then add 15000

    property "Discount is capped"
      result is at most 15000

    example "Regular purchase"
      given amount equals 5000
      given "loyal customer" equals false
      expected result equals 0

    example "Large loyal purchase"
      given amount equals 20000
      given "loyal customer" equals true
      expected result equals 3000

    example "Purchase at the discount cap"
      given amount equals 100000
      given "loyal customer" equals true
      expected result equals 15000

Compare these two blocks: the rules, percentages and numbers in the examples match one to one, but Sales/Sales, Purchase/Purchase, amount/amount — разные слова, не автоперевод. Английская запись независимо называет предметные сущности; переводятся только зарезервированные служебные фразы (category, if, then, is at least, percent of field and similar), while the field names, objects and categories remain as the author wrote them. This means that Russian and English documents are free to describe different ubiquitous languages, if these are two different subject dictionaries — but since both compile with one parser into the same canonical model, the utility behavior and field types will be identical with identical rule structure.

Structure is equal to object

структура «Строка счёта»
  номер является строкой
  сумма является деньгами
  комментарий иногда является строкой

structure и object — синонимы на уровне синтаксиса: оба варианта строят одинаковый узел FtsStructure в JSON. Выбор слова — вопрос стиля команды, а не семантики: некоторые предпочитают «объект» для сущностей с состоянием и «структура» для чистых DTO, но компилятор эту границу не проверяет.

Имена и кавычки

Имя из одного слова можно писать без кавычек: Order, amount, number. Пробел делает кавычки обязательными — и, что важно, объявление обязано иметь отступ относительно строки category, otherwise the compiler will assume that the document has ended at the first line after the heading:

категория «Обслуживание клиентов»

  объект "Строка счёта"
    номер является строкой

Quotation marks and Russian ёlочки are intentionally mixed in this example — «Customer service» и "Invoice string" — оба вида равноправны для компилятора и не создают двух разных синтаксисов внутри одного файла. Имя читается функцией, которая всегда завершает разбор вызовом .normalize("NFC"). Поэтому визуально одинаковая буква «й», собранная как одна кодовая точка или как «и» с отдельным комбинирующим знаком, превращается в одно и то же имя поля, а не в два разных.

CamelCase не требуется. В предметном тексте предпочтительнее «ready for shipment», чем ReadyForShipment, если модель читают русскоязычные аналитики и разработчики вперемешку.

Значения

Русская запись принимает yes, no, nothing; обе поверхности принимают true, false, null, numbers and quoted strings. Field names are not translated when switching the surface — this is the model author’s responsibility, not the compiler’s.

Practice in the sandbox

Open the same model для order-discount.en.fts (если песочница даёт выбор модели, сравните оба JSON вручную по исходникам в static/fts/models/). Убедитесь, что rules, properties и examples совпадают числами и операторами, а различаются только строки category, structures[].name и structures[].fields[].name.

Change the first line "Sales" на Sales без кавычек (одно слово — кавычки не обязательны) и убедитесь, что check по-прежнему возвращает valid: true — quotes are needed only where the name contains a space.

Rename the object «Line Item» в "Line Item, version 2" (добавьте пробел и запятую), но не трогайте theorem, которая ссылается на старое имя. Запустите check и найдите диагностику FTS_UNKNOWN_FIELD — она покажет, что имя нужно поменять во всех местах вручную: компилятор не переименовывает ссылки за автора.

Типичные ошибки

FTS_NATURAL_INDENT — объявление верхнего уровня (object, structure, morphism, theorem, utility) написано без отступа относительно строки category. Компилятор считает, что документ закончился, и сообщает: «объявление должно иметь отступ относительно категории». Именно эта ошибка была в блоке «Имена и кавычки» этой главы до правки — object "Line Item" стоял на той же колонке, что и category. Правка — минимум один пробел или таб отступа, и дальше вложенность считается уже от первой такой строки.

FTS_EXPECTED_KEYWORD — первая строка не опознана ни как category, ни как category, и компилятор молча переключается на легаси-парсер с фигурными скобками, который тут же требует буквально слово category. Опечатка category «Sales» (без «о») даёт диагностику expected 'category' — in English, even if the rest of the file is in Russian. This is not a localization bug, but a consequence of automatic surface detection from the first line: if it is not recognized as natural syntax, the document is interpreted as an outdated bracket format. Fix — check the spelling of the first word in the file.

Checklist

  • I explain that the Russian and English notations are one parser and one canonical model, not a translation.
  • I know that only reserved phrases are translated, not names of objects, fields, and categories.
  • I write multiword names in quotes and do not confuse the required indentation of top-level declarations.
  • I know that names are normalized in NFC, and do not rely on visual character matches.

Cases in the catalog on this topic

Next: structures and types

Нашли неточность? Выделите фрагмент текста — рядом появится жучок.

Нужен разбор именно вашей ситуации?

Статья описывает общий случай. Если у вас частный — можно разобрать его отдельно, платно. А если не хватает целого материала, предложите тему: её оплачивают вскладчину, и она выходит открытой для всех.

Доска запросов
Дальше