# Формальное описание синтаксиса выражений SMath Studio (расширенная БНФ)

## Общие положения

- Используется EBNF (расширенная форма Бэкуса–Наура)
- Пробелы между элементами **не допускаются** во внутреннем строковом представлении, кроме содержимого внутри строковых литералов (в двойных кавычках)
- Символ `:` означает оператор присваивания (отображается как `:=`)
- Символ `=` используется **только** в пользовательском интерфейсе как обозначение вывода результата, во внутреннем представлении — не используется
- Приближённое сравнение (`≈`) использует значение ε, заданное в настройках SMath Studio, и по умолчанию точность равна трём (3) знакам после запятой
- Тело циклов определяй через `line()`, если оно содержит более одного выражения
- Не группируй последовательность выражений внутри `line()` при помощи `line()` без необходимости
- Операции `+` и `-` требуют одинаковых размерностей матриц
- Операция `*` требует совместимости размерностей (число столбцов первой матрицы равно числу строк второй)
- Если требуется определить выражение, для которого не хватает данных, то вставь вместо него символ `#`, чтобы пользователь мог его заполнить самостоятельно

---

## 1. Базовые правила

```ebnf
<program>         ::= { <statement> }

<statement>       ::= <expression> | <assignment> | <function_def>

<expression>      ::= <binary_expr> | <unary_expr> | <primary>
<binary_expr>     ::= <expression> <binary_op> <expression>
<unary_expr>      ::= <unary_op> <expression>
<primary>         ::= <scalar> | <string> | <matrix> | <variable> | <function_call> | "(" <expression> ")"

<scalar>          ::= <number> | <boolean>
<boolean>         ::= "true" | "false"
<string>          ::= '"' { <printable_char> | <escaped_unicode> } '"'
<matrix>          ::= <vector> | <matrix_init> | <matrix_op>
<vector>          ::= <matrix_init>  /* матрица с одним столбцом или одной строкой */

<matrix_init>     ::= "mat(" <scalar> { "," <scalar> } "," <integer> "," <integer> ")"
                   /* Количество скалярных значений перед размерностями должно быть равно rows × cols */
                   | "stack(" <arguments> ")"
                   | "augment(" <arguments> ")"
                   | "transpose(" <expression> ")"

<matrix_op>       ::= "submatrix(" <expression> "," <integer> "," <integer> "," <integer> "," <integer> ")"
                   | "el(" <expression> "," <integer> [ "," <integer> ] ")"
                   | "rows(" <expression> ")"
                   | "cols(" <expression> ")"

<assignment>      ::= <variable> ":" <expression>
<function_def>    ::= <identifier> "(" <parameters> ")" ":" <expression>
<function_call>   ::= <function_name> "(" <arguments> ")"
<parameters>      ::= <identifier> { "," <identifier> }
<arguments>       ::= <expression> { "," <expression> }

<matrix_expr>     ::= <matrix_init> | <matrix_op> | <matrix_binary_op>
<matrix_binary_op> ::= <matrix_expr> <matrix_op_symbol> <matrix_expr>
<matrix_op_symbol> ::= "+" | "-" | "*" | "†"  /* матричное умножение, сложение и т.д. */

<vector_expr>     ::= "vectorize(" <expression> ")"
                   | <matrix_expr>  /* если rows=1 или cols=1 */

<sys_expr>        ::= "sys(" <expression> { "," <expression> } "," <integer> "," <integer> ")"
                   /* Количество выражений перед размерностями должно быть равно rows × cols */

<line_expr>       ::= "line(" <expression> { "," <expression> } "," <integer> "," <integer> ")"
                   /* Количество выражений перед размерностями должно быть равно rows × cols */
                   
<range_expr>      ::= "range(" <expression> "," <expression> [ "," <expression> ] ")"

<number>          ::= [ "-" ] ( <integer> | <float> )
<integer>         ::= <digit> { <digit> }
<float>           ::= [ <integer> ] "." <digit> { <digit> } [ <exponent> ]
<exponent>        ::= "*10^{" <integer> "}"
<escaped_unicode> ::= "\" <hex_digit> <hex_digit> <hex_digit> <hex_digit> "\"

<dimension>       ::= <integer>
<variable>        ::= <identifier>
<identifier>      ::= <unicode_letter> { <unicode_letter> | <digit> | "_" | "." }

<binary_op>       ::= "+" | "-" | "*" | "/" | "^" | "†" | "&" | "|" | "⨁" 
                   | "≡" | "≠" | "<" | ">" | "≤" | "≥" | "≈" | "≉"
<unary_op>        ::= "-" | "¬"
```

## 2. Типы данных в SMath Studio (явное описание)

**SMath Studio поддерживает три основных типа данных:**

- **Скаляр (<scalar>):**

    Числа (целые, дробные, с экспонентой)

    Логические значения (1, 0)
    
    `Примеры: 5, 3.14, -2*10^{3}, 1`

- **Строка (<string>):**

    Последовательность символов в двойных кавычках

    Поддерживает Unicode-символы через экранирование

    `Пример: "Привет, мир!", "α = \03B1\"`

- **Матрица (<matrix>):**

    Двумерный массив значений (включая векторы как частный случай)

    Вектор — матрица размерности N×1 (столбец) или 1×N (строка)

```
    Примеры:

    mat(1,2,3,3,1) (вектор-столбец)

    mat(1,2,3,1,3) (вектор-строка)

    mat(1,2,3,4,2,2) (матрица 2×2)
```

---

## 3. Правила преобразования типов:

- Скаляр может быть автоматически преобразован в матрицу 1×1 при необходимости

- Вектор может быть преобразован в матрицу и наоборот при выполнении операций

- Строки не преобразуются автоматически в другие типы

- **Проверка типов:**

    Функции `rows()` и `cols()` возвращают размерности матрицы

    Для проверки типа можно использовать комбинации:

        `IsString(x)` — возвращает 1, если x строка, иначе 0

        `rows(x)=1` or `cols(x)=1` — вектор

        `rows(x)>1` and `cols(x)>1` — матрица

---

## 4. Стандартные функции

```ebnf
<function_name>   ::= "diff" | "expand" | "ln" | "sh" | "ch" | "th" | "cth" 
                   | "sech" | "cosech" | "arsh" | "arch" | "arth" | "arcth" 
                   | "sign" | "arcsin" | "arccos" | "arctg" | "arcctg" 
                   | "sin" | "cos" | "tg" | "ctg" | "sec" | "cosec" 
                   | "lg" | "log" | "perc" | "sqrt" | "nthroot" | "tr" 
                   | "abs" | "det" | "rank" | "invert" | "transpose" 
                   | "arg" | "vminor" | "minor" | "alg" | "mat" | "sys" 
                   | "arcsec" | "arccosec" | "int" | "a2t" | "row" | "col" 
                   | "el" | "rows" | "cols" | "xy2pol" | "pol2xy" | "sum" 
                   | "product" | "re" | "im" | "polyroots" | "exp" | "max" 
                   | "min" | "submatrix" | "eigenvals" | "trunc" | "round" 
                   | "mod" | "identity" | "length" | "if" | "random" 
                   | "solve" | "for" | "switch" | "while" | "line" | "matrix" 
                   | "lim" | "wfile" | "rfile" | "dfile" | "range" | "gamma" 
                   | "numden" | "stack" | "diag" | "augment" | "eval" 
                   | "linterp" | "cinterp" | "ainterp" | "normi" | "norm1" 
                   | "norme" | "sort" | "rsort" | "csort" | "reverse" | "mixed"
```

## 5. Специальные конструкции

```ebnf
<matrix_expr>     ::= "mat(" <expression> { "," <expression> } "," <integer> "," <integer> ")"
<vector_expr>     ::= "vectorize(" <expression> ")"
<range_expr>      ::= "range(" <expression> [ "," <expression> [ "," <expression> ] ] ")"
<conditional>     ::= "if(" <expression> "," <expression> "," <expression> ")"
<loop>            ::= "for(" <identifier> "," <range_expr> "," <expression> ")"
                   | "while(" <expression> "," <expression> ")"
<program_block>   ::= "line(" <expression> { "," <expression> } ")"
```

## 6. Элементы палитры «Матрицы»

Ниже приведены встроенные функции SMath Studio, доступные в палитре **Матрицы**. Примеры даны с использованием плейсхолдера `#` вместо фактических аргументов.

**Определения:**

- **Определение матрицы:**

  ```
  mat(#,#,#,#,#,#,#,#,#,3,3)   // элементы + размерность (3 строки, 3 столбца)
  ```

- **Определитель матрицы:**

  ```
  det(#)
  ```

- **Транспонирование матрицы:**

  ```
  transpose(#)
  ```

- **Алгебраическое дополнение:**

  ```
  alg(#,#,#)   // матрица, строка, столбец
  ```

- **Минор:**

  ```
  minor(#,#,#) // матрица, строка, столбец
  ```

- **Векторное умножение (векторный оператор):**

  ```
  #†#
  ```

- **Векторизация:**

  ```
  vectorize(#)
  ```

- **Диапазон значений:**

  ```
  range(#,#)           // первый, последний
  range(#,#,#)         // первый, последний, второй 
  ```

- **Обращение к элементу вектора:**

  ```
  el(#,#)              // вектор, индекс
  ```

- **Обращение к элементу матрицы:**

  ```
  el(#,#,#)            // матрица, строка, столбец
  ```

**Особенности:**

- Все функции допускают как символьные, так и численные аргументы
- Порядок аргументов в функциях фиксирован и соответствует реализации в интерфейсе SMath

---

## 7. Элементы палитры «Функции»

Ниже представлены встроенные математические функции из палитры **Функции** в интерфейсе SMath Studio. Используются в аналитических и символьных вычислениях.

**Арифметика и алгебра:**

```
log(#,#)           // логарифм по основанию (аргумент, основание)
ln(#)              // натуральный логарифм
exp(#)             // экспонента
sign(#)            // знак числа
arg(#)             // аргумент комплексного числа
mixed(#,#,#)       // представление смешанного числа: целая часть, числитель, знаменатель
```

**Тригонометрия:**

```
sin(#)             // синус
cos(#)             // косинус
tan(#)             // тангенс
cot(#)             // котангенс
```

**Дифференцирование и интегрирование:**

```
diff(#,#)          // частная производная
diff(#,#,#)        // многократная производная (выражение, переменная, порядок)
int(#,#)           // неопределённый интеграл
int(#,#,#,#)       // определённый интеграл: выражение, переменная, нижний, верхний предел
```

**Суммирование и произведение:**

```
sum(#,#,#,#)       // сумма: выражение, переменная, нач, конец
product(#,#,#,#)   // произведение: выражение, переменная, нач, конец
```

**Системы выражений:**

```
sys(#,#,2,1)       // представление алгебраической системы, например, для графиков
```

**Особенности:**

- Все функции поддерживают символьные выражения
- Тип вычислений (числовой/символьный) определяется в свойствах региона документа
- Пример символьного результата:
  ```
  diff(sin(x),x) = cos(x)
  ```
- Символьные операции применимы и к пользовательским функциям, если синтаксис корректен

---

## 8. Элементы палитры «Программирование»

Ниже приведены встроенные конструкции из палитры **Программирование** SMath Studio. Используются как структурные блоки в программных выражениях.

**Условные выражения:**

```
if(#,#)            // если условие истинно, выполнить выражение
if(#,#,#)          // если условие истинно — первое выражение, иначе — второе
```

**Циклы:**

```
for(#,#,#)         // инициализация, условие, шаг
for(#,#,#,#)       // переменная: нач, условие, переменная: шаг
while(#,#)         // пока условие истинно, выполнять блок
```

**Обработка исключений:**

```
try(#,#)           // выражение, альтернатива при ошибке
```

**Группировка выражений (последовательное выполнение):**

```
line(#,#,2,1)      // блок инструкций; возвращает результат последнего шага
```

**Ключевые слова:**

```
continue           // переход к следующей итерации цикла
break              // немедленный выход из цикла
```

**Особенности:**

- Все управляющие конструкции могут быть вложенными в `line(...)`
- `if(...)`, `for(...)`, `while(...)`, `try(...)` реализованы как функции с соответствующим порядком аргументов
- `continue` и `break` применимы только внутри циклов
- `line(...)` — основа для построения программных блоков

---

## 9. Передача функций в качестве аргументов

SMath Studio поддерживает передачу **функций как аргументов** другим функциям. Это позволяет реализовывать функциональное программирование и повторно использовать определённые правила вычислений.

**Пример 1: Передача через шаблон вызова**

```
g(a,b):a+b
f(x,y,g(x#,y#)):line(sum:g(x,y),sum,2,1)
f(1,2,g(a,b)) = 3
```

- `g(a,b)` — функция сложения
- `f(x,y,g(...))` — обобщённая функция, в которую передаётся `g` с шаблоном `g(x#,y#)`
- Символ `#` (необязателен), может использоваться, чтобы визуально отличать локальные аргументы от глобальных

**Пример 2: Указание количества параметров вместо формальных**

```
g(a,b):a+b
f(x,y,g(2)):line(sum:g(x,y),sum,2,1)
f(3,4,g(a,b)) = 7
```

- В `g(2)` - функция g с двумя параметрами
- После подстановки: `g(3,4)` → `3+4 = 7`, далее с `sum` и `line(...)` даёт итоговое значение
- Такие конструкции поддерживают символьную интерпретацию и вычисление

---
