// 2025-2026 Богданович Давид Когут Прихожденко (кдб.дійсність.укр)

взяти визначення мавка/розбирач;

// це треба ще разок переписати так як є проблеми які складно виловити
// в цілому змінити багато не вийде і не треба
// з чистого листа буде краще

простір мавка {
  простір розбирач {
    внутрішня дія визначити_розмір_символа(перший_байт: п8) -> п8 {
      якщо (перший_байт & 128) == 0 {
        вернути 1;
      }

      якщо (перший_байт & 224) == 192 {
        вернути 2;
      }

      якщо (перший_байт & 240) == 224 {
        вернути 3;
      }

      якщо (перший_байт & 248) == 240 {
        вернути 4;
      }

      вернути 0;
    }

    внутрішня дія виділити_копію_кд(М: *Машина, вхід: кд, вихід: *кд) -> логічне {
      змінна дані = виділити<п8>(М, вхід.розмір);

      змінна п: природне = 0;

      поки п < вхід.розмір {
        дані[п] = вхід.дані[п];

        п += 1;
      }

      вихід::вміст = кд { дані, вхід.розмір };

      вернути так;
    }
  }
}

простір мавка {
  простір розбирач {
    внутрішня дія перевірити_чи_початок_ідентифікатора(М: *Машина, значення_кд: кд, позиція_початку: ПозиціяЗнаки, вихід_позиції_кінця: *ПозиціяЗнаки) -> логічне;
    внутрішня дія перевірити_чи_продовження_ідентифікатора(М: *Машина, значення_кд: кд, позиція_початку: ПозиціяЗнаки, вихід_позиції_кінця: *ПозиціяЗнаки) -> логічне;
    внутрішня дія перевірити_чи_починається_з(М: *Машина, значення_кд: кд, позиція_початку: ПозиціяЗнаки, значення: кд, вихід_позиції_кінця: *ПозиціяЗнаки) -> логічне;
    внутрішня дія перевірити_чи_починається_з_ключового_слова(М: *Машина, значення_кд: кд, позиція_початку: ПозиціяЗнаки, значення: кд, вихід_позиції_кінця: *ПозиціяЗнаки, вихід_це_ідентифікатор: *логічне) -> логічне;
    внутрішня дія перевірити_чи_число(М: *Машина, значення_кд: кд, позиція_початку: ПозиціяЗнаки, вихід_позиції_кінця: *ПозиціяЗнаки, вихід_має_крапку: *логічне) -> логічне;
    внутрішня дія перевірити_чи_має_ідентифікатор_за_позицією_початку(М: *Машина, значення_кд: кд, позиція_початку: ПозиціяЗнаки, вихід_позиції_кінця: *ПозиціяЗнаки) -> логічне;

    внутрішня дія перевірити_чи_початок_ідентифікатора(М: *Машина, значення_кд: кд, позиція_початку: ПозиціяЗнаки, вихід_позиції_кінця: *ПозиціяЗнаки) -> логічне {
      якщо позиція_початку.позиція_в_тексті >= значення_кд.розмір {
        вернути ні;
      }
      якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "а", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "б", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "в", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "г", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "д", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "е", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "є", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "ж", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "з", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "и", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "і", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "ї", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "й", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "к", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "л", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "м", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "н", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "о", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "п", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "р", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "с", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "т", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "у", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "ф", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "х", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "ц", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "ч", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "ш", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "щ", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "ь", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "ю", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "я", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "ґ", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "А", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Б", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "В", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Г", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Д", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Е", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Є", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Ж", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "З", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "И", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "І", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Ї", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Й", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "К", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Л", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "М", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Н", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "О", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "П", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Р", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "С", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Т", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "У", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Ф", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Х", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Ц", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Ч", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Ш", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Щ", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Ь", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Ю", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Я", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Ґ", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "_", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "ʼ", вихід_позиції_кінця) {
      } інакше {
        вернути ні;
      }
      вернути так;
    }

    внутрішня дія перевірити_чи_продовження_ідентифікатора(М: *Машина, значення_кд: кд, позиція_початку: ПозиціяЗнаки, вихід_позиції_кінця: *ПозиціяЗнаки) -> логічне {
      якщо позиція_початку.позиція_в_тексті >= значення_кд.розмір {
        вернути ні;
      }
      якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "а", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "б", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "в", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "г", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "д", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "е", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "є", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "ж", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "з", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "и", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "і", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "ї", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "й", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "к", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "л", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "м", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "н", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "о", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "п", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "р", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "с", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "т", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "у", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "ф", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "х", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "ц", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "ч", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "ш", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "щ", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "ь", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "ю", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "я", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "ґ", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "А", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Б", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "В", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Г", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Д", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Е", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Є", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Ж", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "З", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "И", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "І", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Ї", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Й", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "К", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Л", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "М", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Н", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "О", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "П", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Р", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "С", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Т", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "У", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Ф", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Х", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Ц", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Ч", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Ш", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Щ", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Ь", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Ю", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Я", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "Ґ", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "_", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "ʼ", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "0", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "1", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "2", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "3", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "4", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "5", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "6", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "7", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "8", вихід_позиції_кінця) {
      } інакше якщо перевірити_чи_починається_з(М, значення_кд, позиція_початку, "9", вихід_позиції_кінця) {
      } інакше {
        вернути ні;
      }
      вернути так;
    }

    внутрішня дія перевірити_чи_починається_з(М: *Машина, значення_кд: кд, позиція_початку: ПозиціяЗнаки, значення: кд, вихід_позиції_кінця: *ПозиціяЗнаки) -> логічне {
      якщо позиція_початку.позиція_в_тексті >= значення_кд.розмір {
        вернути ні;
      }
      вихід_позиції_кінця::вміст = позиція_початку;
      змінна п: природне = 0;
      поки п < значення.розмір {
        змінна розмір_символа = визначити_розмір_символа(значення.дані[п]);
        якщо розмір_символа == 1 {
          якщо (позиція_початку.позиція_в_тексті + п) >= значення_кд.розмір {
            вернути ні;
          }
          якщо значення_кд.дані[позиція_початку.позиція_в_тексті + п] != значення.дані[п] {
            вернути ні;
          }
          якщо значення.дані[п] == КД_РОЗРИВ {
            вихід_позиції_кінця.позиція_в_тексті = позиція_початку.позиція_в_тексті + п;
            вихід_позиції_кінця.рядок += 1;
          } інакше {
            вихід_позиції_кінця.позиція_в_тексті = позиція_початку.позиція_в_тексті + п;
            вихід_позиції_кінця.рядок = позиція_початку.рядок;
          }
          п += 1;
        } інакше якщо розмір_символа == 2 {
          якщо (позиція_початку.позиція_в_тексті + п + 1) >= значення_кд.розмір {
            вернути ні;
          }
          якщо значення_кд.дані[позиція_початку.позиція_в_тексті + п] != значення.дані[п] {
            вернути ні;
          }
          якщо значення_кд.дані[позиція_початку.позиція_в_тексті + п + 1] != значення.дані[п + 1] {
            вернути ні;
          }
          вихід_позиції_кінця.позиція_в_тексті = позиція_початку.позиція_в_тексті + п + 1;
          вихід_позиції_кінця.рядок = позиція_початку.рядок;
          п += 2;
        } інакше якщо розмір_символа == 3 {
          якщо (позиція_початку.позиція_в_тексті + п + 1 + 1) >= значення_кд.розмір {
            вернути ні;
          }
          якщо значення_кд.дані[позиція_початку.позиція_в_тексті + п] != значення.дані[п] {
            вернути ні;
          }
          якщо значення_кд.дані[позиція_початку.позиція_в_тексті + п + 1] != значення.дані[п + 1] {
            вернути ні;
          }
          якщо значення_кд.дані[позиція_початку.позиція_в_тексті + п + 1 + 1] != значення.дані[п + 1 + 1] {
            вернути ні;
          }
          вихід_позиції_кінця.позиція_в_тексті = позиція_початку.позиція_в_тексті + п + 1 + 1;
          вихід_позиції_кінця.рядок = позиція_початку.рядок;
          п += 3;
        } інакше якщо розмір_символа == 4 {
          якщо (позиція_початку.позиція_в_тексті + п + 1 + 1 + 1) >= значення_кд.розмір {
            вернути ні;
          }
          якщо значення_кд.дані[позиція_початку.позиція_в_тексті + п] != значення.дані[п] {
            вернути ні;
          }
          якщо значення_кд.дані[позиція_початку.позиція_в_тексті + п + 1] != значення.дані[п + 1] {
            вернути ні;
          }
          якщо значення_кд.дані[позиція_початку.позиція_в_тексті + п + 1 + 1] != значення.дані[п + 1 + 1] {
            вернути ні;
          }
          якщо значення_кд.дані[позиція_початку.позиція_в_тексті + п + 1 + 1 + 1] != значення.дані[п + 1 + 1 + 1] {
            вернути ні;
          }
          вихід_позиції_кінця.позиція_в_тексті = позиція_початку.позиція_в_тексті + п + 1 + 1 + 1;
          вихід_позиції_кінця.рядок = позиція_початку.рядок;
          п += 4;
        } інакше {
          вернути ні;
        }
      }
      вернути так;
    }

    внутрішня дія перевірити_чи_починається_з_ключового_слова(М: *Машина, значення_кд: кд, позиція_початку: ПозиціяЗнаки, значення: кд, вихід_позиції_кінця: *ПозиціяЗнаки, вихід_це_ідентифікатор: *логічне) -> логічне {
      якщо позиція_початку.позиція_в_тексті >= значення_кд.розмір {
        вернути ні;
      }
      вихід_позиції_кінця::вміст = позиція_початку;
      змінна п: природне = 0;
      поки п < значення.розмір {
        змінна розмір_символа = визначити_розмір_символа(значення.дані[п]);
        якщо розмір_символа == 1 {
          якщо (позиція_початку.позиція_в_тексті + п) >= значення_кд.розмір {
            вернути ні;
          }
          якщо значення_кд.дані[позиція_початку.позиція_в_тексті + п] != значення.дані[п] {
            вернути ні;
          }
          вихід_позиції_кінця.позиція_в_тексті = позиція_початку.позиція_в_тексті + п;
          вихід_позиції_кінця.рядок = позиція_початку.рядок;
          п += 1;
        } інакше якщо розмір_символа == 2 {
          якщо (позиція_початку.позиція_в_тексті + п + 1) >= значення_кд.розмір {
            вернути ні;
          }
          якщо значення_кд.дані[позиція_початку.позиція_в_тексті + п] != значення.дані[п] {
            вернути ні;
          }
          якщо значення_кд.дані[позиція_початку.позиція_в_тексті + п + 1] != значення.дані[п + 1] {
            вернути ні;
          }
          вихід_позиції_кінця.позиція_в_тексті = позиція_початку.позиція_в_тексті + п + 1;
          вихід_позиції_кінця.рядок = позиція_початку.рядок;
          п += 2;
        } інакше якщо розмір_символа == 3 {
          якщо (позиція_початку.позиція_в_тексті + п + 1 + 1) >= значення_кд.розмір {
            вернути ні;
          }
          якщо значення_кд.дані[позиція_початку.позиція_в_тексті + п] != значення.дані[п] {
            вернути ні;
          }
          якщо значення_кд.дані[позиція_початку.позиція_в_тексті + п + 1] != значення.дані[п + 1] {
            вернути ні;
          }
          якщо значення_кд.дані[позиція_початку.позиція_в_тексті + п + 1 + 1] != значення.дані[п + 1 + 1] {
            вернути ні;
          }
          вихід_позиції_кінця.позиція_в_тексті = позиція_початку.позиція_в_тексті + п + 1 + 1;
          вихід_позиції_кінця.рядок = позиція_початку.рядок;
          п += 3;
        } інакше якщо розмір_символа == 4 {
          якщо (позиція_початку.позиція_в_тексті + п + 1 + 1 + 1) >= значення_кд.розмір {
            вернути ні;
          }
          якщо значення_кд.дані[позиція_початку.позиція_в_тексті + п] != значення.дані[п] {
            вернути ні;
          }
          якщо значення_кд.дані[позиція_початку.позиція_в_тексті + п + 1] != значення.дані[п + 1] {
            вернути ні;
          }
          якщо значення_кд.дані[позиція_початку.позиція_в_тексті + п + 1 + 1] != значення.дані[п + 1 + 1] {
            вернути ні;
          }
          якщо значення_кд.дані[позиція_початку.позиція_в_тексті + п + 1 + 1 + 1] != значення.дані[п + 1 + 1 + 1] {
            вернути ні;
          }
          вихід_позиції_кінця.позиція_в_тексті = позиція_початку.позиція_в_тексті + п + 1 + 1 + 1;
          вихід_позиції_кінця.рядок = позиція_початку.рядок;
          п += 4;
        } інакше {
          вернути ні;
        }
      }
      якщо (позиція_початку.позиція_в_тексті + п) >= значення_кд.розмір {
        вернути так;
      }
      змінна пкп = ПозиціяЗнаки { 0, 0, 0 };
      якщо перевірити_чи_продовження_ідентифікатора(М, значення_кд, ПозиціяЗнаки { позиція_початку.позиція_в_тексті + п, вихід_позиції_кінця.рядок, вихід_позиції_кінця.стовпець }, пкп::адреса) {
        вихід_це_ідентифікатор::вміст = так;
        вернути ні;
      }
      вернути так;
    }

    внутрішня дія перевірити_чи_число(М: *Машина, значення_кд: кд, позиція_початку: ПозиціяЗнаки, вихід_позиції_кінця: *ПозиціяЗнаки, вихід_має_крапку: *логічне) -> логічне {
      змінна має_крапку: логічне = ні;
      змінна має_символ_після_крапки: логічне = ні;
      змінна п = позиція_початку;

      якщо п.позиція_в_тексті >= значення_кд.розмір {
        вернути ні;
      }

      якщо значення_кд.дані[п.позиція_в_тексті] == КД_0 {
        п.позиція_в_тексті += 1;
        якщо п.позиція_в_тексті >= значення_кд.розмір {
          п.позиція_в_тексті -= 1;
          вихід_позиції_кінця::вміст = п;
          вихід_має_крапку::вміст = має_крапку;
          вернути так;
        }
      } інакше якщо значення_кд.дані[п.позиція_в_тексті] == КД_1 {
        п.позиція_в_тексті += 1;
      } інакше якщо значення_кд.дані[п.позиція_в_тексті] == КД_2 {
        п.позиція_в_тексті += 1;
      } інакше якщо значення_кд.дані[п.позиція_в_тексті] == КД_3 {
        п.позиція_в_тексті += 1;
      } інакше якщо значення_кд.дані[п.позиція_в_тексті] == КД_4 {
        п.позиція_в_тексті += 1;
      } інакше якщо значення_кд.дані[п.позиція_в_тексті] == КД_5 {
        п.позиція_в_тексті += 1;
      } інакше якщо значення_кд.дані[п.позиція_в_тексті] == КД_6 {
        п.позиція_в_тексті += 1;
      } інакше якщо значення_кд.дані[п.позиція_в_тексті] == КД_7 {
        п.позиція_в_тексті += 1;
      } інакше якщо значення_кд.дані[п.позиція_в_тексті] == КД_8 {
        п.позиція_в_тексті += 1;
      } інакше якщо значення_кд.дані[п.позиція_в_тексті] == КД_9 {
        п.позиція_в_тексті += 1;
      } інакше {
        вернути ні;
      }

    перевірка_продовження_числа:
      якщо п.позиція_в_тексті >= значення_кд.розмір {
        якщо має_крапку {
          якщо має_символ_після_крапки {
            п.позиція_в_тексті -= 1;
            вихід_позиції_кінця::вміст = п;
            вихід_має_крапку::вміст = має_крапку;
            вернути так;
          } інакше {
            вернути ні;
          }
        }
        п.позиція_в_тексті -= 1;
        вихід_позиції_кінця::вміст = п;
        вихід_має_крапку::вміст = має_крапку;
        вернути так;
      }

      якщо значення_кд.дані[п.позиція_в_тексті] == КД_КРАПКА {
        якщо має_крапку {
          якщо має_символ_після_крапки {
            п.позиція_в_тексті -= 1;
            вихід_позиції_кінця::вміст = п;
            вихід_має_крапку::вміст = має_крапку;
            вернути так;
          } інакше {
            п.позиція_в_тексті -= 2;
            вихід_позиції_кінця::вміст = п;
            вихід_має_крапку::вміст = ні  ;
            вернути так;
          }
        } інакше {
          має_крапку = так;
          п.позиція_в_тексті += 1;
          стрибнути перевірка_продовження_числа;
        }
      }

      якщо значення_кд.дані[п.позиція_в_тексті] == КД_0 {
        якщо має_крапку { має_символ_після_крапки = так; }
        п.позиція_в_тексті += 1;
        стрибнути перевірка_продовження_числа;
      }
      якщо значення_кд.дані[п.позиція_в_тексті] == КД_1 {
        якщо має_крапку { має_символ_після_крапки = так; }
        п.позиція_в_тексті += 1;
        стрибнути перевірка_продовження_числа;
      }
      якщо значення_кд.дані[п.позиція_в_тексті] == КД_2 {
        якщо має_крапку { має_символ_після_крапки = так; }
        п.позиція_в_тексті += 1;
        стрибнути перевірка_продовження_числа;
      }
      якщо значення_кд.дані[п.позиція_в_тексті] == КД_3 {
        якщо має_крапку { має_символ_після_крапки = так; }
        п.позиція_в_тексті += 1;
        стрибнути перевірка_продовження_числа;
      }
      якщо значення_кд.дані[п.позиція_в_тексті] == КД_4 {
        якщо має_крапку { має_символ_після_крапки = так; }
        п.позиція_в_тексті += 1;
        стрибнути перевірка_продовження_числа;
      }
      якщо значення_кд.дані[п.позиція_в_тексті] == КД_5 {
        якщо має_крапку { має_символ_після_крапки = так; }
        п.позиція_в_тексті += 1;
        стрибнути перевірка_продовження_числа;
      }
      якщо значення_кд.дані[п.позиція_в_тексті] == КД_6 {
        якщо має_крапку { має_символ_після_крапки = так; }
        п.позиція_в_тексті += 1;
        стрибнути перевірка_продовження_числа;
      }
      якщо значення_кд.дані[п.позиція_в_тексті] == КД_7 {
        якщо має_крапку { має_символ_після_крапки = так; }
        п.позиція_в_тексті += 1;
        стрибнути перевірка_продовження_числа;
      }
      якщо значення_кд.дані[п.позиція_в_тексті] == КД_8 {
        якщо має_крапку { має_символ_після_крапки = так; }
        п.позиція_в_тексті += 1;
        стрибнути перевірка_продовження_числа;
      }
      якщо значення_кд.дані[п.позиція_в_тексті] == КД_9 {
        якщо має_крапку { має_символ_після_крапки = так; }
        п.позиція_в_тексті += 1;
        стрибнути перевірка_продовження_числа;
      }
      якщо значення_кд.дані[п.позиція_в_тексті] == КД_ПІДРИСКА {
        якщо має_крапку { має_символ_після_крапки = так; }
        п.позиція_в_тексті += 1;
        стрибнути перевірка_продовження_числа;
      }

      // Перевіряємо наукову нотацію (е)
      якщо значення_кд.дані[п.позиція_в_тексті] == КД_мала_буква_е { // е
        п.позиція_в_тексті += 1;

        якщо п.позиція_в_тексті >= значення_кд.розмір {
          п.позиція_в_тексті -= 1;
          якщо має_крапку {
            якщо має_символ_після_крапки {
              п.позиція_в_тексті -= 1;
              вихід_позиції_кінця::вміст = п;
              вихід_має_крапку::вміст = має_крапку;
              вернути так;
            } інакше {
              вернути ні;
            }
          }
          п.позиція_в_тексті -= 1;
          вихід_позиції_кінця::вміст = п;
          вихід_має_крапку::вміст = має_крапку;
          вернути так;
        }

        // Перевіряємо знак експоненти (+/-)
        якщо значення_кд.дані[п.позиція_в_тексті] == КД_РИСКА { // -
          п.позиція_в_тексті += 1;
        } інакше якщо значення_кд.дані[п.позиція_в_тексті] == КД_ХРЕСТИК { // +
          п.позиція_в_тексті += 1;
        }

        якщо п.позиція_в_тексті >= значення_кд.розмір {
          вернути ні;
        }

        змінна має_цифру_в_експоненті = ні;

      перевірка_експоненти:
        якщо п.позиція_в_тексті >= значення_кд.розмір {
          якщо має_цифру_в_експоненті {
            п.позиція_в_тексті -= 1;
            вихід_позиції_кінця::вміст = п;
            вихід_має_крапку::вміст = має_крапку;
            вернути так;
          } інакше {
            вернути ні;
          }
        }

        якщо значення_кд.дані[п.позиція_в_тексті] == КД_0 {
          має_цифру_в_експоненті = так;
          п.позиція_в_тексті += 1;
          стрибнути перевірка_експоненти;
        }
        якщо значення_кд.дані[п.позиція_в_тексті] == КД_1 {
          має_цифру_в_експоненті = так;
          п.позиція_в_тексті += 1;
          стрибнути перевірка_експоненти;
        }
        якщо значення_кд.дані[п.позиція_в_тексті] == КД_2 {
          має_цифру_в_експоненті = так;
          п.позиція_в_тексті += 1;
          стрибнути перевірка_експоненти;
        }
        якщо значення_кд.дані[п.позиція_в_тексті] == КД_3 {
          має_цифру_в_експоненті = так;
          п.позиція_в_тексті += 1;
          стрибнути перевірка_експоненти;
        }
        якщо значення_кд.дані[п.позиція_в_тексті] == КД_4 {
          має_цифру_в_експоненті = так;
          п.позиція_в_тексті += 1;
          стрибнути перевірка_експоненти;
        }
        якщо значення_кд.дані[п.позиція_в_тексті] == КД_5 {
          має_цифру_в_експоненті = так;
          п.позиція_в_тексті += 1;
          стрибнути перевірка_експоненти;
        }
        якщо значення_кд.дані[п.позиція_в_тексті] == КД_6 {
          має_цифру_в_експоненті = так;
          п.позиція_в_тексті += 1;
          стрибнути перевірка_експоненти;
        }
        якщо значення_кд.дані[п.позиція_в_тексті] == КД_7 {
          має_цифру_в_експоненті = так;
          п.позиція_в_тексті += 1;
          стрибнути перевірка_експоненти;
        }
        якщо значення_кд.дані[п.позиція_в_тексті] == КД_8 {
          має_цифру_в_експоненті = так;
          п.позиція_в_тексті += 1;
          стрибнути перевірка_експоненти;
        }
        якщо значення_кд.дані[п.позиція_в_тексті] == КД_9 {
          має_цифру_в_експоненті = так;
          п.позиція_в_тексті += 1;
          стрибнути перевірка_експоненти;
        }
        якщо значення_кд.дані[п.позиція_в_тексті] == КД_ПІДРИСКА {
          п.позиція_в_тексті += 1;
          стрибнути перевірка_експоненти;
        }

        якщо має_цифру_в_експоненті {
          п.позиція_в_тексті -= 1;
          вихід_позиції_кінця::вміст = п;
          вихід_має_крапку::вміст = має_крапку;
          вернути так;
        } інакше {
          вернути ні;
        }
      }

      якщо має_крапку {
        якщо має_символ_після_крапки {
          п.позиція_в_тексті -= 1;
          вихід_позиції_кінця::вміст = п;
          вихід_має_крапку::вміст = має_крапку;
          вернути так;
        } інакше {
          вернути ні;
        }
      }

      п.позиція_в_тексті -= 1;
      вихід_позиції_кінця::вміст = п;
      вихід_має_крапку::вміст = має_крапку;
      вернути так;
    }

    внутрішня дія перевірити_чи_має_ідентифікатор_за_позицією_початку(М: *Машина, значення_кд: кд, позиція_початку: ПозиціяЗнаки, вихід_позиції_кінця: *ПозиціяЗнаки) -> логічне {
      якщо позиція_початку.позиція_в_тексті >= значення_кд.розмір {
        вернути ні;
      }
      змінна п = позиція_початку;
      якщо перевірити_чи_початок_ідентифікатора(М, значення_кд, п, п::адреса) {
      } інакше {
        вихід_позиції_кінця::вміст = п;
        вернути ні;
      }
      п.позиція_в_тексті += 1;
      змінна є_продовження: логічне = так;
      поки є_продовження {
        якщо перевірити_чи_продовження_ідентифікатора(М, значення_кд, п, п::адреса) {
          п.позиція_в_тексті += 1;
        } інакше {
          вихід_позиції_кінця::вміст = п;
          є_продовження = ні;
        }
      }
      п.позиція_в_тексті -= 1;
      вихід_позиції_кінця::вміст = п;
      вернути так;
    }

    внутрішня дія розібрати_на_знаки_0(М: *Машина, значення_кд: кд, позиція_початку: ПозиціяЗнаки, до_закритої_дужки: логічне, вихід_позиції_кінця: *ПозиціяЗнаки, вихід: *Знаки, вихід_помилки: *ПомилкаРозборуНаЗнаки) -> логічне {
      змінна накопичувач_слів = зробити_накопичувач<Знак>(М, 0);

      змінна п = позиція_початку;
      змінна позиція_помилки = ПозиціяЗнаки { 0, 0, 0 };

      поки п.позиція_в_тексті < значення_кд.розмір {
        якщо значення_кд.дані[п.позиція_в_тексті] == КД_ПРОПУСК {
          стрибнути далі;
        }

        змінна позиція_кінця = ПозиціяЗнаки { 0, 1, 1 };
        змінна це_ідентифікатор: логічне = ні;

        якщо перевірити_чи_починається_з_ключового_слова(М, значення_кд, п, "кінець", позиція_кінця::адреса, це_ідентифікатор::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуКінець,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }
        якщо це_ідентифікатор {
          стрибнути перевірка_ідентифікатора;
        }

        якщо перевірити_чи_починається_з_ключового_слова(М, значення_кд, п, "дія", позиція_кінця::адреса, це_ідентифікатор::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуДія,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }
        якщо це_ідентифікатор {
          стрибнути перевірка_ідентифікатора;
        }

        якщо перевірити_чи_починається_з_ключового_слова(М, значення_кд, п, "структура", позиція_кінця::адреса, це_ідентифікатор::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуКлас,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }
        якщо це_ідентифікатор {
          стрибнути перевірка_ідентифікатора;
        }

        якщо перевірити_чи_починається_з_ключового_слова(М, значення_кд, п, "клас", позиція_кінця::адреса, це_ідентифікатор::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуКлас,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }
        якщо це_ідентифікатор {
          стрибнути перевірка_ідентифікатора;
        }

        якщо перевірити_чи_починається_з_ключового_слова(М, значення_кд, п, "перебрати", позиція_кінця::адреса, це_ідентифікатор::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуПеребрати,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }
        якщо це_ідентифікатор {
          стрибнути перевірка_ідентифікатора;
        }

        якщо перевірити_чи_починається_з_ключового_слова(М, значення_кд, п, "передати", позиція_кінця::адреса, це_ідентифікатор::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуПередати,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }
        якщо це_ідентифікатор {
          стрибнути перевірка_ідентифікатора;
        }

        якщо перевірити_чи_починається_з_ключового_слова(М, значення_кд, п, "перестрибнути", позиція_кінця::адреса, це_ідентифікатор::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуПерестрибнути,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }
        якщо це_ідентифікатор {
          стрибнути перевірка_ідентифікатора;
        }

        якщо перевірити_чи_починається_з_ключового_слова(М, значення_кд, п, "перервати", позиція_кінця::адреса, це_ідентифікатор::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуПерервати,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }
        якщо це_ідентифікатор {
          стрибнути перевірка_ідентифікатора;
        }

        якщо перевірити_чи_починається_з_ключового_слова(М, значення_кд, п, "як", позиція_кінця::адреса, це_ідентифікатор::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуЯк,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }

        якщо перевірити_чи_починається_з_ключового_слова(М, значення_кд, п, "якщо", позиція_кінця::адреса, це_ідентифікатор::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуЯкщо,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }
        якщо це_ідентифікатор {
          стрибнути перевірка_ідентифікатора;
        }

        якщо перевірити_чи_починається_з_ключового_слова(М, значення_кд, п, "чекати", позиція_кінця::адреса, це_ідентифікатор::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуЧекати,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }
        якщо це_ідентифікатор {
          стрибнути перевірка_ідентифікатора;
        }

        якщо перевірити_чи_починається_з_ключового_слова(М, значення_кд, п, "взяти", позиція_кінця::адреса, це_ідентифікатор::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуВзяти,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }
        якщо це_ідентифікатор {
          стрибнути перевірка_ідентифікатора;
        }

        якщо перевірити_чи_починається_з_ключового_слова(М, значення_кд, п, "власна", позиція_кінця::адреса, це_ідентифікатор::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуВласна,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }
        якщо це_ідентифікатор {
          стрибнути перевірка_ідентифікатора;
        }

        якщо перевірити_чи_починається_з_ключового_слова(М, значення_кд, п, "дати", позиція_кінця::адреса, це_ідентифікатор::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуДати,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }
        якщо це_ідентифікатор {
          стрибнути перевірка_ідентифікатора;
        }

        якщо перевірити_чи_починається_з_ключового_слова(М, значення_кд, п, "є", позиція_кінця::адреса, це_ідентифікатор::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуЄ,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }
        якщо це_ідентифікатор {
          стрибнути перевірка_ідентифікатора;
        }

        якщо перевірити_чи_починається_з_ключового_слова(М, значення_кд, п, "вернути", позиція_кінця::адреса, це_ідентифікатор::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуВернути,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }
        якщо це_ідентифікатор {
          стрибнути перевірка_ідентифікатора;
        }

        якщо перевірити_чи_починається_з_ключового_слова(М, значення_кд, п, "тривала", позиція_кінця::адреса, це_ідентифікатор::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуТривала,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }
        якщо це_ідентифікатор {
          стрибнути перевірка_ідентифікатора;
        }

        якщо перевірити_чи_починається_з_ключового_слова(М, значення_кд, п, "і", позиція_кінця::адреса, це_ідентифікатор::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуІ,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }

        якщо перевірити_чи_починається_з_ключового_слова(М, значення_кд, п, "інакше", позиція_кінця::адреса, це_ідентифікатор::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуІнакше,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }
        якщо це_ідентифікатор {
          стрибнути перевірка_ідентифікатора;
        }

        якщо перевірити_чи_починається_з_ключового_слова(М, значення_кд, п, "або", позиція_кінця::адреса, це_ідентифікатор::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуАбо,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }
        якщо це_ідентифікатор {
          стрибнути перевірка_ідентифікатора;
        }

        якщо перевірити_чи_починається_з_ключового_слова(М, значення_кд, п, "спробувати", позиція_кінця::адреса, це_ідентифікатор::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуСпробувати,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }
        якщо це_ідентифікатор {
          стрибнути перевірка_ідентифікатора;
        }

        якщо перевірити_чи_починається_з_ключового_слова(М, значення_кд, п, "зловити", позиція_кінця::адреса, це_ідентифікатор::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуЗловити,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }
        якщо це_ідентифікатор {
          стрибнути перевірка_ідентифікатора;
        }

        якщо перевірити_чи_починається_з_ключового_слова(М, значення_кд, п, "впасти", позиція_кінця::адреса, це_ідентифікатор::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуВпасти,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }
        якщо це_ідентифікатор {
          стрибнути перевірка_ідентифікатора;
        }

        якщо перевірити_чи_починається_з_ключового_слова(М, значення_кд, п, "поки", позиція_кінця::адреса, це_ідентифікатор::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуПоки,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }
        якщо це_ідентифікатор {
          стрибнути перевірка_ідентифікатора;
        }

        якщо перевірити_чи_починається_з_ключового_слова(М, значення_кд, п, "модуль", позиція_кінця::адреса, це_ідентифікатор::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуМодуль,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }
        якщо це_ідентифікатор {
          стрибнути перевірка_ідентифікатора;
        }

        якщо перевірити_чи_починається_з_ключового_слова(М, значення_кд, п, "рівно", позиція_кінця::адреса, це_ідентифікатор::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуРівно,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }
        якщо це_ідентифікатор {
          стрибнути перевірка_ідентифікатора;
        }

        якщо перевірити_чи_починається_з_ключового_слова(М, значення_кд, п, "більше", позиція_кінця::адреса, це_ідентифікатор::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуБільше,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }
        якщо це_ідентифікатор {
          стрибнути перевірка_ідентифікатора;
        }

        якщо перевірити_чи_починається_з_ключового_слова(М, значення_кд, п, "менше", позиція_кінця::адреса, це_ідентифікатор::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуМенше,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }
        якщо це_ідентифікатор {
          стрибнути перевірка_ідентифікатора;
        }

        якщо перевірити_чи_починається_з_ключового_слова(М, значення_кд, п, "не", позиція_кінця::адреса, це_ідентифікатор::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуНе,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }
        якщо це_ідентифікатор {
          стрибнути перевірка_ідентифікатора;
        }

        якщо перевірити_чи_починається_з(М, значення_кд, п, "=", позиція_кінця::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуСимволРівно,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }

        якщо перевірити_чи_починається_з(М, значення_кд, п, ">", позиція_кінця::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуСимволБільше,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }

        якщо перевірити_чи_починається_з(М, значення_кд, п, "<", позиція_кінця::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуСимволМенше,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }

        якщо перевірити_чи_починається_з(М, значення_кд, п, ".", позиція_кінця::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуСимволКрапка,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }

        якщо перевірити_чи_починається_з(М, значення_кд, п, "+", позиція_кінця::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуСимволПлюс,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }

        якщо перевірити_чи_починається_з(М, значення_кд, п, "-", позиція_кінця::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуСимволМінус,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }

        якщо перевірити_чи_починається_з(М, значення_кд, п, "*", позиція_кінця::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуСимволПомножити,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }

        якщо перевірити_чи_починається_з(М, значення_кд, п, "/", позиція_кінця::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуСимволПоділити,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }

        якщо перевірити_чи_починається_з(М, значення_кд, п, "^", позиція_кінця::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуСимволВиключнеАбо,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }

        якщо перевірити_чи_починається_з(М, значення_кд, п, "%", позиція_кінця::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуСимволЗалишку,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }

        якщо перевірити_чи_починається_з(М, значення_кд, п, "&", позиція_кінця::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуСимволІ,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }

        якщо перевірити_чи_починається_з(М, значення_кд, п, "|", позиція_кінця::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуСимволАбо,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }

        якщо перевірити_чи_починається_з(М, значення_кд, п, "(", позиція_кінця::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуСимволВідкритаДужка,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }

        якщо перевірити_чи_починається_з(М, значення_кд, п, ")", позиція_кінця::адреса) {
          якщо до_закритої_дужки {
            вихід::вміст = Знаки {
              накопичувач_слів.розмір,
              накопичувач_слів.дані
            };
            вихід_позиції_кінця::вміст = позиція_кінця;
            вернути так;
          }
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуСимволЗакритаДужка,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }

        якщо перевірити_чи_починається_з(М, значення_кд, п, "[", позиція_кінця::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуСимволКвадратнаВідкритаДужка,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }

        якщо перевірити_чи_починається_з(М, значення_кд, п, "]", позиція_кінця::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуСимволКвадратнаЗакритаДужка,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }

        якщо перевірити_чи_починається_з(М, значення_кд, п, "{", позиція_кінця::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуСимволФігурнаВідкритаДужка,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }

        якщо перевірити_чи_починається_з(М, значення_кд, п, "}", позиція_кінця::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуСимволФігурнаЗакритаДужка,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }

        якщо перевірити_чи_починається_з(М, значення_кд, п, "?", позиція_кінця::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуСимволЗнакПитання,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }

        якщо перевірити_чи_починається_з(М, значення_кд, п, ":", позиція_кінця::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуСимволДвокрапка,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }

        якщо перевірити_чи_починається_з(М, значення_кд, п, "~", позиція_кінця::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуСимволДвійковеНе,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }

        якщо перевірити_чи_починається_з(М, значення_кд, п, "!", позиція_кінця::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуСимволЗнакОклику,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }

        якщо перевірити_чи_починається_з(М, значення_кд, п, ",", позиція_кінця::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуСимволКома,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }

        якщо перевірити_чи_починається_з(М, значення_кд, п, "", позиція_кінця::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуСимволМіжряд,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }

        якщо перевірити_чи_починається_з(М, значення_кд, п, "'", позиція_кінця::адреса) {
          змінна пп = позиція_кінця;
          пп.позиція_в_тексті += 1;
          змінна закінчено: логічне = ні;
          поки пп.позиція_в_тексті < значення_кд.розмір {
            якщо значення_кд.дані[пп.позиція_в_тексті] == КД_ОБЕРНЕНА_ПОХИЛА {
              пп.позиція_в_тексті += 1;
              стрибнути далі3;
            }
            якщо значення_кд.дані[пп.позиція_в_тексті] == КД_ЛАПКА {
              закінчено = так;
              стрибнути закінчити_перебір_символів;
            }
            якщо значення_кд.дані[пп.позиція_в_тексті] == КД_РОЗРИВ {
              пп.рядок += 1;
              стрибнути закінчити_перебір_символів;
            }
            далі3:
            пп.позиція_в_тексті += 1;
          }
          закінчити_перебір_символів:
          якщо закінчено {
            накопичувач_слів.покласти(М, Знак {
              вид = ВидЗнакуСимвол,
              позиція_початку = п,
              позиція_кінця = пп
            });
            п = пп;
            стрибнути далі;
          }
          стрибнути вийти_з_помилкою;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }

        якщо перевірити_чи_починається_з(М, значення_кд, п, "\"\"\"", позиція_кінця::адреса) {
          змінна пп = позиція_кінця;
          пп.позиція_в_тексті += 1;
          змінна закінчено = ні;
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуПочатокЗбитогоТексту,
            позиція_початку = п,
            позиція_кінця = пп
          });
          п = пп;
          п.позиція_в_тексті -= 1;
          поки пп.позиція_в_тексті < значення_кд.розмір {
            якщо значення_кд.дані[пп.позиція_в_тексті] == КД_ОБЕРНЕНА_ПОХИЛА {
              пп.позиція_в_тексті += 1;
              стрибнути багаторяд_далі1;
            }
            якщо значення_кд.дані[пп.позиція_в_тексті] == КД_ВІДСОТОК {
              пп.позиція_в_тексті += 1;
              якщо значення_кд.дані[пп.позиція_в_тексті] == КД_ВІДКРИТА_ДУЖКА {
                змінна пч = п;
                п.позиція_в_тексті += 1;
                змінна ппч = пп;
                ппч.позиція_в_тексті -= 1;
                накопичувач_слів.покласти(М, Знак {
                  вид = ВидЗнакуЧастинаЗбитогоТексту,
                  позиція_початку = пч,
                  позиція_кінця = ппч
                });
                накопичувач_слів.покласти(М, Знак {
                  вид = ВидЗнакуРоздільникЗбитогоТексту,
                  позиція_початку = п,
                  позиція_кінця = пп
                });
                п = пп;
                пп.позиція_в_тексті += 1;
                змінна знаки = Знаки { 0, пусто };
                змінна помилка_розбору_на_знаки = ПомилкаРозборуНаЗнаки { ... };
                якщо розібрати_на_знаки_0(М, значення_кд, пп, так, пп::адреса, знаки::адреса, помилка_розбору_на_знаки::адреса) {
                  змінна ппп: природне = 0;
                  поки ппп < знаки.розмір {
                    накопичувач_слів.покласти(М, знаки.дані[ппп]);
                    ппп += 1;
                  }
                  звільнити(М, знаки.дані);
                  накопичувач_слів.покласти(М, Знак {
                    вид = ВидЗнакуРоздільникЗбитогоТексту,
                    позиція_початку = п,
                    позиція_кінця = пп
                  });
                  п = пп;
                  стрибнути багаторяд_далі1;
                } інакше {
                  вихід_помилки::вміст = помилка_розбору_на_знаки;
                  вернути ні;
                }
              } інакше {
                пп.позиція_в_тексті -= 1;
              }
            }
            якщо значення_кд.дані[пп.позиція_в_тексті] == КД_ОБЕРНЕНА_ПОХИЛА {
              стрибнути багаторяд_далі1;
            }
            якщо перевірити_чи_починається_з(М, значення_кд, пп, "\"\"\"", пп::адреса) {
              закінчено = так;
              стрибнути закінчити_перебір_багаторядкового_тексту;
            }
            багаторяд_далі1:
            пп.позиція_в_тексті += 1;
          }
          закінчити_перебір_багаторядкового_тексту:
          якщо закінчено {
            змінна пч = п;
            змінна ппч = пп;
            ппч.позиція_в_тексті -= 2;
            накопичувач_слів.покласти(М, Знак {
              вид = ВидЗнакуЧастинаЗбитогоТексту,
              позиція_початку = пч,
              позиція_кінця = ппч
            });
            п = пп;
            накопичувач_слів.покласти(М, Знак {
              вид = ВидЗнакуКінецьЗбитогоТексту,
              позиція_початку = п,
              позиція_кінця = пп
            });
            стрибнути далі;
          }
          стрибнути вийти_з_помилкою;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }

        якщо перевірити_чи_починається_з(М, значення_кд, п, "\"", позиція_кінця::адреса) {
          змінна пп = позиція_кінця;
          пп.позиція_в_тексті += 1;
          змінна закінчено = ні;
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуПочатокЗбитогоТексту,
            позиція_початку = п,
            позиція_кінця = пп
          });
          поки пп.позиція_в_тексті < значення_кд.розмір {
            якщо значення_кд.дані[пп.позиція_в_тексті] == КД_ОБЕРНЕНА_ПОХИЛА {
              пп.позиція_в_тексті += 1;
              стрибнути далі1;
            }
            якщо значення_кд.дані[пп.позиція_в_тексті] == КД_ВІДСОТОК {
              пп.позиція_в_тексті += 1;
              якщо значення_кд.дані[пп.позиція_в_тексті] == КД_ВІДКРИТА_ДУЖКА {
                змінна пч = п;
                п.позиція_в_тексті += 1;
                змінна ппч = пп;
                ппч.позиція_в_тексті -= 1;
                накопичувач_слів.покласти(М, Знак {
                  вид = ВидЗнакуЧастинаЗбитогоТексту,
                  позиція_початку = пч,
                  позиція_кінця = ппч
                });
                накопичувач_слів.покласти(М, Знак {
                  вид = ВидЗнакуРоздільникЗбитогоТексту,
                  позиція_початку = п,
                  позиція_кінця = пп
                });
                п = пп;
                пп.позиція_в_тексті += 1;
                змінна знаки = Знаки { 0, пусто };
                змінна помилка_розбору_на_знаки = ПомилкаРозборуНаЗнаки { ... };
                якщо розібрати_на_знаки_0(М, значення_кд, пп, так, пп::адреса, знаки::адреса, помилка_розбору_на_знаки::адреса) {
                  змінна ппп: природне = 0;
                  поки ппп < знаки.розмір {
                    накопичувач_слів.покласти(М, знаки.дані[ппп]);
                    ппп += 1;
                  }
                  звільнити(М, знаки.дані);
                  накопичувач_слів.покласти(М, Знак {
                    вид = ВидЗнакуРоздільникЗбитогоТексту,
                    позиція_початку = п,
                    позиція_кінця = пп
                  });
                  п = пп;
                  стрибнути далі1;
                } інакше {
                  вихід_помилки::вміст = помилка_розбору_на_знаки;
                  вернути ні;
                }
              } інакше {
                пп.позиція_в_тексті -= 1;
              }
            }
            якщо значення_кд.дані[пп.позиція_в_тексті] == КД_ДВОЛАПКА {
              закінчено = так;
              стрибнути закінчити_перебір_тексту;
            }
            якщо значення_кд.дані[пп.позиція_в_тексті] == КД_РОЗРИВ {
              пп.рядок += 1;
              стрибнути закінчити_перебір_тексту;
            }
            далі1:
            пп.позиція_в_тексті += 1;
          }
          закінчити_перебір_тексту:
          якщо закінчено {
            змінна пч = п;
            п.позиція_в_тексті += 1;
            змінна ппч = пп;
            накопичувач_слів.покласти(М, Знак {
              вид = ВидЗнакуЧастинаЗбитогоТексту,
              позиція_початку = пч,
              позиція_кінця = ппч
            });
            п = пп;
            накопичувач_слів.покласти(М, Знак {
              вид = ВидЗнакуКінецьЗбитогоТексту,
              позиція_початку = п,
              позиція_кінця = пп
            });
            стрибнути далі;
          }
          стрибнути вийти_з_помилкою;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }

        якщо перевірити_чи_починається_з(М, значення_кд, п, ";;", позиція_кінця::адреса) {
          змінна пп = позиція_кінця;
          пп.позиція_в_тексті += 1;
          змінна закінчено: логічне = ні;
          поки пп.позиція_в_тексті < значення_кд.розмір {
            якщо значення_кд.дані[пп.позиція_в_тексті] == КД_РОЗРИВ {
              пп.рядок += 1;
              закінчено = так;
              стрибнути закінчити_перебір_коментаря2;
            }
            пп.позиція_в_тексті += 1;
          }
          закінчити_перебір_коментаря2:
  //        накопичувач_слів.покласти(М, Знак {
  //          вид = ВидЗнакуКоментар,
  //          позиція_початку = п,
  //          позиція_кінця = пп - 1
  //        });
          якщо закінчено {
            накопичувач_слів.покласти(М, Знак {
              вид = ВидЗнакуСимволМіжряд,
              позиція_початку = пп,
              позиція_кінця = пп
            });
          }
          п = пп;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }

        якщо перевірити_чи_починається_з(М, значення_кд, п, ";*", позиція_кінця::адреса) {
          змінна пп = позиція_кінця;
          пп.позиція_в_тексті += 1;
          змінна закінчено: логічне = ні;
          поки пп.позиція_в_тексті < значення_кд.розмір {
            якщо значення_кд.дані[пп.позиція_в_тексті] == КД_РОЗРИВ {
              пп.рядок += 1;
            }
            якщо перевірити_чи_починається_з(М, значення_кд, пп, "*;", пп::адреса) {
              закінчено = так;
              стрибнути закінчити_перебір_багаторядкового_коментаря2;
            }
            пп.позиція_в_тексті += 1;
          }
          закінчити_перебір_багаторядкового_коментаря2:
          якщо закінчено {
  //          накопичувач_слів.покласти(М, Знак {
  //            вид = ВидЗнакуБагаторядковийКоментар,
  //            позиція_початку = п,
  //            позиція_кінця = пп
  //          });
            п = пп;
            стрибнути далі;
          }
          стрибнути вийти_з_помилкою;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }

        змінна число_має_крапку = ні;
        якщо перевірити_чи_число(М, значення_кд, п, позиція_кінця::адреса, число_має_крапку::адреса) {
          якщо число_має_крапку {
            накопичувач_слів.покласти(М, Знак {
              вид = ВидЗнакуЧисло,
              позиція_початку = п,
              позиція_кінця = позиція_кінця
            });
          } інакше {
            накопичувач_слів.покласти(М, Знак {
              вид = ВидЗнакуЧисло,
              позиція_початку = п,
              позиція_кінця = позиція_кінця
            });
          }
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }

    перевірка_ідентифікатора:
        якщо перевірити_чи_має_ідентифікатор_за_позицією_початку(М, значення_кд, п, позиція_кінця::адреса) {
          накопичувач_слів.покласти(М, Знак {
            вид = ВидЗнакуІдентифікатор,
            позиція_початку = п,
            позиція_кінця = позиція_кінця
          });
          п = позиція_кінця;
          стрибнути далі;
        }
        якщо позиція_кінця.позиція_в_тексті == 0 {
          позиція_кінця = п;
        }
        якщо позиція_кінця.позиція_в_тексті > позиція_помилки.позиція_в_тексті {
          позиція_помилки = позиція_кінця;
        }

        стрибнути вийти_з_помилкою;

    далі:
        п.позиція_в_тексті += 1;
      }

      накопичувач_слів.покласти(М, Знак {
        вид = ВидЗнакуКІНЕЦЬСЛІВ,
        позиція_початку = ПозиціяЗнаки { 0, 0, 0 },
        позиція_кінця = ПозиціяЗнаки { 0, 0, 0 }
      });

      вихід::вміст = Знаки {
        накопичувач_слів.розмір,
        накопичувач_слів.дані
      };
      вихід_позиції_кінця::вміст = п;
      вернути так;

    вийти_з_помилкою:
      звільнити(М, накопичувач_слів.дані);
      вихід_помилки::вміст = ПомилкаРозборуНаЗнаки {
        позиція_в_тексті = позиція_помилки.позиція_в_тексті,
        рядок = позиція_помилки.рядок,
        стовпець = позиція_помилки.стовпець
      };
      вернути ні;
    }

    дія розібрати_на_знаки(М: *Машина, значення_кд: кд, вихід: *Знаки, вихід_помилки: *ПомилкаРозборуНаЗнаки) -> логічне {
      змінна позиція_кінця = ПозиціяЗнаки { 0, 0, 0 };
      вернути розібрати_на_знаки_0(М, значення_кд, ПозиціяЗнаки { 0, 1, 1 }, ні, позиція_кінця::адреса, вихід, вихід_помилки);
    }

    дія звільнити_знаки(М: *Машина, знаки: Знаки) {
      звільнити(М, знаки.дані);
    }

    дія звільнити_помилку_розбору_на_знаки(М: *Машина, помилка: ПомилкаРозборуНаЗнаки) {
      // ...
    }

    дія отримати_помилку_розбору_на_знаки(М: *Машина, помилка: ПомилкаРозборуНаЗнаки, вихід: *кд) -> логічне {
      виділити_копію_кд(М, "Не вдалось розібрати на знаки0", вихід);
      вернути так;
    }

    дія отримати_рядок_помилки_розбору_на_знаки(М: *Машина, помилка: ПомилкаРозборуНаЗнаки) -> природне {
      вернути помилка.рядок;
    }

    дія отримати_стовпець_помилки_розбору_на_знаки(М: *Машина, помилка: ПомилкаРозборуНаЗнаки) -> природне {
      вернути помилка.стовпець;
    }

    дія отримати_значення_ідентифікатора(значення_кд: кд, знаки: Знаки, ідентифікатор: Ідентифікатор) -> кд {
      вернути отримати_значення_знаку(значення_кд, знаки, знаки.дані[ідентифікатор.позиція_знаку]);
    }

    дія отримати_значення_знаку(значення_кд: кд, знаки: Знаки, знак: Знак) -> кд {
      вернути кд {
        розмір = (знак.позиція_кінця.позиція_в_тексті - знак.позиція_початку.позиція_в_тексті) + 1,
        дані = значення_кд.дані[знак.позиція_початку.позиція_в_тексті]::адреса як *п8
      };
    }

    дія отримати_значення_тексту(значення_кд: кд, знаки: Знаки, знак: Знак) -> кд {
      змінна значення_знаку = отримати_значення_знаку(значення_кд, знаки, знак);
      вернути кд { значення_знаку.дані[1]::адреса як *п8, значення_знаку.розмір - 2 };
    }

    дія отримати_значення_символу(значення_кд: кд, знаки: Знаки, знак: Знак) -> кд {
      змінна значення_знаку = отримати_значення_знаку(значення_кд, знаки, знак);
      вернути кд { значення_знаку.дані[1]::адреса як *п8, значення_знаку.розмір - 2 };
    }

    дія отримати_рядок_з_місцезнаходження(значення_кд: кд, знаки: Знаки, місцезнаходження: Місцезнаходження) -> природне {
      вернути знаки.дані[місцезнаходження.позиція_знаку].позиція_початку.рядок;
    }

    дія отримати_стовпець_з_місцезнаходження(значення_кд: кд, знаки: Знаки, місцезнаходження: Місцезнаходження) -> природне {
      вернути знаки.дані[місцезнаходження.позиція_знаку].позиція_початку.стовпець;
    }
  }
}

простір мавка {
  простір розбирач {
    внутрішня дія зробити_повну_копію_сполуки(М: *Машина, сполука: *Сполука) -> *Сполука;
    внутрішня дія зробити_повну_копію_тіла(М: *Машина, тіло: Сполуки) -> Сполуки;
    внутрішня дія зробити_повну_копію_типу(М: *Машина, тип: Тип) -> Тип;
    внутрішня дія зробити_повну_копію_можливо_типу(М: *Машина, тип: можливо<Тип>) -> можливо<Тип>;
    внутрішня дія зробити_повну_копію_параметра(М: *Машина, параметр: Параметр) -> Параметр;
    внутрішня дія зробити_повну_копію_параметрів(М: *Машина, кількість_параметрів: природне, параметри: *Параметр) -> *Параметр;
    внутрішня дія зробити_повну_копію_аргумента(М: *Машина, аргумент: Аргумент) -> Аргумент;
    внутрішня дія зробити_повну_копію_аргументів(М: *Машина, кількість_аргументів: природне, аргументи: *Аргумент) -> *Аргумент;
    внутрішня дія зробити_повну_копію_гілок(М: *Машина, кількість_гілок: природне, сполуки: **Сполука) -> **Сполука;
    внутрішня дія зробити_повну_копію_елемента_словника(М: *Машина, елемент: ЕлементСловника) -> ЕлементСловника;
    внутрішня дія зробити_повну_копію_елементів_словника(М: *Машина, кількість_елементів: природне, елементи: *ЕлементСловника) -> *ЕлементСловника;
    внутрішня дія зробити_повну_копію_ідентифікаторів(М: *Машина, кількість_ідентифікаторів: природне, ідентифікатори: *Ідентифікатор) -> *Ідентифікатор;
    внутрішня дія зробити_повну_копію_елемента_взяти(М: *Машина, елемент: ЕлементВзяти) -> ЕлементВзяти;
    внутрішня дія зробити_повну_копію_елементів_взяти(М: *Машина, кількість_елементів: природне, елементи: *ЕлементВзяти) -> *ЕлементВзяти;
    внутрішня дія зробити_повну_копію_елемента_дати(М: *Машина, елемент: ЕлементДати) -> ЕлементДати;
    внутрішня дія зробити_повну_копію_елементів_дати(М: *Машина, кількість_елементів: природне, елементи: *ЕлементДати) -> *ЕлементДати;
    внутрішня дія звільнити_сполуку(М: *Машина, сполука: *Сполука);
    внутрішня дія звільнити_тіло(М: *Машина, тіло: Сполуки);
    внутрішня дія звільнити_тип(М: *Машина, тип: Тип);
    внутрішня дія звільнити_параметри(М: *Машина, кількість_параметрів: природне, параметри: *Параметр);
    внутрішня дія звільнити_аргументи(М: *Машина, кількість_аргументів: природне, аргументи: *Аргумент);
    внутрішня дія звільнити_елементи_словника(М: *Машина, кількість_елементів: природне, елементи: *ЕлементСловника);

    внутрішня дія зробити_повну_копію_сполуки(М: *Машина, сполука: *Сполука) -> *Сполука {
      якщо сполука == пусто {
        вернути пусто;
      }
      змінна копія = виділити<Сполука>(М, 1);
      копія.вид = сполука.вид;
      якщо сполука.вид == ВидСполукиВизначити {
        змінна дані = сполука.дані як ДаніСполукиВизначити;
        копія.дані = ДаніСполукиВизначити {
          ідентифікатор = дані.ідентифікатор,
          значення = зробити_повну_копію_сполуки(М, дані.значення)
        };
      } інакше якщо сполука.вид == ВидСполукиЗвернутись {
        змінна дані = сполука.дані як ДаніСполукиЗвернутись;
        копія.дані = ДаніСполукиЗвернутись {
          ідентифікатор = дані.ідентифікатор
        };
      } інакше якщо сполука.вид == ВидСполукиОтриматиВластивість {
        змінна дані = сполука.дані як ДаніСполукиОтриматиВластивість;
        копія.дані = ДаніСполукиОтриматиВластивість {
          предмет = зробити_повну_копію_сполуки(М, дані.предмет),
          ідентифікатор = дані.ідентифікатор
        };
      } інакше якщо сполука.вид == ВидСполукиОтриматиЕлемент {
        змінна дані = сполука.дані як ДаніСполукиОтриматиЕлемент;
        копія.дані = ДаніСполукиОтриматиЕлемент {
          предмет = зробити_повну_копію_сполуки(М, дані.предмет),
          ключ = зробити_повну_копію_сполуки(М, дані.ключ)
        };
      } інакше якщо сполука.вид == ВидСполукиЗмінитиВластивість {
        змінна дані = сполука.дані як ДаніСполукиЗмінитиВластивість;
        копія.дані = ДаніСполукиЗмінитиВластивість {
          предмет = зробити_повну_копію_сполуки(М, дані.предмет),
          ідентифікатор = дані.ідентифікатор,
          значення = зробити_повну_копію_сполуки(М, дані.значення)
        };
      } інакше якщо сполука.вид == ВидСполукиЗмінитиЕлемент {
        змінна дані = сполука.дані як ДаніСполукиЗмінитиЕлемент;
        копія.дані = ДаніСполукиЗмінитиЕлемент {
          предмет = зробити_повну_копію_сполуки(М, дані.предмет),
          ключ = зробити_повну_копію_сполуки(М, дані.ключ),
          значення = зробити_повну_копію_сполуки(М, дані.значення)
        };
      } інакше якщо сполука.вид == ВидСполукиВиконати {
        змінна дані = сполука.дані як ДаніСполукиВиконати;
        копія.дані = ДаніСполукиВиконати {
          предмет = зробити_повну_копію_сполуки(М, дані.предмет),
          кількість_аргументів = дані.кількість_аргументів,
          аргументи = зробити_повну_копію_аргументів(М, дані.кількість_аргументів, дані.аргументи)
        };
      } інакше якщо сполука.вид == ВидСполукиДія {
        змінна дані = сполука.дані як ДаніСполукиДія;
        копія.дані = ДаніСполукиДія {
          тривала = дані.тривала,
          власна = дані.власна,
          клас = зробити_повну_копію_сполуки(М, дані.клас),
          ідентифікатор = дані.ідентифікатор,
          кількість_параметрів = дані.кількість_параметрів,
          параметри = зробити_повну_копію_параметрів(М, дані.кількість_параметрів, дані.параметри),
          тип_результату = зробити_повну_копію_можливо_типу(М, дані.тип_результату),
          тіло = зробити_повну_копію_тіла(М, дані.тіло)
        };
      } інакше якщо сполука.вид == ВидСполукиКлас {
        змінна дані = сполука.дані як ДаніСполукиКлас;
        копія.дані = ДаніСполукиКлас {
          ідентифікатор = дані.ідентифікатор,
          предок = зробити_повну_копію_сполуки(М, дані.предок),
          кількість_параметрів = дані.кількість_параметрів,
          параметри = зробити_повну_копію_параметрів(М, дані.кількість_параметрів, дані.параметри),
          методи = зробити_повну_копію_тіла(М, дані.методи)
        };
      } інакше якщо сполука.вид == ВидСполукиЧисло {
        змінна дані = сполука.дані як ДаніСполукиЧисло;
        копія.дані = ДаніСполукиЧисло {
          позиція_знаку = дані.позиція_знаку
        };
      } інакше якщо сполука.вид == ВидСполукиТекст {
        змінна дані = сполука.дані як ДаніСполукиТекст;
        копія.дані = ДаніСполукиТекст {
          ідентифікатор = дані.ідентифікатор,
          позиція_знаку = дані.позиція_знаку
        };
      } інакше якщо сполука.вид == ВидСполукиОперація {
        змінна дані = сполука.дані як ДаніСполукиОперація;
        копія.дані = ДаніСполукиОперація {
          ліво = зробити_повну_копію_сполуки(М, дані.ліво),
          операція = дані.операція,
          право = зробити_повну_копію_сполуки(М, дані.право)
        };
      } інакше якщо сполука.вид == ВидСполукиЯкщо {
        змінна дані = сполука.дані як ДаніСполукиЯкщо;
        копія.дані = ДаніСполукиЯкщо {
          умова = зробити_повну_копію_сполуки(М, дані.умова),
          тіло = зробити_повну_копію_тіла(М, дані.тіло),
          тіло_інакше = зробити_повну_копію_тіла(М, дані.тіло_інакше)
        };
      } інакше якщо сполука.вид == ВидСполукиПоки {
        змінна дані = сполука.дані як ДаніСполукиПоки;
        копія.дані = ДаніСполукиПоки {
          умова = зробити_повну_копію_сполуки(М, дані.умова),
          тіло = зробити_повну_копію_тіла(М, дані.тіло)
        };
      } інакше якщо сполука.вид == ВидСполукиВернути {
        змінна дані = сполука.дані як ДаніСполукиВернути;
        копія.дані = ДаніСполукиВернути {
          значення = зробити_повну_копію_сполуки(М, дані.значення)
        };
      } інакше якщо сполука.вид == ВидСполукиПередати {
        змінна дані = сполука.дані як ДаніСполукиПередати;
        копія.дані = ДаніСполукиПередати {
          значення = зробити_повну_копію_сполуки(М, дані.значення)
        };
      } інакше якщо сполука.вид == ВидСполукиПослідовність {
        змінна дані = сполука.дані як ДаніСполукиПослідовність;
        копія.дані = ДаніСполукиПослідовність {
          кількість_елементів = дані.кількість_елементів,
          елементи = зробити_повну_копію_гілок(М, дані.кількість_елементів, дані.елементи)
        };
      } інакше якщо сполука.вид == ВидСполукиПерестрибнути {
        змінна дані = сполука.дані як ДаніСполукиПерестрибнути;
        копія.дані = ДаніСполукиПерестрибнути {
          ідентифікатор = дані.ідентифікатор
        };
      } інакше якщо сполука.вид == ВидСполукиПерервати {
      } інакше якщо сполука.вид == ВидСполукиЗначенняЯкщо {
        змінна дані = сполука.дані як ДаніСполукиЗначенняЯкщо;
        копія.дані = ДаніСполукиЗначенняЯкщо {
          умова = зробити_повну_копію_сполуки(М, дані.умова),
          значення_так = зробити_повну_копію_сполуки(М, дані.значення_так),
          значення_ні = зробити_повну_копію_сполуки(М, дані.значення_ні)
        };
      } інакше якщо сполука.вид == ВидСполукиСамоОперація {
        змінна дані = сполука.дані як ДаніСполукиСамоОперація;
        копія.дані = ДаніСполукиСамоОперація {
          операція = дані.операція,
          предмет = зробити_повну_копію_сполуки(М, дані.предмет)
        };
      } інакше якщо сполука.вид == ВидСполукиВзяти {
        змінна дані = сполука.дані як ДаніСполукиВзяти;
        копія.дані = ДаніСполукиВзяти {
          тип = дані.тип,
          відносно = дані.відносно,
          довжина_шляху = дані.довжина_шляху,
          шлях = зробити_повну_копію_ідентифікаторів(М, дані.довжина_шляху, дані.шлях),
          ідентифікатор_як = дані.ідентифікатор_як,
          кількість_елементів = дані.кількість_елементів,
          елементи = зробити_повну_копію_елементів_взяти(М, дані.кількість_елементів, дані.елементи)
        };
      } інакше якщо сполука.вид == ВидСполукиСпробувати {
        змінна дані = сполука.дані як ДаніСполукиСпробувати;
        копія.дані = ДаніСполукиСпробувати {
          тіло = зробити_повну_копію_тіла(М, дані.тіло),
          ідентифікатор_зловити = дані.ідентифікатор_зловити,
          тіло_зловити = зробити_повну_копію_тіла(М, дані.тіло_зловити)
        };
      } інакше якщо сполука.вид == ВидСполукиВпасти {
        змінна дані = сполука.дані як ДаніСполукиВпасти;
        копія.дані = ДаніСполукиВпасти {
          значення = зробити_повну_копію_сполуки(М, дані.значення)
        };
      } інакше якщо сполука.вид == ВидСполукиДати {
        змінна дані = сполука.дані як ДаніСполукиДати;
        копія.дані = ДаніСполукиДати {
          кількість_елементів = дані.кількість_елементів,
          елементи = зробити_повну_копію_елементів_дати(М, дані.кількість_елементів, дані.елементи)
        };
      } інакше якщо сполука.вид == ВидСполукиМодуль {
        змінна дані = сполука.дані як ДаніСполукиМодуль;
        копія.дані = ДаніСполукиМодуль {
          ідентифікатор = дані.ідентифікатор,
          тіло = зробити_повну_копію_тіла(М, дані.тіло)
        };
      } інакше якщо сполука.вид == ВидСполукиСписок {
        змінна дані = сполука.дані як ДаніСполукиСписок;
        копія.дані = ДаніСполукиСписок {
          кількість_елементів = дані.кількість_елементів,
          елементи = зробити_повну_копію_гілок(М, дані.кількість_елементів, дані.елементи)
        };
      } інакше якщо сполука.вид == ВидСполукиСловник {
        змінна дані = сполука.дані як ДаніСполукиСловник;
        копія.дані = ДаніСполукиСловник {
          кількість_елементів = дані.кількість_елементів,
          елементи = зробити_повну_копію_елементів_словника(М, дані.кількість_елементів, дані.елементи)
        };
      } інакше якщо сполука.вид == ВидСполукиСимвол {
        змінна дані = сполука.дані як ДаніСполукиСимвол;
        копія.дані = ДаніСполукиСимвол {
          ідентифікатор = дані.ідентифікатор,
          позиція_знаку = дані.позиція_знаку
        };
      } інакше якщо сполука.вид == ВидСполукиПеребрати {
        змінна дані = сполука.дані як ДаніСполукиПеребрати;
        копія.дані = ДаніСполукиПеребрати {
          предмет = зробити_повну_копію_сполуки(М, дані.предмет),
          ідентифікатор = дані.ідентифікатор,
          тіло = зробити_повну_копію_тіла(М, дані.тіло)
        };
      } інакше якщо сполука.вид == ВидСполукиВизначитиЗзовні {
        змінна дані = сполука.дані як ДаніСполукиВизначитиЗзовні;
        копія.дані = ДаніСполукиВизначитиЗзовні {
          ідентифікатор = дані.ідентифікатор,
          значення = зробити_повну_копію_сполуки(М, дані.значення)
        };
      } інакше якщо сполука.вид == ВидСполукиЧекати {
        змінна дані = сполука.дані як ДаніСполукиЧекати;
        копія.дані = ДаніСполукиЧекати {
          значення = зробити_повну_копію_сполуки(М, дані.значення)
        };
      } інакше якщо сполука.вид == ВидСполукиПроміжок {
        змінна дані = сполука.дані як ДаніСполукиПроміжок;
        копія.дані = ДаніСполукиПроміжок {
          від = зробити_повну_копію_сполуки(М, дані.від),
          до = зробити_повну_копію_сполуки(М, дані.до),
          включно = дані.включно
        };
      } інакше якщо сполука.вид == ВидСполукиЗбитийТекст {
        змінна дані = сполука.дані як ДаніСполукиЗбитийТекст;
        копія.дані = ДаніСполукиЗбитийТекст {
          ідентифікатор = дані.ідентифікатор,
          кількість_гілок = дані.кількість_гілок,
          сполуки = зробити_повну_копію_гілок(М, дані.кількість_гілок, дані.сполуки)
        };
      } інакше {
//        надрукувати_кд("НЕВІДОМИЙ ВИД ГІЛКИ ДЛЯ КОПІЮВАННЯ");
      }
      копія.місцезнаходження = сполука.місцезнаходження;
      вернути копія;
    }

    внутрішня дія зробити_повну_копію_тіла(М: *Машина, тіло: Сполуки) -> Сполуки {
      вернути Сполуки { тіло.розмір, зробити_повну_копію_гілок(М, тіло.розмір, тіло.дані) };
    }

    внутрішня дія зробити_повну_копію_типу(М: *Машина, тип: Тип) -> Тип {
      вернути Тип { тип.кількість_гілок, зробити_повну_копію_гілок(М, тип.кількість_гілок, тип.сполуки) };
    }

    внутрішня дія зробити_повну_копію_можливо_типу(М: *Машина, тип: можливо<Тип>) -> можливо<Тип> {
      якщо тип.заповнено {
        вернути можливо<Тип> { так, зробити_повну_копію_типу(М, тип.значення) };
      }
      вернути можливо<Тип> { ні, ... };
    }

    внутрішня дія зробити_повну_копію_параметра(М: *Машина, параметр: Параметр) -> Параметр {
      вернути Параметр {
        ідентифікатор = параметр.ідентифікатор,
        тип = зробити_повну_копію_можливо_типу(М, параметр.тип),
        значення = зробити_повну_копію_сполуки(М, параметр.значення),
        місцезнаходження = параметр.місцезнаходження
      };
    }

    внутрішня дія зробити_повну_копію_параметрів(М: *Машина, кількість_параметрів: природне, параметри: *Параметр) -> *Параметр {
      якщо кількість_параметрів == 0 {
        вернути пусто;
      }
      змінна нові_параметри = виділити<Параметр>(М, кількість_параметрів);
      змінна п: природне = 0;
      поки п < кількість_параметрів {
        нові_параметри[п] = зробити_повну_копію_параметра(М, параметри[п]);
        п += 1;
      }
      вернути нові_параметри;
    }

    внутрішня дія зробити_повну_копію_аргумента(М: *Машина, аргумент: Аргумент) -> Аргумент {
      вернути Аргумент {
        ідентифікатор = аргумент.ідентифікатор,
        значення = зробити_повну_копію_сполуки(М, аргумент.значення),
        місцезнаходження = аргумент.місцезнаходження
      };
    }

    внутрішня дія зробити_повну_копію_аргументів(М: *Машина, кількість_аргументів: природне, аргументи: *Аргумент) -> *Аргумент {
      якщо кількість_аргументів == 0 {
        вернути пусто;
      }
      змінна нові_аргументи = виділити<Аргумент>(М, кількість_аргументів);
      змінна п: природне = 0;
      поки п < кількість_аргументів {
        нові_аргументи[п] = зробити_повну_копію_аргумента(М, аргументи[п]);
        п += 1;
      }
      вернути нові_аргументи;
    }

    внутрішня дія зробити_повну_копію_гілок(М: *Машина, кількість_гілок: природне, сполуки: **Сполука) -> **Сполука {
      якщо кількість_гілок == 0 {
        вернути пусто;
      }
      змінна нові_сполуки = виділити<*Сполука>(М, кількість_гілок);
      змінна п: природне = 0;
      поки п < кількість_гілок {
        нові_сполуки[п] = зробити_повну_копію_сполуки(М, сполуки[п]);
        п += 1;
      }
      вернути нові_сполуки;
    }

    внутрішня дія зробити_повну_копію_елемента_словника(М: *Машина, елемент: ЕлементСловника) -> ЕлементСловника {
      вернути ЕлементСловника {
        ключ = зробити_повну_копію_сполуки(М, елемент.ключ),
        значення = зробити_повну_копію_сполуки(М, елемент.значення),
        місцезнаходження = елемент.місцезнаходження
      };
    }

    внутрішня дія зробити_повну_копію_елементів_словника(М: *Машина, кількість_елементів: природне, елементи: *ЕлементСловника) -> *ЕлементСловника {
      якщо кількість_елементів == 0 {
        вернути пусто;
      }
      змінна нові_елементи = виділити<ЕлементСловника>(М, кількість_елементів);
      змінна п: природне = 0;
      поки п < кількість_елементів {
        нові_елементи[п] = зробити_повну_копію_елемента_словника(М, елементи[п]);
        п += 1;
      }
      вернути нові_елементи;
    }

    внутрішня дія зробити_повну_копію_ідентифікаторів(М: *Машина, кількість_ідентифікаторів: природне, ідентифікатори: *Ідентифікатор) -> *Ідентифікатор {
      якщо кількість_ідентифікаторів == 0 {
        вернути пусто;
      }
      змінна нові_ідентифікатори = виділити<Ідентифікатор>(М, кількість_ідентифікаторів);
      змінна п: природне = 0;
      поки п < кількість_ідентифікаторів {
        нові_ідентифікатори[п] = ідентифікатори[п];
        п += 1;
      }
      вернути нові_ідентифікатори;
    }

    внутрішня дія зробити_повну_копію_елемента_взяти(М: *Машина, елемент: ЕлементВзяти) -> ЕлементВзяти {
      вернути елемент;
    }

    внутрішня дія зробити_повну_копію_елементів_взяти(М: *Машина, кількість_елементів: природне, елементи: *ЕлементВзяти) -> *ЕлементВзяти {
      якщо кількість_елементів == 0 {
        вернути пусто;
      }
      змінна нові_елементи = виділити<ЕлементВзяти>(М, кількість_елементів);
      змінна п: природне = 0;
      поки п < кількість_елементів {
        нові_елементи[п] = зробити_повну_копію_елемента_взяти(М, елементи[п]);
        п += 1;
      }
      вернути нові_елементи;
    }

    внутрішня дія зробити_повну_копію_елемента_дати(М: *Машина, елемент: ЕлементДати) -> ЕлементДати {
      вернути елемент;
    }

    внутрішня дія зробити_повну_копію_елементів_дати(М: *Машина, кількість_елементів: природне, елементи: *ЕлементДати) -> *ЕлементДати {
      якщо кількість_елементів == 0 {
        вернути пусто;
      }
      змінна нові_елементи = виділити<ЕлементДати>(М, кількість_елементів);
      змінна п: природне = 0;
      поки п < кількість_елементів {
        нові_елементи[п] = зробити_повну_копію_елемента_дати(М, елементи[п]);
        п += 1;
      }
      вернути нові_елементи;
    }

    внутрішня дія звільнити_сполуку(М: *Машина, сполука: *Сполука) {
      якщо сполука != пусто {
        якщо сполука.вид == ВидСполукиВизначити {
          змінна дані = сполука.дані як ДаніСполукиВизначити;
          звільнити_сполуку(М, дані.значення);
        } інакше якщо сполука.вид == ВидСполукиОтриматиВластивість {
          змінна дані = сполука.дані як ДаніСполукиОтриматиВластивість;
          звільнити_сполуку(М, дані.предмет);
        } інакше якщо сполука.вид == ВидСполукиОтриматиЕлемент {
          змінна дані = сполука.дані як ДаніСполукиОтриматиЕлемент;
          звільнити_сполуку(М, дані.предмет);
          звільнити_сполуку(М, дані.ключ);
        } інакше якщо сполука.вид == ВидСполукиЗмінитиВластивість {
          змінна дані = сполука.дані як ДаніСполукиЗмінитиВластивість;
          звільнити_сполуку(М, дані.предмет);
          звільнити_сполуку(М, дані.значення);
        } інакше якщо сполука.вид == ВидСполукиЗмінитиЕлемент {
          змінна дані = сполука.дані як ДаніСполукиЗмінитиЕлемент;
          звільнити_сполуку(М, дані.предмет);
          звільнити_сполуку(М, дані.ключ);
          звільнити_сполуку(М, дані.значення);
        } інакше якщо сполука.вид == ВидСполукиВиконати {
          змінна дані = сполука.дані як ДаніСполукиВиконати;
          звільнити_сполуку(М, дані.предмет);
          звільнити_аргументи(М, дані.кількість_аргументів, дані.аргументи);
        } інакше якщо сполука.вид == ВидСполукиДія {
          змінна дані = сполука.дані як ДаніСполукиДія;
          звільнити_сполуку(М, дані.клас);
          звільнити_параметри(М, дані.кількість_параметрів, дані.параметри);
          якщо дані.тип_результату.заповнено {
            звільнити_тип(М, дані.тип_результату.значення);
          }
          звільнити_тіло(М, дані.тіло);
        } інакше якщо сполука.вид == ВидСполукиКлас {
          змінна дані = сполука.дані як ДаніСполукиКлас;
          звільнити_сполуку(М, дані.предок);
          звільнити_параметри(М, дані.кількість_параметрів, дані.параметри);
          звільнити_тіло(М, дані.методи);
        } інакше якщо сполука.вид == ВидСполукиОперація {
          змінна дані = сполука.дані як ДаніСполукиОперація;
          звільнити_сполуку(М, дані.ліво);
          звільнити_сполуку(М, дані.право);
        } інакше якщо сполука.вид == ВидСполукиЯкщо {
          змінна дані = сполука.дані як ДаніСполукиЯкщо;
          звільнити_сполуку(М, дані.умова);
          звільнити_тіло(М, дані.тіло);
          звільнити_тіло(М, дані.тіло_інакше);
        } інакше якщо сполука.вид == ВидСполукиПоки {
          змінна дані = сполука.дані як ДаніСполукиПоки;
          звільнити_сполуку(М, дані.умова);
          звільнити_тіло(М, дані.тіло);
        } інакше якщо сполука.вид == ВидСполукиВернути {
          змінна дані = сполука.дані як ДаніСполукиВернути;
          звільнити_сполуку(М, дані.значення);
        } інакше якщо сполука.вид == ВидСполукиПередати {
          змінна дані = сполука.дані як ДаніСполукиПередати;
          звільнити_сполуку(М, дані.значення);
        } інакше якщо сполука.вид == ВидСполукиПослідовність {
          змінна дані = сполука.дані як ДаніСполукиПослідовність;
          звільнити_сполуки(М, Сполуки { дані.кількість_елементів, дані.елементи });
        } інакше якщо сполука.вид == ВидСполукиПерестрибнути {
          змінна дані = сполука.дані як ДаніСполукиПерестрибнути;
        } інакше якщо сполука.вид == ВидСполукиПерервати {
        } інакше якщо сполука.вид == ВидСполукиЗначенняЯкщо {
          змінна дані = сполука.дані як ДаніСполукиЗначенняЯкщо;
          звільнити_сполуку(М, дані.умова);
          звільнити_сполуку(М, дані.значення_так);
          звільнити_сполуку(М, дані.значення_ні);
        } інакше якщо сполука.вид == ВидСполукиСамоОперація {
          змінна дані = сполука.дані як ДаніСполукиСамоОперація;
          звільнити_сполуку(М, дані.предмет);
        } інакше якщо сполука.вид == ВидСполукиВзяти {
          змінна дані = сполука.дані як ДаніСполукиВзяти;
          звільнити(М, дані.шлях);
          звільнити(М, дані.елементи);
        } інакше якщо сполука.вид == ВидСполукиСпробувати {
          змінна дані = сполука.дані як ДаніСполукиСпробувати;
          звільнити_тіло(М, дані.тіло);
          звільнити_тіло(М, дані.тіло_зловити);
        } інакше якщо сполука.вид == ВидСполукиВпасти {
          змінна дані = сполука.дані як ДаніСполукиВпасти;
          звільнити_сполуку(М, дані.значення);
        } інакше якщо сполука.вид == ВидСполукиДати {
          змінна дані = сполука.дані як ДаніСполукиДати;
          звільнити(М, дані.елементи);
        } інакше якщо сполука.вид == ВидСполукиМодуль {
          змінна дані = сполука.дані як ДаніСполукиМодуль;
          звільнити_тіло(М, дані.тіло);
        } інакше якщо сполука.вид == ВидСполукиСписок {
          змінна дані = сполука.дані як ДаніСполукиСписок;
          звільнити_сполуки(М, Сполуки { дані.кількість_елементів, дані.елементи });
        } інакше якщо сполука.вид == ВидСполукиСловник {
          змінна дані = сполука.дані як ДаніСполукиСловник;
          звільнити_елементи_словника(М, дані.кількість_елементів, дані.елементи);
        } інакше якщо сполука.вид == ВидСполукиПеребрати {
          змінна дані = сполука.дані як ДаніСполукиПеребрати;
          звільнити_сполуку(М, дані.предмет);
          звільнити_тіло(М, дані.тіло);
        } інакше якщо сполука.вид == ВидСполукиВизначитиЗзовні {
          змінна дані = сполука.дані як ДаніСполукиВизначитиЗзовні;
          звільнити_сполуку(М, дані.значення);
        } інакше якщо сполука.вид == ВидСполукиЧекати {
          змінна дані = сполука.дані як ДаніСполукиЧекати;
          звільнити_сполуку(М, дані.значення);
        } інакше якщо сполука.вид == ВидСполукиПроміжок {
          змінна дані = сполука.дані як ДаніСполукиПроміжок;
          звільнити_сполуку(М, дані.від);
          звільнити_сполуку(М, дані.до);
        } інакше якщо сполука.вид == ВидСполукиЗбитийТекст {
          змінна дані = сполука.дані як ДаніСполукиЗбитийТекст;
          звільнити_сполуки(М, Сполуки { дані.кількість_гілок, дані.сполуки });
        }
        звільнити(М, сполука);
      }
    }

    внутрішня дія звільнити_тіло(М: *Машина, тіло: Сполуки) {
      змінна п: природне = 0;
      поки п < тіло.розмір {
        звільнити_сполуку(М, тіло.дані[п]);
        п += 1;
      }
      звільнити(М, тіло.дані);
    }

    внутрішня дія звільнити_тип(М: *Машина, тип: Тип) {
      змінна п: природне = 0;
      поки п < тип.кількість_гілок {
        звільнити_сполуку(М, тип.сполуки[п]);
        п += 1;
      }
      звільнити(М, тип.сполуки);
    }

    внутрішня дія звільнити_параметри(М: *Машина, кількість_параметрів: природне, параметри: *Параметр) {
      змінна п: природне = 0;
      поки п < кількість_параметрів {
        якщо параметри[п].тип.заповнено {
          звільнити_тип(М, параметри[п].тип.значення);
        }
        звільнити_сполуку(М, параметри[п].значення);
        п += 1;
      }
      звільнити(М, параметри);
    }

    внутрішня дія звільнити_аргументи(М: *Машина, кількість_аргументів: природне, аргументи: *Аргумент) {
      змінна п: природне = 0;
      поки п < кількість_аргументів {
        звільнити_сполуку(М, аргументи[п].значення);
        п += 1;
      }
      звільнити(М, аргументи);
    }

    внутрішня дія звільнити_елементи_словника(М: *Машина, кількість_елементів: природне, елементи: *ЕлементСловника) {
      змінна п: природне = 0;
      поки п < кількість_елементів {
        звільнити_сполуку(М, елементи[п].ключ);
        звільнити_сполуку(М, елементи[п].значення);
        п += 1;
      }
      звільнити(М, елементи);
    }

    внутрішня дія зʼїсти_міжрядки(знаки: Знаки, позиція_початку: природне, вихід_позиції_кінця: *природне) -> логічне;
    внутрішня дія спробувати_розібрати_заперечення(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне;
    внутрішня дія спробувати_розібрати_двійкове_заперечення(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне;
    внутрішня дія спробувати_розібрати_префікс_плюс(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне;
    внутрішня дія спробувати_розібрати_префікс_мінус(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне;
    внутрішня дія спробувати_розібрати_чекати(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне;
    внутрішня дія спробувати_розібрати_частинку(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне;
    внутрішня дія спробувати_розібрати_атом(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне;
    внутрішня дія спробувати_розібрати_аргумент(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: *Аргумент, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне;
    внутрішня дія спробувати_розібрати_молекулу(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне;
    внутрішня дія спробувати_розібрати_молекулу__хвіст(М: *Машина, знаки: Знаки, позиція_початку: природне, позиція_початку_молекули: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, сполука_атома: *Сполука, вихід_позиції_помилки: *природне) -> логічне;
    внутрішня дія спробувати_розібрати_мікрооперацію(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне;
    внутрішня дія спробувати_розібрати_операцію(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, в_гнізді: логічне, вихід_позиції_помилки: *природне) -> логічне;
    внутрішня дія спробувати_розібрати_операцію_1(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, сполука_ліво: *Сполука, мін: природне, в_гнізді: логічне, вихід_позиції_помилки: *природне) -> логічне;
    внутрішня дія спробувати_розібрати_значення(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, в_гнізді: логічне, вихід_позиції_помилки: *природне) -> логічне;
    внутрішня дія спробувати_розібрати_вернути(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне;
    внутрішня дія спробувати_розібрати_перестрибнути(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне;
    внутрішня дія спробувати_розібрати_передати(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне;
    внутрішня дія спробувати_розібрати_перервати(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне;
    внутрішня дія спробувати_розібрати_впасти(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне;
    внутрішня дія спробувати_розібрати_елемент_взяти(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: *ЕлементВзяти, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне;
    внутрішня дія спробувати_розібрати_взяти(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне;
    внутрішня дія спробувати_розібрати_елемент_дати(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: *ЕлементДати, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне;
    внутрішня дія спробувати_розібрати_дати(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне;
    внутрішня дія спробувати_розібрати_елемент_тіла(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне;
    внутрішня дія спробувати_розібрати_тіло(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: *Сполуки, вихід_позиції_кінця: *природне, вид_знаку_закінчення: природне, вихід_позиції_помилки: *природне) -> логічне;
    внутрішня дія спробувати_розібрати_тип(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: *Тип, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне;
    внутрішня дія спробувати_розібрати_параметр(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: *Параметр, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне;
    внутрішня дія спробувати_розібрати_дію(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне;
    внутрішня дія спробувати_розібрати_клас(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне;
    внутрішня дія спробувати_розібрати_модуль(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне;
    внутрішня дія спробувати_розібрати_якщо(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне;
    внутрішня дія спробувати_розібрати_поки(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне;
    внутрішня дія спробувати_розібрати_перебрати(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне;
    внутрішня дія спробувати_розібрати_спробувати(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне;

    внутрішня дія зʼїсти_міжрядки(знаки: Знаки, позиція_початку: природне, вихід_позиції_кінця: *природне) -> логічне {
      якщо знаки.дані[позиція_початку].вид != ВидЗнакуСимволМіжряд {
        вернути ні;
      }
      змінна п = позиція_початку;
      поки знаки.дані[п].вид == ВидЗнакуСимволМіжряд {
        п += 1;
      }
      вихід_позиції_кінця::вміст = п;
      вернути так;
    }

    внутрішня дія спробувати_розібрати_заперечення(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
      змінна п = позиція_початку;

      якщо знаки.дані[п].вид != ВидЗнакуНе {
        вихід_позиції_помилки::вміст = п;
        вернути ні;
      }
      п += 1;

      змінна сполука_значення: *Сполука = пусто;
      змінна позиція_помилки_сполуки_значення: природне = 0;
      якщо не спробувати_розібрати_мікрооперацію(М, знаки, п, сполука_значення::адреса, п::адреса, позиція_помилки_сполуки_значення::адреса) {
        вихід_позиції_помилки::вміст = позиція_помилки_сполуки_значення;
        вернути ні;
      }

      змінна сполука_самооперація = виділити<Сполука>(М, 1);
      сполука_самооперація.вид = ВидСполукиСамоОперація;
      сполука_самооперація.дані = ДаніСполукиСамоОперація {
        операція = ВидСамоОпераціїЛогічнеНі,
        предмет = сполука_значення
      };
      сполука_самооперація.місцезнаходження = Місцезнаходження { позиція_початку };
      вихід::вміст = сполука_самооперація;
      вихід_позиції_кінця::вміст = п;
      вернути так;
    }

    внутрішня дія спробувати_розібрати_двійкове_заперечення(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
      змінна п = позиція_початку;

      якщо знаки.дані[п].вид != ВидЗнакуСимволДвійковеНе {
        вихід_позиції_помилки::вміст = п;
        вернути ні;
      }
      п += 1;

      змінна сполука_значення: *Сполука = пусто;
      змінна позиція_помилки_сполуки_значення: природне = 0;
      якщо не спробувати_розібрати_мікрооперацію(М, знаки, п, сполука_значення::адреса, п::адреса, позиція_помилки_сполуки_значення::адреса) {
        вихід_позиції_помилки::вміст = позиція_помилки_сполуки_значення;
        вернути ні;
      }

      змінна сполука_самооперація = виділити<Сполука>(М, 1);
      сполука_самооперація.вид = ВидСполукиСамоОперація;
      сполука_самооперація.дані = ДаніСполукиСамоОперація {
        операція = ВидСамоОпераціїДвійковеНі,
        предмет = сполука_значення
      };
      сполука_самооперація.місцезнаходження = Місцезнаходження { позиція_початку };
      вихід::вміст = сполука_самооперація;
      вихід_позиції_кінця::вміст = п;
      вернути так;
    }

    внутрішня дія спробувати_розібрати_префікс_плюс(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
      змінна п = позиція_початку;

      якщо знаки.дані[п].вид != ВидЗнакуСимволПлюс {
        вихід_позиції_помилки::вміст = п;
        вернути ні;
      }
      п += 1;

      змінна сполука_значення: *Сполука = пусто;
      змінна позиція_помилки_сполуки_значення: природне = 0;
      якщо не спробувати_розібрати_мікрооперацію(М, знаки, п, сполука_значення::адреса, п::адреса, позиція_помилки_сполуки_значення::адреса) {
        вихід_позиції_помилки::вміст = позиція_помилки_сполуки_значення;
        вернути ні;
      }

      змінна сполука_самооперація = виділити<Сполука>(М, 1);
      сполука_самооперація.вид = ВидСполукиСамоОперація;
      сполука_самооперація.дані = ДаніСполукиСамоОперація {
        операція = ВидСамоОпераціїПлюс,
        предмет = сполука_значення
      };
      сполука_самооперація.місцезнаходження = Місцезнаходження { позиція_початку };
      вихід::вміст = сполука_самооперація;
      вихід_позиції_кінця::вміст = п;
      вернути так;
    }

    внутрішня дія спробувати_розібрати_префікс_мінус(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
      змінна п = позиція_початку;

      якщо знаки.дані[п].вид != ВидЗнакуСимволМінус {
        вихід_позиції_помилки::вміст = п;
        вернути ні;
      }
      п += 1;

      змінна сполука_значення: *Сполука = пусто;
      змінна позиція_помилки_сполуки_значення: природне = 0;
      якщо не спробувати_розібрати_мікрооперацію(М, знаки, п, сполука_значення::адреса, п::адреса, позиція_помилки_сполуки_значення::адреса) {
        вихід_позиції_помилки::вміст = позиція_помилки_сполуки_значення;
        вернути ні;
      }

      змінна сполука_самооперація = виділити<Сполука>(М, 1);
      сполука_самооперація.вид = ВидСполукиСамоОперація;
      сполука_самооперація.дані = ДаніСполукиСамоОперація {
        операція = ВидСамоОпераціїМінус,
        предмет = сполука_значення
      };
      сполука_самооперація.місцезнаходження = Місцезнаходження { позиція_початку };
      вихід::вміст = сполука_самооперація;
      вихід_позиції_кінця::вміст = п;
      вернути так;
    }

    внутрішня дія спробувати_розібрати_чекати(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
      змінна п = позиція_початку;

      якщо знаки.дані[п].вид != ВидЗнакуЧекати {
        вихід_позиції_помилки::вміст = п;
        вернути ні;
      }
      п += 1;

      змінна сполука_значення: *Сполука = пусто;
      змінна позиція_помилки_сполуки_значення: природне = 0;
      якщо не спробувати_розібрати_мікрооперацію(М, знаки, п, сполука_значення::адреса, п::адреса, позиція_помилки_сполуки_значення::адреса) {
        вихід_позиції_помилки::вміст = позиція_помилки_сполуки_значення;
        вернути ні;
      }

      змінна сполука_чекати = виділити<Сполука>(М, 1);
      сполука_чекати.вид = ВидСполукиЧекати;
      сполука_чекати.дані = ДаніСполукиЧекати {
        значення = сполука_значення
      };
      сполука_чекати.місцезнаходження = Місцезнаходження { позиція_початку };
      вихід::вміст = сполука_чекати;
      вихід_позиції_кінця::вміст = п;
      вернути так;
    }



    внутрішня дія спробувати_розібрати_послідовність(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
      змінна п = позиція_початку;

      якщо знаки.дані[п].вид == ВидЗнакуСимволВідкритаДужка {
        змінна позиція_початку_послідовності = п;

        п += 1;

        зʼїсти_міжрядки(знаки, п, п::адреса);

        якщо знаки.дані[п].вид == ВидЗнакуСимволЗакритаДужка {
          змінна сполука_послідовності = виділити<Сполука>(М, 1);
          сполука_послідовності.вид = ВидСполукиПослідовність;
          сполука_послідовності.дані = ДаніСполукиПослідовність {
            кількість_елементів = 0,
            елементи = пусто
          };
          сполука_послідовності.місцезнаходження = Місцезнаходження { позиція_початку_послідовності };
          вихід::вміст = сполука_послідовності;
          вихід_позиції_кінця::вміст = п;
          вернути так;
        }

        змінна сполука_гнізда: *Сполука = пусто;
        змінна позиція_помилки_сполуки_гнізда: природне = 0;
        якщо спробувати_розібрати_значення(М, знаки, п, сполука_гнізда::адреса, п::адреса, так, позиція_помилки_сполуки_гнізда::адреса) {
          п += 1;

          зʼїсти_міжрядки(знаки, п, п::адреса);

          якщо знаки.дані[п].вид == ВидЗнакуСимволЗакритаДужка {
            вихід::вміст = сполука_гнізда;
            вихід_позиції_кінця::вміст = п;
            вернути так;
          } інакше якщо знаки.дані[п].вид == ВидЗнакуСимволКома {
            п += 1;

            зʼїсти_міжрядки(знаки, п, п::адреса);

            якщо знаки.дані[п].вид == ВидЗнакуСимволЗакритаДужка {
              змінна елементи_послідовності = зробити_накопичувач<*Сполука>(М, 0);
              елементи_послідовності.покласти(М, сполука_гнізда);

              змінна сполука_послідовності = виділити<Сполука>(М, 1);
              сполука_послідовності.вид = ВидСполукиПослідовність;
              сполука_послідовності.дані = ДаніСполукиПослідовність {
                кількість_елементів = елементи_послідовності.розмір,
                елементи = елементи_послідовності.дані
              };
              сполука_послідовності.місцезнаходження = Місцезнаходження { позиція_початку_послідовності };
              вихід::вміст = сполука_послідовності;
              вихід_позиції_кінця::вміст = п;
              вернути так;
            }
          } інакше {
            звільнити_сполуку(М, сполука_гнізда);
            вихід_позиції_помилки::вміст = п;
            вернути ні;
          }
        }

        змінна елементи_послідовності = зробити_накопичувач<*Сполука>(М, 0);
        елементи_послідовності.покласти(М, сполука_гнізда);

        поки п < знаки.розмір {
          змінна сполука_значення_елемента: *Сполука = пусто;
          змінна позиція_помилки_елемента: природне = 0;

          якщо спробувати_розібрати_значення(М, знаки, п, сполука_значення_елемента::адреса, п::адреса, ні, позиція_помилки_елемента::адреса) {
            п += 1;

            зʼїсти_міжрядки(знаки, п, п::адреса);
          } інакше {
            звільнити_сполуки(М, Сполуки { елементи_послідовності.розмір, елементи_послідовності.дані });
            вихід_позиції_помилки::вміст = позиція_помилки_елемента;
            вернути ні;
          }

          елементи_послідовності.покласти(М, сполука_значення_елемента);

          зʼїсти_міжрядки(знаки, п, п::адреса);

          якщо знаки.дані[п].вид == ВидЗнакуСимволКома {
            п += 1;
            зʼїсти_міжрядки(знаки, п, п::адреса);
            якщо знаки.дані[п].вид == ВидЗнакуСимволЗакритаДужка {
              змінна сполука_послідовності = виділити<Сполука>(М, 1);
              сполука_послідовності.вид = ВидСполукиПослідовність;
              сполука_послідовності.дані = ДаніСполукиПослідовність {
                кількість_елементів = елементи_послідовності.розмір,
                елементи = елементи_послідовності.дані
              };
              сполука_послідовності.місцезнаходження = Місцезнаходження { позиція_початку_послідовності };
              вихід::вміст = сполука_послідовності;
              вихід_позиції_кінця::вміст = п;
              вернути так;
            }
          } інакше якщо знаки.дані[п].вид == ВидЗнакуСимволЗакритаДужка {
            змінна сполука_послідовності = виділити<Сполука>(М, 1);
            сполука_послідовності.вид = ВидСполукиПослідовність;
            сполука_послідовності.дані = ДаніСполукиПослідовність {
              кількість_елементів = елементи_послідовності.розмір,
              елементи = елементи_послідовності.дані
            };
            сполука_послідовності.місцезнаходження = Місцезнаходження { позиція_початку_послідовності };
            вихід::вміст = сполука_послідовності;
            вихід_позиції_кінця::вміст = п;
            вернути так;
          } інакше {
            звільнити_сполуки(М, Сполуки { елементи_послідовності.розмір, елементи_послідовності.дані });
            вихід_позиції_помилки::вміст = п;
            вернути ні;
          }
        }

        звільнити_сполуки(М, Сполуки { елементи_послідовності.розмір, елементи_послідовності.дані });
        вихід_позиції_помилки::вміст = п;
        вернути ні;
      }

      вихід_позиції_помилки::вміст = позиція_початку;
      вернути ні;
    }

    внутрішня дія спробувати_розібрати_частинку(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
      змінна п = позиція_початку;

      якщо спробувати_розібрати_послідовність(М, знаки, п, вихід, вихід_позиції_кінця, вихід_позиції_помилки) {
        вернути так;
      }

      п = позиція_початку;

      якщо знаки.дані[п].вид == ВидЗнакуІдентифікатор {
        змінна позиція_ідентифікатора = п;

        п += 1;

        якщо знаки.дані[п].вид == ВидЗнакуТекст {
          змінна сполука_тексту = виділити<Сполука>(М, 1);
          сполука_тексту.вид = ВидСполукиТекст;
          сполука_тексту.дані = ДаніСполукиТекст {
            ідентифікатор = можливо<Ідентифікатор> { так, Ідентифікатор { позиція_ідентифікатора } },
            позиція_знаку = п
          };
          сполука_тексту.місцезнаходження = Місцезнаходження { позиція_ідентифікатора };
          вихід::вміст = сполука_тексту;
          вихід_позиції_кінця::вміст = п;
          вернути так;
        } інакше якщо знаки.дані[п].вид == ВидЗнакуСимвол {
          змінна сполука_символа = виділити<Сполука>(М, 1);
          сполука_символа.вид = ВидСполукиСимвол;
          сполука_символа.дані = ДаніСполукиСимвол {
            ідентифікатор = можливо<Ідентифікатор> { так, Ідентифікатор { позиція_ідентифікатора } },
            позиція_знаку = п
          };
          сполука_символа.місцезнаходження = Місцезнаходження { позиція_ідентифікатора };
          вихід::вміст = сполука_символа;
          вихід_позиції_кінця::вміст = п;
          вернути так;
        } інакше якщо знаки.дані[п].вид == ВидЗнакуПочатокЗбитогоТексту {
          п += 1;

          змінна накопичувач_гілок = зробити_накопичувач<*Сполука>(М, 0);

          поки п < знаки.розмір {
            змінна сполука_значення: *Сполука = пусто;
            змінна позиція_помилки_збитого_тексту: природне = 0;

            якщо знаки.дані[п].вид == ВидЗнакуЧастинаЗбитогоТексту {
              змінна сполука_тексту = виділити<Сполука>(М, 1);
              сполука_тексту.вид = ВидСполукиТекст;
              сполука_тексту.дані = ДаніСполукиТекст {
                ідентифікатор = можливо<Ідентифікатор> { так, Ідентифікатор { позиція_ідентифікатора } },
                позиція_знаку = п
              };
              сполука_тексту.місцезнаходження = Місцезнаходження { позиція_ідентифікатора };
              накопичувач_гілок.покласти(М, сполука_тексту);
              п += 1;
            } інакше якщо спробувати_розібрати_значення(М, знаки, п, сполука_значення::адреса, п::адреса, ні, позиція_помилки_збитого_тексту::адреса) {
              накопичувач_гілок.покласти(М, сполука_значення);
              п += 1;
            } інакше {
              вихід_позиції_помилки::вміст = позиція_помилки_збитого_тексту;
              звільнити_сполуки(М, Сполуки { накопичувач_гілок.розмір, накопичувач_гілок.дані });
              вернути ні;
            }

            якщо знаки.дані[п].вид == ВидЗнакуРоздільникЗбитогоТексту {
              п += 1;
            } інакше якщо знаки.дані[п].вид == ВидЗнакуКінецьЗбитогоТексту {
              стрибнути вихід_збитого_тексту_з_ідентифікатором;
            } інакше {
              вихід_позиції_помилки::вміст = п;
              звільнити_сполуки(М, Сполуки { накопичувач_гілок.розмір, накопичувач_гілок.дані });
              вернути ні;
            }
          }

    вихід_збитого_тексту_з_ідентифікатором:
          якщо накопичувач_гілок.розмір == 1 {
            змінна сполука = накопичувач_гілок.дані[0];
            звільнити(М, накопичувач_гілок.дані);
            вихід::вміст = сполука;
            вихід_позиції_кінця::вміст = п;
            вернути так;
          } інакше {
            змінна сполука_збитого_тексту = виділити<Сполука>(М, 1);
            сполука_збитого_тексту.вид = ВидСполукиЗбитийТекст;
            сполука_збитого_тексту.дані = ДаніСполукиЗбитийТекст {
              ідентифікатор = можливо<Ідентифікатор> { так, Ідентифікатор { позиція_ідентифікатора } },
              кількість_гілок = накопичувач_гілок.розмір,
              сполуки = накопичувач_гілок.дані,
            };
            сполука_збитого_тексту.місцезнаходження = Місцезнаходження { п };
            вихід::вміст = сполука_збитого_тексту;
            вихід_позиції_кінця::вміст = п;
            вернути так;
          }
        } інакше {
          п -= 1;
        }

        змінна сполука_звернення = виділити<Сполука>(М, 1);
        сполука_звернення.вид = ВидСполукиЗвернутись;
        сполука_звернення.дані = ДаніСполукиЗвернутись {
          ідентифікатор = Ідентифікатор { п }
        };
        сполука_звернення.місцезнаходження = Місцезнаходження { п };
        вихід::вміст = сполука_звернення;
        вихід_позиції_кінця::вміст = п;
        вернути так;
      }

      якщо знаки.дані[п].вид == ВидЗнакуЧисло {
        змінна сполука_числа = виділити<Сполука>(М, 1);
        сполука_числа.вид = ВидСполукиЧисло;
        сполука_числа.дані = ДаніСполукиЧисло {
          позиція_знаку = п
        };
        сполука_числа.місцезнаходження = Місцезнаходження { п };
        вихід::вміст = сполука_числа;
        вихід_позиції_кінця::вміст = п;
        вернути так;
      }

      якщо знаки.дані[п].вид == ВидЗнакуТекст {
        змінна сполука_тексту = виділити<Сполука>(М, 1);
        сполука_тексту.вид = ВидСполукиТекст;
        сполука_тексту.дані = ДаніСполукиТекст {
          ідентифікатор = можливо<Ідентифікатор> { ні, ... },
          позиція_знаку = п
        };
        сполука_тексту.місцезнаходження = Місцезнаходження { п };
        вихід::вміст = сполука_тексту;
        вихід_позиції_кінця::вміст = п;
        вернути так;
      }

      якщо знаки.дані[п].вид == ВидЗнакуСимвол {
        змінна сполука_символа = виділити<Сполука>(М, 1);
        сполука_символа.вид = ВидСполукиСимвол;
        сполука_символа.дані = ДаніСполукиСимвол {
          ідентифікатор = можливо<Ідентифікатор> { ні, ... },
          позиція_знаку = п
        };
        сполука_символа.місцезнаходження = Місцезнаходження { п };
        вихід::вміст = сполука_символа;
        вихід_позиції_кінця::вміст = п;
        вернути так;
      }

      якщо знаки.дані[п].вид == ВидЗнакуПочатокЗбитогоТексту {
        п += 1;

        змінна накопичувач_гілок = зробити_накопичувач<*Сполука>(М, 0);

        поки п < знаки.розмір {
          змінна сполука_значення: *Сполука = пусто;
          змінна позиція_помилки_збитого_тексту: природне = 0;
          якщо знаки.дані[п].вид == ВидЗнакуЧастинаЗбитогоТексту {
            змінна сполука_тексту = виділити<Сполука>(М, 1);
            сполука_тексту.вид = ВидСполукиТекст;
            сполука_тексту.дані = ДаніСполукиТекст {
              ідентифікатор = можливо<Ідентифікатор> { ні, ... },
              позиція_знаку = п
            };
            сполука_тексту.місцезнаходження = Місцезнаходження { п };
            накопичувач_гілок.покласти(М, сполука_тексту);
            п += 1;
          } інакше якщо спробувати_розібрати_значення(М, знаки, п, сполука_значення::адреса, п::адреса, ні, позиція_помилки_збитого_тексту::адреса) {
            накопичувач_гілок.покласти(М, сполука_значення);
            п += 1;
          } інакше {
            вихід_позиції_помилки::вміст = позиція_помилки_збитого_тексту;
            звільнити_сполуки(М, Сполуки { накопичувач_гілок.розмір, накопичувач_гілок.дані });
            вернути ні;
          }

          якщо знаки.дані[п].вид == ВидЗнакуРоздільникЗбитогоТексту {
            п += 1;
          } інакше якщо знаки.дані[п].вид == ВидЗнакуКінецьЗбитогоТексту {
            стрибнути вихід_збитого_тексту;
          } інакше {
            вихід_позиції_помилки::вміст = п;
            звільнити_сполуки(М, Сполуки { накопичувач_гілок.розмір, накопичувач_гілок.дані });
            вернути ні;
          }
        }

    вихід_збитого_тексту:
        якщо накопичувач_гілок.розмір == 1 {
          змінна сполука = накопичувач_гілок.дані[0];
          звільнити(М, накопичувач_гілок.дані);
          вихід::вміст = сполука;
          вихід_позиції_кінця::вміст = п;
          вернути так;
        } інакше {
          змінна сполука_збитого_тексту = виділити<Сполука>(М, 1);
          сполука_збитого_тексту.вид = ВидСполукиЗбитийТекст;
          сполука_збитого_тексту.дані = ДаніСполукиЗбитийТекст {
            ідентифікатор = можливо<Ідентифікатор> { ні, ... },
            кількість_гілок = накопичувач_гілок.розмір,
            сполуки = накопичувач_гілок.дані,
          };
          сполука_збитого_тексту.місцезнаходження = Місцезнаходження { п };
          вихід::вміст = сполука_збитого_тексту;
          вихід_позиції_кінця::вміст = п;
          вернути так;
        }
      }

      вихід_позиції_помилки::вміст = п;
      вернути ні;
    }

    внутрішня дія спробувати_розібрати_атом(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
      змінна п = позиція_початку;

      якщо знаки.дані[п].вид == ВидЗнакуСимволКвадратнаВідкритаДужка {
        змінна позиція_початку_списку = п;

        п += 1;

        зʼїсти_міжрядки(знаки, п, п::адреса);

        якщо знаки.дані[п].вид == ВидЗнакуСимволКвадратнаЗакритаДужка {
          змінна сполука_списку = виділити<Сполука>(М, 1);
          сполука_списку.вид = ВидСполукиСписок;
          сполука_списку.дані = ДаніСполукиСписок {
            кількість_елементів = 0,
            елементи = пусто
          };
          сполука_списку.місцезнаходження = Місцезнаходження { позиція_початку_списку };
          вихід::вміст = сполука_списку;
          вихід_позиції_кінця::вміст = п;
          вернути так;
        }

        змінна елементи_списку = зробити_накопичувач<*Сполука>(М, 0);

        поки п < знаки.розмір {
          змінна сполука_значення_елемента: *Сполука = пусто;
          змінна позиція_помилки_елемента: природне = 0;

          якщо спробувати_розібрати_значення(М, знаки, п, сполука_значення_елемента::адреса, п::адреса, ні, позиція_помилки_елемента::адреса) {
            п += 1;

            зʼїсти_міжрядки(знаки, п, п::адреса);
          } інакше {
            звільнити_сполуки(М, Сполуки { елементи_списку.розмір, елементи_списку.дані });
            вихід_позиції_помилки::вміст = позиція_помилки_елемента;
            вернути ні;
          }

          елементи_списку.покласти(М, сполука_значення_елемента);

          зʼїсти_міжрядки(знаки, п, п::адреса);

          якщо знаки.дані[п].вид == ВидЗнакуСимволКома {
            п += 1;
            зʼїсти_міжрядки(знаки, п, п::адреса);
            якщо знаки.дані[п].вид == ВидЗнакуСимволКвадратнаЗакритаДужка {
              змінна сполука_списку = виділити<Сполука>(М, 1);
              сполука_списку.вид = ВидСполукиСписок;
              сполука_списку.дані = ДаніСполукиСписок {
                кількість_елементів = елементи_списку.розмір,
                елементи = елементи_списку.дані
              };
              сполука_списку.місцезнаходження = Місцезнаходження { позиція_початку_списку };
              вихід::вміст = сполука_списку;
              вихід_позиції_кінця::вміст = п;
              вернути так;
            }
          } інакше якщо знаки.дані[п].вид == ВидЗнакуСимволКвадратнаЗакритаДужка {
            змінна сполука_списку = виділити<Сполука>(М, 1);
            сполука_списку.вид = ВидСполукиСписок;
            сполука_списку.дані = ДаніСполукиСписок {
              кількість_елементів = елементи_списку.розмір,
              елементи = елементи_списку.дані
            };
            сполука_списку.місцезнаходження = Місцезнаходження { позиція_початку_списку };
            вихід::вміст = сполука_списку;
            вихід_позиції_кінця::вміст = п;
            вернути так;
          } інакше {
            звільнити_сполуки(М, Сполуки { елементи_списку.розмір, елементи_списку.дані });
            вихід_позиції_помилки::вміст = п;
            вернути ні;
          }
        }

        звільнити_сполуки(М, Сполуки { елементи_списку.розмір, елементи_списку.дані });
        вихід_позиції_помилки::вміст = п;
        вернути ні;
      }

      якщо знаки.дані[п].вид == ВидЗнакуСимволФігурнаВідкритаДужка {
        змінна позиція_початку_словника = п;

        п += 1;

        зʼїсти_міжрядки(знаки, п, п::адреса);

        якщо знаки.дані[п].вид == ВидЗнакуСимволФігурнаЗакритаДужка {
          змінна сполука_словника = виділити<Сполука>(М, 1);
          сполука_словника.вид = ВидСполукиСловник;
          сполука_словника.дані = ДаніСполукиСловник {
            кількість_елементів = 0,
            елементи = пусто
          };
          сполука_словника.місцезнаходження = Місцезнаходження { позиція_початку_словника };
          вихід::вміст = сполука_словника;
          вихід_позиції_кінця::вміст = п;
          вернути так;
        }

        змінна елементи_словника = зробити_накопичувач<ЕлементСловника>(М, 0);

        поки п < знаки.розмір {
          змінна сполука_ключа_елемента: *Сполука = пусто;
          змінна сполука_значення_елемента: *Сполука = пусто;
          змінна позиція_помилки_елемента: природне = 0;

          якщо спробувати_розібрати_значення(М, знаки, п, сполука_ключа_елемента::адреса, п::адреса, ні, позиція_помилки_елемента::адреса) {
            п += 1;

            зʼїсти_міжрядки(знаки, п, п::адреса);

            якщо знаки.дані[п].вид == ВидЗнакуСимволРівно {
              п += 1;

              якщо знаки.дані[п].вид == ВидЗнакуСимволБільше {
                п += 1;

                зʼїсти_міжрядки(знаки, п, п::адреса);

                якщо спробувати_розібрати_значення(М, знаки, п, сполука_значення_елемента::адреса, п::адреса, ні, позиція_помилки_елемента::адреса) {
                  п += 1;
                } інакше {
                  звільнити_сполуку(М, сполука_ключа_елемента);
                  звільнити_елементи_словника(М, елементи_словника.розмір, елементи_словника.дані);
                  вихід_позиції_помилки::вміст = позиція_помилки_елемента;
                  вернути ні;
                }
              } інакше {
                звільнити_елементи_словника(М, елементи_словника.розмір, елементи_словника.дані);
                вихід_позиції_помилки::вміст = п;
                вернути ні;
              }
            } інакше {
              звільнити_елементи_словника(М, елементи_словника.розмір, елементи_словника.дані);
              вихід_позиції_помилки::вміст = п;
              вернути ні;
            }
          } інакше {
            звільнити_елементи_словника(М, елементи_словника.розмір, елементи_словника.дані);
            вихід_позиції_помилки::вміст = позиція_помилки_елемента;
            вернути ні;
          }

          елементи_словника.покласти(М, ЕлементСловника {
            ключ = сполука_ключа_елемента,
            значення = сполука_значення_елемента,
            місцезнаходження = Місцезнаходження { позиція_початку }
          });

          зʼїсти_міжрядки(знаки, п, п::адреса);

          якщо знаки.дані[п].вид == ВидЗнакуСимволКома {
            п += 1;
            зʼїсти_міжрядки(знаки, п, п::адреса);
            якщо знаки.дані[п].вид == ВидЗнакуСимволФігурнаЗакритаДужка {
              змінна сполука_словника = виділити<Сполука>(М, 1);
              сполука_словника.вид = ВидСполукиСловник;
              сполука_словника.дані = ДаніСполукиСловник {
                кількість_елементів = елементи_словника.розмір,
                елементи = елементи_словника.дані
              };
              сполука_словника.місцезнаходження = Місцезнаходження { позиція_початку_словника };
              вихід::вміст = сполука_словника;
              вихід_позиції_кінця::вміст = п;
              вернути так;
            }
          } інакше якщо знаки.дані[п].вид == ВидЗнакуСимволФігурнаЗакритаДужка {
            змінна сполука_словника = виділити<Сполука>(М, 1);
            сполука_словника.вид = ВидСполукиСловник;
            сполука_словника.дані = ДаніСполукиСловник {
              кількість_елементів = елементи_словника.розмір,
              елементи = елементи_словника.дані
            };
            сполука_словника.місцезнаходження = Місцезнаходження { позиція_початку_словника };
            вихід::вміст = сполука_словника;
            вихід_позиції_кінця::вміст = п;
            вернути так;
          } інакше {
            звільнити_елементи_словника(М, елементи_словника.розмір, елементи_словника.дані);
            вихід_позиції_помилки::вміст = п;
            вернути ні;
          }
        }

        звільнити_елементи_словника(М, елементи_словника.розмір, елементи_словника.дані);
        вихід_позиції_помилки::вміст = п;
        вернути ні;
      }

      п = позиція_початку;

      якщо спробувати_розібрати_частинку(М, знаки, п, вихід, вихід_позиції_кінця, вихід_позиції_помилки) {
        вернути так;
      }

      вернути ні;
    }

    внутрішня дія спробувати_розібрати_аргумент(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: *Аргумент, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
      змінна п = позиція_початку;

      змінна має_ідентифікатор = ні;
      змінна позиція_ідентифікатора = п;

      якщо знаки.дані[п].вид == ВидЗнакуІдентифікатор {
        має_ідентифікатор = так;
        п += 1;

        зʼїсти_міжрядки(знаки, п, п::адреса);

        якщо знаки.дані[п].вид == ВидЗнакуСимволРівно {
          п += 1;

          якщо знаки.дані[п].вид == ВидЗнакуСимволРівно {
            має_ідентифікатор = ні;
            п = позиція_ідентифікатора;
          } інакше {
            зʼїсти_міжрядки(знаки, п, п::адреса);
          }
        } інакше {
          має_ідентифікатор = ні;
          п = позиція_ідентифікатора;
        }
      }

      змінна сполука_значення_аргумента: *Сполука = пусто;
      змінна позиція_помилки_аргумента: природне = 0;
      якщо спробувати_розібрати_значення(М, знаки, п, сполука_значення_аргумента::адреса, п::адреса, ні, позиція_помилки_аргумента::адреса) {
        якщо має_ідентифікатор {
          вихід::вміст = Аргумент {
            ідентифікатор = можливо<Ідентифікатор> { так, Ідентифікатор { позиція_ідентифікатора } },
            значення = сполука_значення_аргумента,
            місцезнаходження = Місцезнаходження { позиція_початку }
          };
        } інакше {
          вихід::вміст = Аргумент {
            ідентифікатор = можливо<Ідентифікатор> { ні, ... },
            значення = сполука_значення_аргумента,
            місцезнаходження = Місцезнаходження { позиція_початку }
          };
        }

        вихід_позиції_кінця::вміст = п;
        вернути так;
      }

      вихід_позиції_помилки::вміст = позиція_помилки_аргумента;
      вернути ні;
    }

    //
    // --- з рекурсією ---
    // молекула = (молекула ('.' ідентифікатор)) | атом;
    //
    // --- без рекурсії ---
    // молекула = атом хвіст_молекули;
    // хвіст_молекули = ('.' ідентифікатор хвіст_молекули) | ;
    //
    внутрішня дія спробувати_розібрати_молекулу(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
      змінна п = позиція_початку;

      змінна сполука_атома: *Сполука = пусто;
      змінна позиція_помилки_атома: природне = 0;
      якщо спробувати_розібрати_атом(М, знаки, п, сполука_атома::адреса, п::адреса, позиція_помилки_атома::адреса) {
        п += 1;

        змінна сполука_хвоста: *Сполука = пусто;
        змінна позиція_помилки_хвоста: природне = 0;
        якщо спробувати_розібрати_молекулу__хвіст(М, знаки, п, позиція_початку, сполука_хвоста::адреса, п::адреса, сполука_атома, позиція_помилки_хвоста::адреса) {
          вихід::вміст = сполука_хвоста;
          вихід_позиції_кінця::вміст = п;
          вернути так;
        } інакше {
          п -= 1;
        }

        вихід::вміст = сполука_атома;
        вихід_позиції_кінця::вміст = п;
        вернути так;
      } інакше {
        вихід_позиції_помилки::вміст = позиція_помилки_атома;
        стрибнути звільнити_і_вийти;
      }

    звільнити_і_вийти:
      вернути ні;
    }

    внутрішня дія спробувати_розібрати_молекулу__хвіст(М: *Машина, знаки: Знаки, позиція_початку: природне, позиція_початку_молекули: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, сполука_атома: *Сполука, вихід_позиції_помилки: *природне) -> логічне {
      змінна п = позиція_початку;
      змінна п_перед_зʼїданням = п;

      якщо зʼїсти_міжрядки(знаки, п, п::адреса) {
        якщо знаки.дані[п].вид == ВидЗнакуСимволКрапка {
          стрибнути отримання_властивості;
        } інакше {
          п = п_перед_зʼїданням;
        }
      }

      якщо знаки.дані[п].вид == ВидЗнакуСимволКрапка { // отримати властивість
    отримання_властивості:
        п += 1;

        зʼїсти_міжрядки(знаки, п, п::адреса);

        якщо знаки.дані[п].вид == ВидЗнакуІдентифікатор або знаки.дані[п].вид == ВидЗнакуЧисло {
          змінна сполука_отримати_властивість = виділити<Сполука>(М, 1);
          сполука_отримати_властивість.вид = ВидСполукиОтриматиВластивість;
          сполука_отримати_властивість.дані = ДаніСполукиОтриматиВластивість {
            предмет = сполука_атома,
            ідентифікатор = Ідентифікатор { п }
          };
          сполука_отримати_властивість.місцезнаходження = Місцезнаходження { позиція_початку_молекули };
          п += 1;
          змінна позиція_помилки_молекули_хвоста: природне = 0;
          якщо спробувати_розібрати_молекулу__хвіст(М, знаки, п, позиція_початку_молекули, вихід, вихід_позиції_кінця, сполука_отримати_властивість, позиція_помилки_молекули_хвоста::адреса) {
            вернути так;
          } інакше {
            звільнити(М, сполука_отримати_властивість);
            вихід_позиції_помилки::вміст = позиція_помилки_молекули_хвоста;
            вернути ні;
          }
        }

        вихід_позиції_помилки::вміст = п;
        вернути ні;
      } інакше якщо знаки.дані[п].вид == ВидЗнакуСимволКвадратнаВідкритаДужка { // отримати елемент
        п += 1;

        зʼїсти_міжрядки(знаки, п, п::адреса);

        змінна сполука_ключа: *Сполука = пусто;
        змінна позиція_помилки_ключа: природне = 0;
        якщо спробувати_розібрати_молекулу(М, знаки, п, сполука_ключа::адреса, п::адреса, позиція_помилки_ключа::адреса) {
          п += 1;
        } інакше {
          вихід_позиції_помилки::вміст = позиція_помилки_ключа;
          вернути ні;
        }

        змінна сполука_отримати_елемент = виділити<Сполука>(М, 1);
        сполука_отримати_елемент.вид = ВидСполукиОтриматиЕлемент;
        сполука_отримати_елемент.дані = ДаніСполукиОтриматиЕлемент {
          предмет = сполука_атома,
          ключ = сполука_ключа
        };
        сполука_отримати_елемент.місцезнаходження = Місцезнаходження { позиція_початку_молекули };

        зʼїсти_міжрядки(знаки, п, п::адреса);

        якщо знаки.дані[п].вид == ВидЗнакуСимволКвадратнаЗакритаДужка {
          п += 1;
          змінна позиція_помилки_молекули_хвоста: природне = 0;
          якщо спробувати_розібрати_молекулу__хвіст(М, знаки, п, позиція_початку_молекули, вихід, вихід_позиції_кінця, сполука_отримати_елемент, позиція_помилки_молекули_хвоста::адреса) {
            вернути так;
          } інакше {
            звільнити(М, сполука_ключа);
            звільнити(М, сполука_отримати_елемент);
            вихід_позиції_помилки::вміст = позиція_помилки_молекули_хвоста;
            вернути ні;
          }
        }

        звільнити(М, сполука_ключа);
        звільнити(М, сполука_отримати_елемент);
        вихід_позиції_помилки::вміст = п;
        вернути ні;
      } інакше якщо знаки.дані[п].вид == ВидЗнакуСимволВідкритаДужка { // виконати дію
        п += 1;

        зʼїсти_міжрядки(знаки, п, п::адреса);

        змінна аргументи = зробити_накопичувач<Аргумент>(М, 0);
        якщо знаки.дані[п].вид == ВидЗнакуСимволЗакритаДужка {
          п += 1;
          стрибнути виклик__хвіст;
        }

        поки п < знаки.розмір {
          змінна аргумент = Аргумент { ... };
          змінна позиція_помилки_аргумента: природне = 0;
          якщо спробувати_розібрати_аргумент(М, знаки, п, аргумент::адреса, п::адреса, позиція_помилки_аргумента::адреса) {
            аргументи.покласти(М, аргумент);

            п += 1;

            зʼїсти_міжрядки(знаки, п, п::адреса);

            якщо знаки.дані[п].вид == ВидЗнакуСимволЗакритаДужка {
              п += 1;
              стрибнути виклик__хвіст;
            } інакше якщо знаки.дані[п].вид == ВидЗнакуСимволКома {
              п += 1;
              зʼїсти_міжрядки(знаки, п, п::адреса);
              якщо знаки.дані[п].вид == ВидЗнакуСимволЗакритаДужка {
                п += 1;
                стрибнути виклик__хвіст;
              }
            } інакше {
              звільнити_аргументи(М, аргументи.розмір, аргументи.дані);
              вихід_позиції_помилки::вміст = п;
              вернути ні;
            }
          } інакше {
            звільнити_аргументи(М, аргументи.розмір, аргументи.дані);
            вихід_позиції_помилки::вміст = позиція_помилки_аргумента;
            вернути ні;
          }
        }

        якщо знаки.дані[п].вид == ВидЗнакуСимволЗакритаДужка {
          п += 1;

    виклик__хвіст:
          змінна сполука_виконати = виділити<Сполука>(М, 1);
          сполука_виконати.вид = ВидСполукиВиконати;
          сполука_виконати.дані = ДаніСполукиВиконати {
            предмет = сполука_атома,
            кількість_аргументів = аргументи.розмір,
            аргументи = аргументи.дані,
          };
          сполука_виконати.місцезнаходження = Місцезнаходження { позиція_початку_молекули };

          змінна позиція_помилки_молекули_хвоста: природне = 0;
          якщо спробувати_розібрати_молекулу__хвіст(М, знаки, п, позиція_початку_молекули, вихід, вихід_позиції_кінця, сполука_виконати, позиція_помилки_молекули_хвоста::адреса) {
            вернути так;
          } інакше {
            звільнити_аргументи(М, аргументи.розмір, аргументи.дані);
            вихід_позиції_помилки::вміст = позиція_помилки_молекули_хвоста;
            вернути ні;
          }
        }

        звільнити_аргументи(М, аргументи.розмір, аргументи.дані);
        вихід_позиції_помилки::вміст = п;
        вернути ні;
      }

      вихід::вміст = сполука_атома;
      вихід_позиції_кінця::вміст = п - 1;
      вернути так;
    }

    внутрішня дія спробувати_розібрати_мікрооперацію(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
      змінна п = позиція_початку;

      змінна сполука_молекули: *Сполука = пусто;
      змінна позиція_помилки_молекули: природне = 0;
      якщо спробувати_розібрати_молекулу(М, знаки, п, сполука_молекули::адреса, п::адреса, позиція_помилки_молекули::адреса) {
        п += 1;

        якщо знаки.дані[п].вид == ВидЗнакуСимволКрапка {
          п += 1;

          якщо знаки.дані[п].вид == ВидЗнакуСимволКрапка {
            п += 1;

            змінна включно = ні;
            якщо знаки.дані[п].вид == ВидЗнакуСимволРівно {
              включно = так;
              п += 1;
            }

            змінна сполука_молекули_право: *Сполука = пусто;
            змінна позиція_помилки_молекули_право: природне = 0;
            якщо спробувати_розібрати_молекулу(М, знаки, п, сполука_молекули_право::адреса, п::адреса, позиція_помилки_молекули_право::адреса) {
              змінна сполука_проміжок = виділити<Сполука>(М, 1);
              сполука_проміжок.вид = ВидСполукиПроміжок;
              сполука_проміжок.дані = ДаніСполукиПроміжок {
                від = сполука_молекули,
                до = сполука_молекули_право,
                включно = включно
              };
              сполука_проміжок.місцезнаходження = Місцезнаходження { позиція_початку };
              вихід::вміст = сполука_проміжок;
              вихід_позиції_кінця::вміст = п;
              вернути так;
            } інакше {
              вихід_позиції_помилки::вміст = позиція_помилки_молекули_право;
              вернути ні;
            }
          } інакше {
            вихід::вміст = сполука_молекули;
            вихід_позиції_кінця::вміст = п - 2;
            вернути так;
          }
        } інакше {
          вихід::вміст = сполука_молекули;
          вихід_позиції_кінця::вміст = п - 1;
          вернути так;
        }
      }

      змінна позиція_помилки: природне = позиція_помилки_молекули;
      змінна найдовша_позиція_помилки: природне = позиція_помилки;

      якщо спробувати_розібрати_заперечення(М, знаки, позиція_початку, вихід, вихід_позиції_кінця, позиція_помилки::адреса) {
        вернути так;
      }
      якщо позиція_помилки > найдовша_позиція_помилки {
        найдовша_позиція_помилки = позиція_помилки;
      }

      якщо спробувати_розібрати_двійкове_заперечення(М, знаки, позиція_початку, вихід, вихід_позиції_кінця, позиція_помилки::адреса) {
        вернути так;
      }
      якщо позиція_помилки > найдовша_позиція_помилки {
        найдовша_позиція_помилки = позиція_помилки;
      }

      якщо спробувати_розібрати_префікс_плюс(М, знаки, позиція_початку, вихід, вихід_позиції_кінця, позиція_помилки::адреса) {
        вернути так;
      }
      якщо позиція_помилки > найдовша_позиція_помилки {
        найдовша_позиція_помилки = позиція_помилки;
      }

      якщо спробувати_розібрати_префікс_мінус(М, знаки, позиція_початку, вихід, вихід_позиції_кінця, позиція_помилки::адреса) {
        вернути так;
      }
      якщо позиція_помилки > найдовша_позиція_помилки {
        найдовша_позиція_помилки = позиція_помилки;
      }

      якщо спробувати_розібрати_чекати(М, знаки, позиція_початку, вихід, вихід_позиції_кінця, позиція_помилки::адреса) {
        вернути так;
      }
      якщо позиція_помилки > найдовша_позиція_помилки {
        найдовша_позиція_помилки = позиція_помилки;
      }

      вихід_позиції_помилки::вміст = найдовша_позиція_помилки;
      вернути ні;
    }

    внутрішня дія спробувати_розібрати_операцію(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, в_гнізді: логічне, вихід_позиції_помилки: *природне) -> логічне {
      змінна п = позиція_початку;

      змінна сполука_ліво: *Сполука = пусто;
      змінна позиція_помилки_ліво: природне = 0;
      якщо спробувати_розібрати_мікрооперацію(М, знаки, п, сполука_ліво::адреса, п::адреса, позиція_помилки_ліво::адреса) {
        п += 1;

        змінна сполука_результату: *Сполука = пусто;
        змінна позиція_помилки_сполуки_результату: природне = 0;
        якщо спробувати_розібрати_операцію_1(М, знаки, п, сполука_результату::адреса, п::адреса, сполука_ліво, 0, в_гнізді, позиція_помилки_сполуки_результату::адреса) {
          вихід::вміст = сполука_результату;
          вихід_позиції_кінця::вміст = п;
          вернути так;
        } інакше {
          вихід::вміст = сполука_ліво;
          вихід_позиції_кінця::вміст = п - 1;
          вернути так;
        }
      } інакше {
        вихід_позиції_помилки::вміст = позиція_помилки_ліво;
        стрибнути звільнити_і_вийти;
      }

    звільнити_і_вийти:
      звільнити_сполуку(М, сполука_ліво);
      вернути ні;
    }

    структура ІнформаціяОперації {
      вид_операції: природне;
      кількість_слів: природне;
      пріоритет: природне;
    }

    внутрішня дія дізнатись_інформацію_операції(знаки: Знаки, позиція: природне) -> ІнформаціяОперації {
      якщо знаки.дані[позиція].вид == ВидЗнакуКІНЕЦЬСЛІВ {
        вернути ІнформаціяОперації { 0, 0, 0 };
      }

      змінна вид = знаки.дані[позиція].вид;
      змінна вид_далі = знаки.дані[позиція + 1].вид;

      якщо вид == ВидЗнакуСимволПлюс {
        вернути ІнформаціяОперації { ВидОпераціїДодавання, 1, 97 };
      }

      якщо вид == ВидЗнакуСимволМінус {
        вернути ІнформаціяОперації { ВидОпераціїВіднімання, 1, 97 };
      }

      якщо вид == ВидЗнакуСимволПомножити {
        якщо вид_далі == ВидЗнакуСимволПомножити {
          вернути ІнформаціяОперації { ВидОпераціїПіднесенняДоСтепеня, 2, 100 };
        }

        вернути ІнформаціяОперації { ВидОпераціїМноження, 1, 98 };
      }

      якщо вид == ВидЗнакуСимволПоділити {
        якщо вид_далі == ВидЗнакуСимволПоділити {
          вернути ІнформаціяОперації { ВидОпераціїДіленняНаціло, 2, 99 };
        }

        вернути ІнформаціяОперації { ВидОпераціїДілення, 1, 98 };
      }

      якщо вид == ВидЗнакуСимволЗалишку {
        вернути ІнформаціяОперації { ВидОпераціїМодуль, 1, 98 };
      }

      якщо вид == ВидЗнакуСимволБільше {
        якщо вид_далі == ВидЗнакуСимволБільше {
          якщо знаки.дані[позиція + 2].вид == ВидЗнакуСимволБільше {
            вернути ІнформаціяОперації { ВидОпераціїЗсувВправоЗнаковий, 3, 96 };
          }

          вернути ІнформаціяОперації { ВидОпераціїЗсувВправо, 2, 96 };
        }

        якщо вид_далі == ВидЗнакуСимволРівно {
          вернути ІнформаціяОперації { ВидОпераціїБільшеРівне, 2, 95 };
        }

        вернути ІнформаціяОперації { ВидОпераціїБільше, 1, 95 };
      }

      якщо вид == ВидЗнакуСимволМенше {
        якщо вид_далі == ВидЗнакуСимволМенше {
          вернути ІнформаціяОперації { ВидОпераціїЗсувВліво, 2, 96 };
        }

        якщо вид_далі == ВидЗнакуСимволРівно {
          вернути ІнформаціяОперації { ВидОпераціїМеншеРівне, 2, 95 };
        }

        вернути ІнформаціяОперації { ВидОпераціїМенше, 1, 95 };
      }

      якщо вид == ВидЗнакуБільше {
        вернути ІнформаціяОперації { ВидОпераціїБільше, 1, 95 };
      }

      якщо вид == ВидЗнакуМенше {
        вернути ІнформаціяОперації { ВидОпераціїМенше, 1, 95 };
      }

      якщо вид == ВидЗнакуЄ {
        вернути ІнформаціяОперації { ВидОпераціїЄ, 1, 93 };
      }

      якщо вид == ВидЗнакуНе {
        якщо вид_далі == ВидЗнакуБільше {
          вернути ІнформаціяОперації { ВидОпераціїМеншеРівне, 2, 95 };
        }

        якщо вид_далі == ВидЗнакуМенше {
          вернути ІнформаціяОперації { ВидОпераціїБільшеРівне, 2, 95 };
        }

        якщо вид_далі == ВидЗнакуРівно {
          вернути ІнформаціяОперації { ВидОпераціїНерівне, 2, 94 };
        }

        якщо вид_далі == ВидЗнакуЄ {
          вернути ІнформаціяОперації { ВидОпераціїНеЄ, 2, 93 };
        }
      }

      якщо вид == ВидЗнакуСимволЗнакОклику {
        якщо вид_далі == ВидЗнакуСимволРівно {
          вернути ІнформаціяОперації { ВидОпераціїНерівне, 2, 94 };
        }
      }

      якщо вид == ВидЗнакуСимволРівно {
        якщо вид_далі == ВидЗнакуСимволРівно {
          вернути ІнформаціяОперації { ВидОпераціїРівне, 2, 94 };
        }
      }

      якщо вид == ВидЗнакуРівно {
        вернути ІнформаціяОперації { ВидОпераціїРівне, 1, 94 };
      }

      якщо вид == ВидЗнакуСимволІ {
        якщо вид_далі == ВидЗнакуСимволІ {
          вернути ІнформаціяОперації { ВидОпераціїІ, 2, 89 };
        }

        вернути ІнформаціяОперації { ВидОпераціїДІ, 1, 92 };
      }

      якщо вид == ВидЗнакуІ {
        вернути ІнформаціяОперації { ВидОпераціїІ, 1, 89 };
      }

      якщо вид == ВидЗнакуСимволВиключнеАбо {
        вернути ІнформаціяОперації { ВидОпераціїВАБО, 1, 91 };
      }

      якщо вид == ВидЗнакуСимволАбо {
        якщо вид_далі == ВидЗнакуСимволАбо {
          вернути ІнформаціяОперації { ВидОпераціїАБО, 2, 88 };
        }

        вернути ІнформаціяОперації { ВидОпераціїДАБО, 1, 90 };
      }

      якщо вид == ВидЗнакуАбо {
        вернути ІнформаціяОперації { ВидОпераціїАБО, 1, 88 };
      }

      вернути ІнформаціяОперації { 0, 0, 0 };
    }

    внутрішня дія перевірити_оп1(інформація_операції: ІнформаціяОперації, мін: природне) -> логічне {
      якщо інформація_операції.вид_операції == 0 {
        вернути ні;
      }

      якщо інформація_операції.пріоритет >= мін {
        вернути так;
      }

      вернути ні;
    }

    внутрішня дія перевірити_оп2(інформація_операції: ІнформаціяОперації, збережена_інформація_операції: ІнформаціяОперації) -> логічне {
      якщо інформація_операції.вид_операції == 0 {
        вернути ні;
      }

      якщо інформація_операції.пріоритет > збережена_інформація_операції.пріоритет {
        вернути так;
      }

      якщо інформація_операції.вид_операції == ВидОпераціїПіднесенняДоСтепеня {
        вернути інформація_операції.пріоритет == збережена_інформація_операції.пріоритет;
      }

      вернути ні;
    }

    внутрішня дія спробувати_розібрати_операцію_1(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, сполука_ліво: *Сполука, мін: природне, в_гнізді: логічне, вихід_позиції_помилки: *природне) -> логічне {
      змінна п = позиція_початку;
      змінна має_міжряд = ні;

      якщо в_гнізді == так {
        якщо знаки.дані[п].вид == ВидЗнакуСимволМіжряд {
          має_міжряд = так;
          п += 1;
        }
      }

      змінна інформація_операції = дізнатись_інформацію_операції(знаки, п);

      поки перевірити_оп1(інформація_операції, мін) {
        має_міжряд = ні;

        змінна збережена_інформація_операції = інформація_операції;

        п += інформація_операції.кількість_слів;

        якщо в_гнізді == так {
          зʼїсти_міжрядки(знаки, п, п::адреса);
        }

        змінна сполука_право: *Сполука = пусто;
        змінна позиція_помилки_право: природне = 0;
        якщо спробувати_розібрати_мікрооперацію(М, знаки, п, сполука_право::адреса, п::адреса, позиція_помилки_право::адреса) {
          п += 1;

          якщо в_гнізді == так {
            зʼїсти_міжрядки(знаки, п, п::адреса);
          }

          інформація_операції = дізнатись_інформацію_операції(знаки, п);

          поки перевірити_оп2(інформація_операції, збережена_інформація_операції) {
            змінна рсп = ні;
            змінна позиція_помилки_рсп: природне = 0;

            якщо інформація_операції.пріоритет > збережена_інформація_операції.пріоритет {
              рсп = спробувати_розібрати_операцію_1(М, знаки, п, сполука_право::адреса, п::адреса, сполука_право, збережена_інформація_операції.пріоритет + 1, в_гнізді, позиція_помилки_рсп::адреса);
            } інакше {
              рсп = спробувати_розібрати_операцію_1(М, знаки, п, сполука_право::адреса, п::адреса, сполука_право, збережена_інформація_операції.пріоритет, в_гнізді, позиція_помилки_рсп::адреса);
            }

            якщо рсп {
              п += 1;
            } інакше {
              звільнити_сполуку(М, сполука_право);
              вихід_позиції_помилки::вміст = позиція_помилки_рсп;
              вернути ні;
            }

            інформація_операції = дізнатись_інформацію_операції(знаки, п);
          }

          змінна нова_сполука_ліво = виділити<Сполука>(М, 1);
          нова_сполука_ліво.вид = ВидСполукиОперація;
          нова_сполука_ліво.дані = ДаніСполукиОперація {
            ліво = сполука_ліво,
            операція = збережена_інформація_операції.вид_операції,
            право = сполука_право,
          };

          нова_сполука_ліво.місцезнаходження = Місцезнаходження { позиція_початку };
          сполука_ліво = нова_сполука_ліво;

          якщо в_гнізді == так {
            якщо знаки.дані[п].вид == ВидЗнакуСимволМіжряд {
              має_міжряд = так;
              п += 1;
            }
          }

          інформація_операції = дізнатись_інформацію_операції(знаки, п);
        } інакше {
          вихід_позиції_помилки::вміст = позиція_помилки_право;
          вернути ні;
        }
      }

      вихід::вміст = сполука_ліво;

      якщо має_міжряд {
        вихід_позиції_кінця::вміст = п - 2;
      } інакше {
        вихід_позиції_кінця::вміст = п - 1;
      }

      вернути так;
    }

    внутрішня дія спробувати_розібрати_значення(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, в_гнізді: логічне, вихід_позиції_помилки: *природне) -> логічне {
      змінна найдовша_позиція_помилки: природне = 0;
      змінна позиція_помилки: природне = 0;

      якщо спробувати_розібрати_дію(М, знаки, позиція_початку, вихід, вихід_позиції_кінця, позиція_помилки::адреса) {
        вернути так;
      }
      якщо позиція_помилки > найдовша_позиція_помилки {
        найдовша_позиція_помилки = позиція_помилки;
      }

      якщо спробувати_розібрати_клас(М, знаки, позиція_початку, вихід, вихід_позиції_кінця, позиція_помилки::адреса) {
        вернути так;
      }
      якщо позиція_помилки > найдовша_позиція_помилки {
        найдовша_позиція_помилки = позиція_помилки;
      }

      якщо спробувати_розібрати_модуль(М, знаки, позиція_початку, вихід, вихід_позиції_кінця, позиція_помилки::адреса) {
        вернути так;
      }
      якщо позиція_помилки > найдовша_позиція_помилки {
        найдовша_позиція_помилки = позиція_помилки;
      }

      змінна п = позиція_початку;

      змінна сполука_операція: *Сполука = пусто;
      змінна позиція_кінця_сполуки_операція: природне = 0;
      якщо спробувати_розібрати_операцію(М, знаки, п, сполука_операція::адреса, позиція_кінця_сполуки_операція::адреса, в_гнізді, позиція_помилки::адреса) {
        п = позиція_кінця_сполуки_операція;
        п += 1;

        якщо знаки.дані[п].вид == ВидЗнакуЯкщо {
          п += 1;

          змінна сполука_операція_значення: *Сполука = пусто;
          якщо спробувати_розібрати_операцію(М, знаки, п, сполука_операція_значення::адреса, п::адреса, в_гнізді, позиція_помилки::адреса) {
            п += 1;

            якщо знаки.дані[п].вид == ВидЗнакуІнакше {
              п += 1;

              змінна сполука_операція_значення_інакше: *Сполука = пусто;
              якщо спробувати_розібрати_операцію(М, знаки, п, сполука_операція_значення_інакше::адреса, п::адреса, в_гнізді, позиція_помилки::адреса) {
                змінна сполука_значення_якщо = виділити<Сполука>(М, 1);
                сполука_значення_якщо.вид = ВидСполукиЗначенняЯкщо;
                сполука_значення_якщо.дані = ДаніСполукиЗначенняЯкщо {
                  умова = сполука_операція_значення,
                  значення_так = сполука_операція,
                  значення_ні = сполука_операція_значення_інакше,
                };
                сполука_значення_якщо.місцезнаходження = Місцезнаходження { позиція_початку };
                вихід::вміст = сполука_значення_якщо;
                вихід_позиції_кінця::вміст = п;
                вернути так;
              } інакше {
                звільнити_сполуку(М, сполука_операція);
                звільнити_сполуку(М, сполука_операція_значення);
                якщо позиція_помилки > найдовша_позиція_помилки {
                  найдовша_позиція_помилки = позиція_помилки;
                }
                вихід_позиції_помилки::вміст = найдовша_позиція_помилки;
                вернути ні;
              }
            } інакше {
              звільнити_сполуку(М, сполука_операція);
              звільнити_сполуку(М, сполука_операція_значення);
              вихід_позиції_помилки::вміст = п;
              вернути ні;
            }
          } інакше {
            звільнити_сполуку(М, сполука_операція);
            якщо позиція_помилки > найдовша_позиція_помилки {
              найдовша_позиція_помилки = позиція_помилки;
            }
            вихід_позиції_помилки::вміст = найдовша_позиція_помилки;
            вернути ні;
          }
        } інакше {
          п -= 1;
        }

        вихід::вміст = сполука_операція;
        вихід_позиції_кінця::вміст = позиція_кінця_сполуки_операція;
        вернути так;
      }

      якщо позиція_помилки > найдовша_позиція_помилки {
        найдовша_позиція_помилки = позиція_помилки;
      }

      вихід_позиції_помилки::вміст = найдовша_позиція_помилки;
      вернути ні;
    }

    внутрішня дія спробувати_розібрати_вернути(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
      змінна п = позиція_початку;

      якщо знаки.дані[п].вид != ВидЗнакуВернути {
        вихід_позиції_помилки::вміст = п;
        вернути ні;
      }
      п += 1;

      змінна сполука_значення: *Сполука = пусто;
      змінна позиція_помилки_сполуки_значення: природне = 0;
      якщо не спробувати_розібрати_значення(М, знаки, п, сполука_значення::адреса, п::адреса, ні, позиція_помилки_сполуки_значення::адреса) {
        п -= 1;
      }

      змінна сполука_вернути = виділити<Сполука>(М, 1);
      сполука_вернути.вид = ВидСполукиВернути;
      сполука_вернути.дані = ДаніСполукиВернути {
        значення = сполука_значення
      };
      сполука_вернути.місцезнаходження = Місцезнаходження { позиція_початку };
      вихід::вміст = сполука_вернути;
      вихід_позиції_кінця::вміст = п;
      вернути так;
    }

    внутрішня дія спробувати_розібрати_перестрибнути(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
      змінна п = позиція_початку;

      якщо знаки.дані[п].вид != ВидЗнакуПерестрибнути {
        вихід_позиції_помилки::вміст = п;
        вернути ні;
      }

      змінна сполука_перестрибнути = виділити<Сполука>(М, 1);
      сполука_перестрибнути.вид = ВидСполукиПерестрибнути;
      сполука_перестрибнути.дані = ДаніСполукиПерестрибнути {
        ідентифікатор = можливо<Ідентифікатор> { ні, ... },
      };
      сполука_перестрибнути.місцезнаходження = Місцезнаходження { позиція_початку };
      вихід::вміст = сполука_перестрибнути;
      вихід_позиції_кінця::вміст = п;
      вернути так;
    }

    внутрішня дія спробувати_розібрати_передати(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
      змінна п = позиція_початку;

      якщо знаки.дані[п].вид != ВидЗнакуПередати {
        вихід_позиції_помилки::вміст = п;
        вернути ні;
      }
      п += 1;

      змінна сполука_значення: *Сполука = пусто;
      змінна позиція_помилки_сполуки_значення: природне = 0;
      якщо не спробувати_розібрати_значення(М, знаки, п, сполука_значення::адреса, п::адреса, ні, позиція_помилки_сполуки_значення::адреса) {
        п -= 1;
      }

      змінна сполука_передати = виділити<Сполука>(М, 1);
      сполука_передати.вид = ВидСполукиПередати;
      сполука_передати.дані = ДаніСполукиПередати {
        значення = сполука_значення,
      };
      сполука_передати.місцезнаходження = Місцезнаходження { позиція_початку };
      вихід::вміст = сполука_передати;
      вихід_позиції_кінця::вміст = п;
      вернути так;
    }

    внутрішня дія спробувати_розібрати_перервати(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
      змінна п = позиція_початку;

      якщо знаки.дані[п].вид != ВидЗнакуПерервати {
        вихід_позиції_помилки::вміст = п;
        вернути ні;
      }

      змінна сполука_перервати = виділити<Сполука>(М, 1);
      сполука_перервати.вид = ВидСполукиПерервати;
      сполука_перервати.місцезнаходження = Місцезнаходження { позиція_початку };
      вихід::вміст = сполука_перервати;
      вихід_позиції_кінця::вміст = п;
      вернути так;
    }

    внутрішня дія спробувати_розібрати_впасти(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
      змінна п = позиція_початку;

      якщо знаки.дані[п].вид != ВидЗнакуВпасти {
        вихід_позиції_помилки::вміст = п;
        вернути ні;
      }
      п += 1;

      змінна сполука_значення: *Сполука = пусто;
      змінна позиція_помилки_сполуки_значення: природне = 0;
      якщо не спробувати_розібрати_значення(М, знаки, п, сполука_значення::адреса, п::адреса, ні, позиція_помилки_сполуки_значення::адреса) {
        п -= 1;
      }

      змінна сполука_впасти = виділити<Сполука>(М, 1);
      сполука_впасти.вид = ВидСполукиВпасти;
      сполука_впасти.дані = ДаніСполукиВпасти {
        значення = сполука_значення
      };
      сполука_впасти.місцезнаходження = Місцезнаходження { позиція_початку };
      вихід::вміст = сполука_впасти;
      вихід_позиції_кінця::вміст = п;
      вернути так;
    }

    внутрішня дія спробувати_розібрати_елемент_взяти(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: *ЕлементВзяти, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
      змінна п = позиція_початку;

      змінна позиція_ідентифікатора = п;
      якщо знаки.дані[п].вид != ВидЗнакуІдентифікатор {
        вихід_позиції_помилки::вміст = п;
        вернути ні;
      }
      п += 1;

      змінна має_ідентифікатор_як = ні;
      змінна позиція_ідентифікатора_як = п + 1;
      якщо знаки.дані[п].вид == ВидЗнакуЯк {
        п += 1;

        якщо знаки.дані[п].вид != ВидЗнакуІдентифікатор {
          вихід_позиції_помилки::вміст = п;
          вернути ні;
        }

        має_ідентифікатор_як = так;
        позиція_ідентифікатора_як = п;
      } інакше {
        п -= 1;
      }

      вихід::вміст = ЕлементВзяти {
        ідентифікатор = Ідентифікатор { позиція_ідентифікатора },
        ідентифікатор_як = можливо<Ідентифікатор> { має_ідентифікатор_як, Ідентифікатор { позиція_ідентифікатора_як } },
        місцезнаходження = Місцезнаходження { позиція_початку }
      };

      вихід_позиції_кінця::вміст = п;
      вернути так;
    }

    внутрішня дія спробувати_розібрати_взяти(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
      змінна п = позиція_початку;

      змінна шлях = зробити_накопичувач<Ідентифікатор>(М, 0);
      якщо знаки.дані[п].вид != ВидЗнакуВзяти {
        шлях.звільнити_дані(М);
        вихід_позиції_помилки::вміст = п;
        вернути ні;
      }

      п += 1;
      змінна позиція_виду_взяти = п;
      змінна відносно = ні;
      якщо знаки.дані[п].вид == ВидЗнакуМодуль {
        п += 1;

        якщо знаки.дані[п].вид == ВидЗнакуСимволКрапка {
          відносно = так;

          п += 1;
        }
      } інакше якщо знаки.дані[п].вид == ВидЗнакуІдентифікатор {
        п += 1;
      } інакше {
        шлях.звільнити_дані(М);
        вихід_позиції_помилки::вміст = п;
        вернути ні;
      }

      поки п < знаки.розмір {
        якщо знаки.дані[п].вид == ВидЗнакуІдентифікатор {
          шлях.покласти(М, Ідентифікатор { п });
          п += 1;
          якщо знаки.дані[п].вид == ВидЗнакуСимволКрапка {
            п += 1;
          } інакше {
            стрибнути після_шляху;
          }
        } інакше {
        шлях.звільнити_дані(М);
        вихід_позиції_помилки::вміст = п;
          вернути ні;
        }
      }

    після_шляху:
      якщо знаки.дані[п].вид == ВидЗнакуЯк {
        п += 1;

        змінна ідентифікатор_як = п;
        якщо знаки.дані[п].вид != ВидЗнакуІдентифікатор {
          шлях.звільнити_дані(М);
          вихід_позиції_помилки::вміст = п;
          вернути ні;
        }

        змінна сполука_взяти = виділити<Сполука>(М, 1);
        сполука_взяти.вид = ВидСполукиВзяти;
        сполука_взяти.дані = ДаніСполукиВзяти {
          тип = можливо<Ідентифікатор> { так, Ідентифікатор { позиція_виду_взяти } },
          відносно = відносно,
          довжина_шляху = шлях.розмір,
          шлях = шлях.дані,
          ідентифікатор_як = можливо<Ідентифікатор> { так, Ідентифікатор { ідентифікатор_як } },
          кількість_елементів = 0,
          елементи = пусто
        };
        сполука_взяти.місцезнаходження = Місцезнаходження { позиція_початку };
        вихід::вміст = сполука_взяти;
        вихід_позиції_кінця::вміст = п;
        вернути так;
      } інакше якщо знаки.дані[п].вид == ВидЗнакуСимволКвадратнаВідкритаДужка {
        п += 1;

        змінна елементи = зробити_накопичувач<ЕлементВзяти>(М, 0);
        поки п < знаки.розмір {
          змінна елемент_взяти = ЕлементВзяти { ... };
          змінна позиція_помилки_елемента_взяти: природне = 0;
          якщо спробувати_розібрати_елемент_взяти(М, знаки, п, елемент_взяти::адреса, п::адреса, позиція_помилки_елемента_взяти::адреса) {
            елементи.покласти(М, елемент_взяти);
            п += 1;
            якщо знаки.дані[п].вид == ВидЗнакуСимволКома {
              п += 1;
            } інакше якщо знаки.дані[п].вид == ВидЗнакуСимволКвадратнаЗакритаДужка {
              змінна сполука_взяти = виділити<Сполука>(М, 1);
              сполука_взяти.вид = ВидСполукиВзяти;
              сполука_взяти.дані = ДаніСполукиВзяти {
                тип = можливо<Ідентифікатор> { так, Ідентифікатор { позиція_виду_взяти } },
                відносно = відносно,
                довжина_шляху = шлях.розмір,
                шлях = шлях.дані,
                ідентифікатор_як = можливо<Ідентифікатор> { ні, ... },
                кількість_елементів = елементи.розмір,
                елементи = елементи.дані
              };
              сполука_взяти.місцезнаходження = Місцезнаходження { позиція_початку };
              вихід::вміст = сполука_взяти;
              вихід_позиції_кінця::вміст = п;
              вернути так;
            } інакше {
              шлях.звільнити_дані(М);
              елементи.звільнити_дані(М);
              вихід_позиції_помилки::вміст = п;
              вернути ні;
            }
          } інакше {
            шлях.звільнити_дані(М);
            елементи.звільнити_дані(М);
            вихід_позиції_помилки::вміст = позиція_помилки_елемента_взяти;
            вернути ні;
          }
        }

        шлях.звільнити_дані(М);
        елементи.звільнити_дані(М);
        вихід_позиції_помилки::вміст = п;
        вернути ні;
      } інакше {
        змінна сполука_взяти = виділити<Сполука>(М, 1);
        сполука_взяти.вид = ВидСполукиВзяти;
        сполука_взяти.дані = ДаніСполукиВзяти {
          тип = можливо<Ідентифікатор> { так, Ідентифікатор { позиція_виду_взяти } },
          відносно = відносно,
          довжина_шляху = шлях.розмір,
          шлях = шлях.дані,
          ідентифікатор_як = можливо<Ідентифікатор> { ні, ... },
          кількість_елементів = 0,
          елементи = пусто
        };
        сполука_взяти.місцезнаходження = Місцезнаходження { позиція_початку };
        вихід::вміст = сполука_взяти;
        вихід_позиції_кінця::вміст = п - 1;
        вернути так;
      }

      шлях.звільнити_дані(М);
      вихід_позиції_помилки::вміст = п;
      вернути ні;
    }

    внутрішня дія спробувати_розібрати_елемент_дати(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: *ЕлементДати, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
      змінна п = позиція_початку;

      змінна позиція_ідентифікатора = п;
      якщо знаки.дані[п].вид != ВидЗнакуІдентифікатор {
        вихід_позиції_помилки::вміст = п;
        вернути ні;
      }
      п += 1;

      змінна має_ідентифікатор_як = ні;
      змінна позиція_ідентифікатора_як = п + 1;
      якщо знаки.дані[п].вид == ВидЗнакуЯк {
        п += 1;

        якщо знаки.дані[п].вид != ВидЗнакуІдентифікатор {
          вихід_позиції_помилки::вміст = п;
          вернути ні;
        }

        має_ідентифікатор_як = так;
        позиція_ідентифікатора_як = п;
      } інакше {
        п -= 1;
      }

      вихід::вміст = ЕлементДати {
        ідентифікатор = Ідентифікатор { позиція_ідентифікатора },
        ідентифікатор_як = можливо<Ідентифікатор> { має_ідентифікатор_як, Ідентифікатор { позиція_ідентифікатора_як } },
        місцезнаходження = Місцезнаходження { позиція_початку }
      };

      вихід_позиції_кінця::вміст = п;
      вернути так;
    }

    внутрішня дія спробувати_розібрати_дати(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
      змінна п = позиція_початку;

      якщо знаки.дані[п].вид != ВидЗнакуДати {
        вихід_позиції_помилки::вміст = п;
        вернути ні;
      }

      п += 1;

      змінна елементи = зробити_накопичувач<ЕлементДати>(М, 0);
      поки п < знаки.розмір {
        змінна елемент_дати = ЕлементДати { ... };
        змінна позиція_помилки_елемента_дати: природне = 0;
        якщо спробувати_розібрати_елемент_дати(М, знаки, п, елемент_дати::адреса, п::адреса, позиція_помилки_елемента_дати::адреса) {
          елементи.покласти(М, елемент_дати);
          п += 1;
          якщо знаки.дані[п].вид == ВидЗнакуСимволКома {
            п += 1;
          } інакше {
            п -= 1;
            стрибнути завершення;
          }
        } інакше {
          елементи.звільнити_дані(М);
          вихід_позиції_помилки::вміст = позиція_помилки_елемента_дати;
          вернути ні;
        }
      }

    завершення:
      змінна сполука_дати = виділити<Сполука>(М, 1);
      сполука_дати.вид = ВидСполукиДати;
      сполука_дати.дані = ДаніСполукиДати {
        кількість_елементів = елементи.розмір,
        елементи = елементи.дані
      };
      сполука_дати.місцезнаходження = Місцезнаходження { позиція_початку };
      вихід::вміст = сполука_дати;
      вихід_позиції_кінця::вміст = п;
      вернути так;
    }

    внутрішня дія спробувати_розібрати_елемент_тіла(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
      змінна позиція_помилки: природне = 0;
      змінна найдовша_позиція_помилки: природне = 0;

      якщо спробувати_розібрати_передати(М, знаки, позиція_початку, вихід, вихід_позиції_кінця, позиція_помилки::адреса) {
        вернути так;
      }
      якщо позиція_помилки > найдовша_позиція_помилки {
        найдовша_позиція_помилки = позиція_помилки;
      }

      якщо спробувати_розібрати_перервати(М, знаки, позиція_початку, вихід, вихід_позиції_кінця, позиція_помилки::адреса) {
        вернути так;
      }
      якщо позиція_помилки > найдовша_позиція_помилки {
        найдовша_позиція_помилки = позиція_помилки;
      }

      якщо спробувати_розібрати_перестрибнути(М, знаки, позиція_початку, вихід, вихід_позиції_кінця, позиція_помилки::адреса) {
        вернути так;
      }
      якщо позиція_помилки > найдовша_позиція_помилки {
        найдовша_позиція_помилки = позиція_помилки;
      }

      якщо спробувати_розібрати_вернути(М, знаки, позиція_початку, вихід, вихід_позиції_кінця, позиція_помилки::адреса) {
        вернути так;
      }
      якщо позиція_помилки > найдовша_позиція_помилки {
        найдовша_позиція_помилки = позиція_помилки;
      }

      якщо спробувати_розібрати_впасти(М, знаки, позиція_початку, вихід, вихід_позиції_кінця, позиція_помилки::адреса) {
        вернути так;
      }
      якщо позиція_помилки > найдовша_позиція_помилки {
        найдовша_позиція_помилки = позиція_помилки;
      }

      якщо спробувати_розібрати_взяти(М, знаки, позиція_початку, вихід, вихід_позиції_кінця, позиція_помилки::адреса) {
        вернути так;
      }
      якщо позиція_помилки > найдовша_позиція_помилки {
        найдовша_позиція_помилки = позиція_помилки;
      }

      якщо спробувати_розібрати_дати(М, знаки, позиція_початку, вихід, вихід_позиції_кінця, позиція_помилки::адреса) {
        вернути так;
      }
      якщо позиція_помилки > найдовша_позиція_помилки {
        найдовша_позиція_помилки = позиція_помилки;
      }

      якщо спробувати_розібрати_якщо(М, знаки, позиція_початку, вихід, вихід_позиції_кінця, позиція_помилки::адреса) {
        вернути так;
      }
      якщо позиція_помилки > найдовша_позиція_помилки {
        найдовша_позиція_помилки = позиція_помилки;
      }

      якщо спробувати_розібрати_поки(М, знаки, позиція_початку, вихід, вихід_позиції_кінця, позиція_помилки::адреса) {
        вернути так;
      }
      якщо позиція_помилки > найдовша_позиція_помилки {
        найдовша_позиція_помилки = позиція_помилки;
      }

      якщо спробувати_розібрати_перебрати(М, знаки, позиція_початку, вихід, вихід_позиції_кінця, позиція_помилки::адреса) {
        вернути так;
      }
      якщо позиція_помилки > найдовша_позиція_помилки {
        найдовша_позиція_помилки = позиція_помилки;
      }

      якщо спробувати_розібрати_спробувати(М, знаки, позиція_початку, вихід, вихід_позиції_кінця, позиція_помилки::адреса) {
        вернути так;
      }
      якщо позиція_помилки > найдовша_позиція_помилки {
        найдовша_позиція_помилки = позиція_помилки;
      }

      змінна п = позиція_початку;
      змінна сполука_значення: *Сполука = пусто;
      змінна позиція_помилки_сполуки_значення: природне = 0;
      якщо спробувати_розібрати_значення(М, знаки, п, сполука_значення::адреса, п::адреса, ні, позиція_помилки_сполуки_значення::адреса) {
        п += 1;
        змінна вид_операції: природне = 0;
        якщо знаки.дані[п].вид == ВидЗнакуСимволПлюс {
          п += 1;
          якщо знаки.дані[п].вид == ВидЗнакуСимволРівно {
            вид_операції = ВидОпераціїДодавання;
            стрибнути спроба2;
          } інакше {
            п -= 2;
            стрибнути вихід;
          }
        } інакше якщо знаки.дані[п].вид == ВидЗнакуСимволМінус {
          п += 1;
          якщо знаки.дані[п].вид == ВидЗнакуСимволРівно {
            вид_операції = ВидОпераціїВіднімання;
            стрибнути спроба2;
          } інакше {
            п -= 2;
            стрибнути вихід;
          }
        } інакше якщо знаки.дані[п].вид == ВидЗнакуСимволПомножити {
          п += 1;
          якщо знаки.дані[п].вид == ВидЗнакуСимволПомножити {
            п += 1;
            якщо знаки.дані[п].вид == ВидЗнакуСимволРівно {
              вид_операції = ВидОпераціїПіднесенняДоСтепеня;
              стрибнути спроба2;
            } інакше {
              п -= 3;
              стрибнути вихід;
            }
          } інакше якщо знаки.дані[п].вид == ВидЗнакуСимволРівно {
            вид_операції = ВидОпераціїМноження;
            стрибнути спроба2;
          } інакше {
            п -= 2;
            стрибнути вихід;
          }
        } інакше якщо знаки.дані[п].вид == ВидЗнакуСимволПоділити {
          п += 1;
          якщо знаки.дані[п].вид == ВидЗнакуСимволПоділити {
            п += 1;
            якщо знаки.дані[п].вид == ВидЗнакуСимволРівно {
              вид_операції = ВидОпераціїДіленняНаціло;
              стрибнути спроба2;
            } інакше {
              п -= 3;
              стрибнути вихід;
            }
          } інакше якщо знаки.дані[п].вид == ВидЗнакуСимволРівно {
            вид_операції = ВидОпераціїДілення;
            стрибнути спроба2;
          } інакше {
            п -= 2;
            стрибнути вихід;
          }
        } інакше якщо знаки.дані[п].вид == ВидЗнакуСимволЗалишку {
          п += 1;
          якщо знаки.дані[п].вид == ВидЗнакуСимволРівно {
            вид_операції = ВидОпераціїМодуль;
            стрибнути спроба2;
          } інакше {
            п -= 2;
            стрибнути вихід;
          }
        } інакше якщо знаки.дані[п].вид == ВидЗнакуСимволІ {
          п += 1;
          якщо знаки.дані[п].вид == ВидЗнакуСимволРівно {
            вид_операції = ВидОпераціїДІ;
            стрибнути спроба2;
          } інакше {
            п -= 2;
            стрибнути вихід;
          }
        } інакше якщо знаки.дані[п].вид == ВидЗнакуСимволАбо {
          п += 1;
          якщо знаки.дані[п].вид == ВидЗнакуСимволРівно {
            вид_операції = ВидОпераціїДАБО;
            стрибнути спроба2;
          } інакше {
            п -= 2;
            стрибнути вихід;
          }
        } інакше якщо знаки.дані[п].вид == ВидЗнакуСимволВиключнеАбо {
          п += 1;
          якщо знаки.дані[п].вид == ВидЗнакуСимволРівно {
            вид_операції = ВидОпераціїВАБО;
            стрибнути спроба2;
          } інакше {
            п -= 2;
            стрибнути вихід;
          }
        } інакше якщо знаки.дані[п].вид == ВидЗнакуСимволБільше {
          п += 1;
          якщо знаки.дані[п].вид == ВидЗнакуСимволБільше {
            п += 1;
            якщо знаки.дані[п].вид == ВидЗнакуСимволБільше {
              п += 1;
              якщо знаки.дані[п].вид == ВидЗнакуСимволРівно {
                вид_операції = ВидОпераціїЗсувВправоЗнаковий;
                стрибнути спроба2;
              } інакше {
                п -= 4;
                стрибнути вихід;
              }
            } інакше якщо знаки.дані[п].вид == ВидЗнакуСимволРівно {
              вид_операції = ВидОпераціїЗсувВправо;
              стрибнути спроба2;
            } інакше {
              п -= 3;
              стрибнути вихід;
            }
          } інакше {
            п -= 2;
            стрибнути вихід;
          }
        } інакше якщо знаки.дані[п].вид == ВидЗнакуСимволМенше {
          п += 1;
          якщо знаки.дані[п].вид == ВидЗнакуСимволМенше {
            п += 1;
            якщо знаки.дані[п].вид == ВидЗнакуСимволРівно {
              вид_операції = ВидОпераціїЗсувВліво;
              стрибнути спроба2;
            } інакше {
              п -= 3;
              стрибнути вихід;
            }
          } інакше {
            п -= 2;
            стрибнути вихід;
          }
        } інакше якщо знаки.дані[п].вид == ВидЗнакуСимволРівно {
          стрибнути спроба;
        } інакше якщо знаки.дані[п].вид == ВидЗнакуСимволДвокрапка {
          п += 1;
          якщо знаки.дані[п].вид == ВидЗнакуСимволРівно {
            стрибнути спроба_ззовні;
          } інакше {
            п -= 2;
            стрибнути вихід;
          }
          стрибнути спроба;
        } інакше {
          п -= 1;
          стрибнути вихід;
        }
        спроба:
        якщо сполука_значення.вид == ВидСполукиЗвернутись {
          змінна дані = сполука_значення.дані як ДаніСполукиЗвернутись;
          змінна ідентифікатор = дані.ідентифікатор;
          п += 1;
          змінна сполука_значення_значення: *Сполука = пусто;
          змінна позиція_помилки_сполуки_значення_значення: природне = 0;
          якщо спробувати_розібрати_значення(М, знаки, п, сполука_значення_значення::адреса, п::адреса, ні, позиція_помилки_сполуки_значення_значення::адреса) {
            змінна сполука_визначити = виділити<Сполука>(М, 1);
            сполука_визначити.вид = ВидСполукиВизначити;
            сполука_визначити.дані = ДаніСполукиВизначити {
              ідентифікатор = ідентифікатор,
              значення = сполука_значення_значення
            };
            сполука_визначити.місцезнаходження = сполука_значення.місцезнаходження;
            вихід::вміст = сполука_визначити;
            вихід_позиції_кінця::вміст = п;
            звільнити(М, сполука_значення);
            вернути так;
          } інакше {
            звільнити_сполуку(М, сполука_значення);
            вихід_позиції_помилки::вміст = позиція_помилки_сполуки_значення_значення;
            вернути ні;
          }
        } інакше якщо сполука_значення.вид == ВидСполукиОтриматиВластивість {
          змінна дані = сполука_значення.дані як ДаніСполукиОтриматиВластивість;
          змінна предмет = дані.предмет;
          змінна ідентифікатор = дані.ідентифікатор;
          п += 1;
          змінна сполука_значення_значення: *Сполука = пусто;
          змінна позиція_помилки_сполуки_значення_значення: природне = 0;
          якщо спробувати_розібрати_значення(М, знаки, п, сполука_значення_значення::адреса, п::адреса, ні, позиція_помилки_сполуки_значення_значення::адреса) {
            змінна сполука_змінити_властивість = виділити<Сполука>(М, 1);
            сполука_змінити_властивість.вид = ВидСполукиЗмінитиВластивість;
            сполука_змінити_властивість.дані = ДаніСполукиЗмінитиВластивість {
              предмет = предмет,
              ідентифікатор = ідентифікатор,
              значення = сполука_значення_значення
            };
            сполука_змінити_властивість.місцезнаходження = сполука_значення.місцезнаходження;
            вихід::вміст = сполука_змінити_властивість;
            вихід_позиції_кінця::вміст = п;
            звільнити(М, сполука_значення);
            вернути так;
          } інакше {
            звільнити_сполуку(М, сполука_значення);
            вихід_позиції_помилки::вміст = позиція_помилки_сполуки_значення_значення;
            вернути ні;
          }
        } інакше якщо сполука_значення.вид == ВидСполукиОтриматиЕлемент {
          змінна дані = сполука_значення.дані як ДаніСполукиОтриматиЕлемент;
          змінна предмет = дані.предмет;
          змінна ключ = дані.ключ;
          п += 1;
          змінна сполука_значення_значення: *Сполука = пусто;
          змінна позиція_помилки_сполуки_значення_значення: природне = 0;
          якщо спробувати_розібрати_значення(М, знаки, п, сполука_значення_значення::адреса, п::адреса, ні, позиція_помилки_сполуки_значення_значення::адреса) {
            змінна сполука_змінити_елемент = виділити<Сполука>(М, 1);
            сполука_змінити_елемент.вид = ВидСполукиЗмінитиЕлемент;
            сполука_змінити_елемент.дані = ДаніСполукиЗмінитиЕлемент {
              предмет = предмет,
              ключ = ключ,
              значення = сполука_значення_значення
            };
            сполука_змінити_елемент.місцезнаходження = сполука_значення.місцезнаходження;
            вихід::вміст = сполука_змінити_елемент;
            вихід_позиції_кінця::вміст = п;
            звільнити(М, сполука_значення);
            вернути так;
          } інакше {
            звільнити_сполуку(М, сполука_значення);
            вихід_позиції_помилки::вміст = позиція_помилки_сполуки_значення_значення;
            вернути ні;
          }
        } інакше {
          вихід_позиції_помилки::вміст = п;
          вернути ні;
        }
        спроба_ззовні:
        якщо сполука_значення.вид == ВидСполукиЗвернутись {
          змінна дані = сполука_значення.дані як ДаніСполукиЗвернутись;
          змінна ідентифікатор = дані.ідентифікатор;
          п += 1;
          змінна сполука_значення_значення: *Сполука = пусто;
          змінна позиція_помилки_сполуки_значення_значення: природне = 0;
          якщо спробувати_розібрати_значення(М, знаки, п, сполука_значення_значення::адреса, п::адреса, ні, позиція_помилки_сполуки_значення_значення::адреса) {
            змінна сполука_визначити_ззовні = виділити<Сполука>(М, 1);
            сполука_визначити_ззовні.вид = ВидСполукиВизначитиЗзовні;
            сполука_визначити_ззовні.дані = ДаніСполукиВизначитиЗзовні {
              ідентифікатор = ідентифікатор,
              значення = сполука_значення_значення
            };
            сполука_визначити_ззовні.місцезнаходження = сполука_значення.місцезнаходження;
            вихід::вміст = сполука_визначити_ззовні;
            вихід_позиції_кінця::вміст = п;
            звільнити(М, сполука_значення);
            вернути так;
          } інакше {
            звільнити_сполуку(М, сполука_значення);
            вихід_позиції_помилки::вміст = позиція_помилки_сполуки_значення_значення;
            вернути ні;
          }
        } інакше {
          вихід_позиції_помилки::вміст = п;
          вернути ні;
        }
        спроба2:
        якщо сполука_значення.вид == ВидСполукиЗвернутись {
          змінна дані = сполука_значення.дані як ДаніСполукиЗвернутись;
          змінна ідентифікатор = дані.ідентифікатор;
          п += 1;
          змінна сполука_значення_значення: *Сполука = пусто;
          змінна позиція_помилки_сполуки_значення_значення: природне = 0;
          якщо спробувати_розібрати_значення(М, знаки, п, сполука_значення_значення::адреса, п::адреса, ні, позиція_помилки_сполуки_значення_значення::адреса) {
            змінна сполука_операція = виділити<Сполука>(М, 1);
            сполука_операція.вид = ВидСполукиОперація;
            сполука_операція.дані = ДаніСполукиОперація {
              ліво = сполука_значення,
              операція = вид_операції,
              право = сполука_значення_значення
            };
            сполука_операція.місцезнаходження = сполука_значення.місцезнаходження;
            змінна сполука_визначити = виділити<Сполука>(М, 1);
            сполука_визначити.вид = ВидСполукиВизначити;
            сполука_визначити.дані = ДаніСполукиВизначити {
              ідентифікатор = ідентифікатор,
              значення = сполука_операція
            };
            сполука_визначити.місцезнаходження = сполука_значення.місцезнаходження;
            вихід::вміст = сполука_визначити;
            вихід_позиції_кінця::вміст = п;
            вернути так;
          } інакше {
            звільнити_сполуку(М, сполука_значення);
            вихід_позиції_помилки::вміст = позиція_помилки_сполуки_значення_значення;
            вернути ні;
          }
        } інакше якщо сполука_значення.вид == ВидСполукиОтриматиВластивість {
          змінна дані = сполука_значення.дані як ДаніСполукиОтриматиВластивість;
          змінна предмет = дані.предмет;
          змінна ідентифікатор = дані.ідентифікатор;
          п += 1;
          змінна сполука_значення_значення: *Сполука = пусто;
          змінна позиція_помилки_сполуки_значення_значення: природне = 0;
          якщо спробувати_розібрати_значення(М, знаки, п, сполука_значення_значення::адреса, п::адреса, ні, позиція_помилки_сполуки_значення_значення::адреса) {
            змінна сполука_операція = виділити<Сполука>(М, 1);
            сполука_операція.вид = ВидСполукиОперація;
            сполука_операція.дані = ДаніСполукиОперація {
              ліво = сполука_значення,
              операція = вид_операції,
              право = сполука_значення_значення
            };
            сполука_операція.місцезнаходження = сполука_значення.місцезнаходження;
            змінна сполука_змінити_властивість = виділити<Сполука>(М, 1);
            сполука_змінити_властивість.вид = ВидСполукиЗмінитиВластивість;
            сполука_змінити_властивість.дані = ДаніСполукиЗмінитиВластивість {
              предмет = зробити_повну_копію_сполуки(М, предмет),
              ідентифікатор = ідентифікатор,
              значення = сполука_операція
            };
            сполука_змінити_властивість.місцезнаходження = сполука_значення.місцезнаходження;
            вихід::вміст = сполука_змінити_властивість;
            вихід_позиції_кінця::вміст = п;
            вернути так;
          } інакше {
            звільнити_сполуку(М, сполука_значення);
            вихід_позиції_помилки::вміст = позиція_помилки_сполуки_значення_значення;
            вернути ні;
          }
        } інакше якщо сполука_значення.вид == ВидСполукиОтриматиЕлемент {
          змінна дані = сполука_значення.дані як ДаніСполукиОтриматиЕлемент;
          змінна предмет = дані.предмет;
          змінна ключ = дані.ключ;
          п += 1;
          змінна сполука_значення_значення: *Сполука = пусто;
          змінна позиція_помилки_сполуки_значення_значення: природне = 0;
          якщо спробувати_розібрати_значення(М, знаки, п, сполука_значення_значення::адреса, п::адреса, ні, позиція_помилки_сполуки_значення_значення::адреса) {
            змінна сполука_операція = виділити<Сполука>(М, 1);
            сполука_операція.вид = ВидСполукиОперація;
            сполука_операція.дані = ДаніСполукиОперація {
              ліво = сполука_значення,
              операція = вид_операції,
              право = сполука_значення_значення
            };
            сполука_операція.місцезнаходження = сполука_значення.місцезнаходження;
            змінна сполука_змінити_елемент = виділити<Сполука>(М, 1);
            сполука_змінити_елемент.вид = ВидСполукиЗмінитиЕлемент;
            сполука_змінити_елемент.дані = ДаніСполукиЗмінитиЕлемент {
              предмет = зробити_повну_копію_сполуки(М, предмет),
              ключ = зробити_повну_копію_сполуки(М, ключ),
              значення = сполука_операція
            };
            сполука_змінити_елемент.місцезнаходження = сполука_значення.місцезнаходження;
            вихід::вміст = сполука_змінити_елемент;
            вихід_позиції_кінця::вміст = п;
            вернути так;
          } інакше {
            звільнити_сполуку(М, сполука_значення);
            вихід_позиції_помилки::вміст = позиція_помилки_сполуки_значення_значення;
            вернути ні;
          }
        } інакше {
          вихід_позиції_помилки::вміст = п;
          вернути ні;
        }
        вихід:
        вихід::вміст = сполука_значення;
        вихід_позиції_кінця::вміст = п;
        вернути так;
      }
      вихід_позиції_помилки::вміст = позиція_помилки_сполуки_значення;
      вернути ні;
    }

    внутрішня дія спробувати_розібрати_тіло(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: *Сполуки, вихід_позиції_кінця: *природне, вид_знаку_закінчення: природне, вихід_позиції_помилки: *природне) -> логічне {
      змінна п = позиція_початку;
      зʼїсти_міжрядки(знаки, п, п::адреса);
      змінна елементи = зробити_накопичувач<*Сполука>(М, 0);
      поки п < знаки.розмір {
        якщо знаки.дані[п].вид == вид_знаку_закінчення {
          вихід::вміст = Сполуки { елементи.розмір, елементи.дані };
          вихід_позиції_кінця::вміст = п;
          вернути так;
        }
        змінна сполука_елемента_тіла: *Сполука = пусто;
        змінна позиція_помилки_елемента_тіла: природне = 0;
        якщо спробувати_розібрати_елемент_тіла(М, знаки, п, сполука_елемента_тіла::адреса, п::адреса, позиція_помилки_елемента_тіла::адреса) {
          елементи.покласти(М, сполука_елемента_тіла);
          п += 1;
          якщо зʼїсти_міжрядки(знаки, п, п::адреса) {
          } інакше якщо знаки.дані[п].вид == вид_знаку_закінчення {
            вихід::вміст = Сполуки { елементи.розмір, елементи.дані };
            вихід_позиції_кінця::вміст = п;
            вернути так;
          } інакше {
            звільнити_сполуки(М, Сполуки { елементи.розмір, елементи.дані });
            вихід_позиції_помилки::вміст = п;
            вернути ні;
          }
        } інакше {
          звільнити_сполуки(М, Сполуки { елементи.розмір, елементи.дані });
          вихід_позиції_помилки::вміст = позиція_помилки_елемента_тіла;
          вернути ні;
        }
      }
      звільнити_сполуки(М, Сполуки { елементи.розмір, елементи.дані });
      вихід_позиції_помилки::вміст = п;
      вернути ні;
    }

    внутрішня дія спробувати_розібрати_тип(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: *Тип, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
      змінна п = позиція_початку;
      змінна типи = зробити_накопичувач<*Сполука>(М, 0);
      поки п < знаки.розмір {
        змінна сполука_типу: *Сполука = пусто;
        змінна позиція_помилки_молекули: природне = 0;
        якщо спробувати_розібрати_молекулу(М, знаки, п, сполука_типу::адреса, п::адреса, позиція_помилки_молекули::адреса) {
          типи.покласти(М, сполука_типу);
          п += 1;
          якщо знаки.дані[п].вид == ВидЗнакуАбо {
            п += 1;
          } інакше {
            вихід::вміст = Тип {
              кількість_гілок = типи.розмір,
              сполуки = типи.дані,
            };
            вихід_позиції_кінця::вміст = п - 1;
            вернути так;
          }
        } інакше {
          звільнити_сполуки(М, Сполуки { типи.розмір, типи.дані });
          вихід_позиції_помилки::вміст = позиція_помилки_молекули;
          вернути ні;
        }
      }
      звільнити_сполуки(М, Сполуки { типи.розмір, типи.дані });
      вихід_позиції_помилки::вміст = п;
      вернути ні;
    }

    внутрішня дія спробувати_розібрати_параметр(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: *Параметр, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
      змінна п = позиція_початку;
      змінна сполука_значення: *Сполука = пусто;
      // ідентифікатор параметра
      змінна позиція_ідентифікатора = п;
      якщо знаки.дані[п].вид != ВидЗнакуІдентифікатор і знаки.дані[п].вид != ВидЗнакуЧисло {
        вихід_позиції_помилки::вміст = п;
        вернути ні;
      }
      п += 1;
      // тип параметра
      змінна тип = Тип { ... };
      змінна позиція_помилки_типу: природне = 0;
      якщо спробувати_розібрати_тип(М, знаки, п, тип::адреса, п::адреса, позиція_помилки_типу::адреса) {
        п += 1;
        якщо знаки.дані[п].вид == ВидЗнакуСимволРівно {
          п += 1;
          змінна позиція_помилки_сполуки_значення: природне = 0;
          якщо спробувати_розібрати_значення(М, знаки, п, сполука_значення::адреса, п::адреса, ні, позиція_помилки_сполуки_значення::адреса) {
          } інакше {
            звільнити_тип(М, тип);
            вихід_позиції_помилки::вміст = позиція_помилки_сполуки_значення;
            вернути ні;
          }
        } інакше {
          п -= 1;
        }
        вихід::вміст = Параметр {
          ідентифікатор = Ідентифікатор { позиція_ідентифікатора },
          тип = можливо<Тип> { так, тип },
          значення = сполука_значення,
          місцезнаходження = Місцезнаходження { позиція_початку }
        };
        вихід_позиції_кінця::вміст = п;
      } інакше {
        якщо знаки.дані[п].вид == ВидЗнакуСимволРівно {
          п += 1;
          змінна позиція_помилки_сполуки_значення: природне = 0;
          якщо спробувати_розібрати_значення(М, знаки, п, сполука_значення::адреса, п::адреса, ні, позиція_помилки_сполуки_значення::адреса) {
          } інакше {
            звільнити_сполуку(М, сполука_значення);
            вихід_позиції_помилки::вміст = позиція_помилки_сполуки_значення;
            вернути ні;
          }
        } інакше {
          п -= 1;
        }
        вихід::вміст = Параметр {
          ідентифікатор = Ідентифікатор { позиція_ідентифікатора },
          тип = можливо<Тип> { ні, ... },
          значення = сполука_значення,
          місцезнаходження = Місцезнаходження { позиція_початку }
        };
        вихід_позиції_кінця::вміст = п;
      }
      вернути так;
    }

    внутрішня дія спробувати_розібрати_дію(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
      змінна дані_сполуки_дія = ДаніСполукиДія {
        тривала = ні,
        власна = ні,
        клас = пусто,
        ідентифікатор = можливо<Ідентифікатор> { ні, ... },
        кількість_параметрів = 0,
        параметри = пусто,
        тип_результату = можливо<Тип> { ні, ... },
        тіло = Сполуки { 0, пусто }
      };
      змінна п = позиція_початку;
      // дія власна?
      якщо знаки.дані[п].вид == ВидЗнакуВласна {
        дані_сполуки_дія.власна = так;
        п += 1;
      }
      // дія тривала?
      якщо знаки.дані[п].вид == ВидЗнакуТривала {
        дані_сполуки_дія.тривала = так;
        п += 1;
      }
      // дія?
      якщо знаки.дані[п].вид != ВидЗнакуДія {
        вихід_позиції_помилки::вміст = п;
        стрибнути звільнити_і_вийти;
      }
      п += 1;
      // клас та/або ідентифікатор дії
      якщо знаки.дані[п].вид == ВидЗнакуІдентифікатор {
        дані_сполуки_дія.ідентифікатор = можливо<Ідентифікатор> { так, Ідентифікатор { п } };
        п += 1;
        якщо знаки.дані[п].вид == ВидЗнакуСимволКрапка {
          п += 1;
          якщо знаки.дані[п].вид == ВидЗнакуІдентифікатор {
            змінна сполука_звернення = виділити<Сполука>(М, 1);
            сполука_звернення.вид = ВидСполукиЗвернутись;
            сполука_звернення.дані = ДаніСполукиЗвернутись {
              ідентифікатор = дані_сполуки_дія.ідентифікатор.значення
            };
            сполука_звернення.місцезнаходження = Місцезнаходження { п };
            дані_сполуки_дія.клас = сполука_звернення;
            дані_сполуки_дія.ідентифікатор = можливо<Ідентифікатор> { так, Ідентифікатор { п } };
            п += 1;
          } інакше {
            вихід_позиції_помилки::вміст = п;
            стрибнути звільнити_і_вийти;
          }
        }
      }
      якщо знаки.дані[п].вид != ВидЗнакуСимволВідкритаДужка {
        вихід_позиції_помилки::вміст = п;
        стрибнути звільнити_і_вийти;
      }
      п += 1;
      зʼїсти_міжрядки(знаки, п, п::адреса);
      // параметри дії
      змінна параметри = зробити_накопичувач<Параметр>(М, 0);
      поки п < знаки.розмір {
        якщо знаки.дані[п].вид == ВидЗнакуСимволЗакритаДужка {
          п += 1;
          стрибнути після_параметрів;
        }
        змінна параметр = Параметр { ... };
        змінна позиція_помилки_параметра: природне = 0;
        якщо спробувати_розібрати_параметр(М, знаки, п, параметр::адреса, п::адреса, позиція_помилки_параметра::адреса) {
          параметри.покласти(М, параметр);
          п += 1;
        } інакше {
          вихід_позиції_помилки::вміст = позиція_помилки_параметра;
          стрибнути звільнити_і_вийти;
        }
        зʼїсти_міжрядки(знаки, п, п::адреса);
        якщо знаки.дані[п].вид == ВидЗнакуСимволКома {
          п += 1;
          зʼїсти_міжрядки(знаки, п, п::адреса);
        } інакше якщо знаки.дані[п].вид == ВидЗнакуСимволЗакритаДужка {
          п += 1;
          стрибнути після_параметрів;
        } інакше {
          звільнити_параметри(М, параметри.розмір, параметри.дані);
          вихід_позиції_помилки::вміст = п;
          стрибнути звільнити_і_вийти;
        }
      }
      після_параметрів:
      дані_сполуки_дія.кількість_параметрів = параметри.розмір;
      дані_сполуки_дія.параметри = параметри.дані;
      // тип результату дії
      якщо знаки.дані[п].вид == ВидЗнакуСимволМіжряд {
        стрибнути розбір_тіла;
      } інакше якщо знаки.дані[п].вид == ВидЗнакуСимволДвокрапка {
        стрибнути розбір_короткого_тіла;
      } інакше {
        змінна позиція_помилки_типу_результату: природне = 0;
        якщо спробувати_розібрати_тип(М, знаки, п, дані_сполуки_дія.тип_результату.значення::адреса, п::адреса, позиція_помилки_типу_результату::адреса) {
          дані_сполуки_дія.тип_результату.заповнено = так;
          п += 1;
        } інакше {
          вихід_позиції_помилки::вміст = позиція_помилки_типу_результату;
          стрибнути звільнити_і_вийти;
        }
      }
      якщо знаки.дані[п].вид == ВидЗнакуСимволМіжряд {
        стрибнути розбір_тіла;
      } інакше {
        вихід_позиції_помилки::вміст = п;
        стрибнути звільнити_і_вийти;
      }
      // тіло дії
      розбір_короткого_тіла:
      п += 1;
      змінна сполука_значення: *Сполука = пусто;
      змінна позиція_помилки_сполуки_значення: природне = 0;
      якщо спробувати_розібрати_елемент_тіла(М, знаки, п, сполука_значення::адреса, п::адреса, позиція_помилки_сполуки_значення::адреса) == ні {
        вихід_позиції_помилки::вміст = позиція_помилки_сполуки_значення;
        стрибнути звільнити_і_вийти;
      }
      дані_сполуки_дія.тіло.дані = перевиділити<*Сполука>(М, дані_сполуки_дія.тіло.дані, 1);
      дані_сполуки_дія.тіло.дані[0] = сполука_значення;
      дані_сполуки_дія.тіло.розмір = 1;
      стрибнути після_тіла;
      розбір_тіла:
      п += 1;
      змінна позиція_помилки_тіла: природне = 0;
      якщо спробувати_розібрати_тіло(М, знаки, п, дані_сполуки_дія.тіло::адреса, п::адреса, ВидЗнакуКінець, позиція_помилки_тіла::адреса) == ні {
        вихід_позиції_помилки::вміст = позиція_помилки_тіла;
        стрибнути звільнити_і_вийти;
      }
      після_тіла:
      змінна сполука_дія = виділити<Сполука>(М, 1);
      сполука_дія.вид = ВидСполукиДія;
      сполука_дія.дані = дані_сполуки_дія;
      сполука_дія.місцезнаходження = Місцезнаходження {
        позиція_початку
      };
      вихід::вміст = сполука_дія;
      вихід_позиції_кінця::вміст = п;
      вернути так;
      звільнити_і_вийти:
      звільнити_параметри(М, дані_сполуки_дія.кількість_параметрів, дані_сполуки_дія.параметри);
      якщо дані_сполуки_дія.тип_результату.заповнено {
        звільнити_тип(М, дані_сполуки_дія.тип_результату.значення);
      }
      звільнити_тіло(М, дані_сполуки_дія.тіло);
      вернути ні;
    }

    внутрішня дія спробувати_розібрати_клас(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
      змінна дані_сполуки_клас = ДаніСполукиКлас {
        ідентифікатор = можливо<Ідентифікатор> { ні, ... },
        предок = пусто,
        кількість_параметрів = 0,
        параметри = пусто,
        методи = Сполуки { 0, пусто }
      };
      змінна п = позиція_початку;
      // клас?
      якщо знаки.дані[п].вид != ВидЗнакуКлас і знаки.дані[п].вид != ВидЗнакуСтруктура {
        вихід_позиції_помилки::вміст = п;
        стрибнути звільнити_і_вийти;
      }
      п += 1;
      // ідентифікатор класу
      якщо знаки.дані[п].вид == ВидЗнакуІдентифікатор {
        дані_сполуки_клас.ідентифікатор = можливо<Ідентифікатор> { так, Ідентифікатор { п } };
        п += 1;
      }
      // предок класу
      якщо знаки.дані[п].вид == ВидЗнакуЄ {
        п += 1;
        змінна позиція_помилки_молекули: природне = 0;
        якщо спробувати_розібрати_молекулу(М, знаки, п, дані_сполуки_клас.предок::адреса, п::адреса, позиція_помилки_молекули::адреса) {
          п += 1;
        } інакше {
          вихід_позиції_помилки::вміст = позиція_помилки_молекули;
          стрибнути звільнити_і_вийти;
        }
      }
      якщо знаки.дані[п].вид != ВидЗнакуСимволМіжряд {
        вихід_позиції_помилки::вміст = п;
        стрибнути звільнити_і_вийти;
      }
      п += 1;
      зʼїсти_міжрядки(знаки, п, п::адреса);
      // параметри і методи класу
      змінна параметри = зробити_накопичувач<Параметр>(М, 0);
      змінна методи = зробити_накопичувач<*Сполука>(М, 0);
      поки п < знаки.розмір {
        якщо знаки.дані[п].вид == ВидЗнакуКінець {
          стрибнути ок;
        }
        змінна параметр = Параметр { ... };
        змінна позиція_помилки_параметра: природне = 0;
        змінна сполука_дії: *Сполука = пусто;
        змінна позиція_помилки_дії: природне = 0;
        якщо спробувати_розібрати_параметр(М, знаки, п, параметр::адреса, п::адреса, позиція_помилки_параметра::адреса) {
          параметри.покласти(М, параметр);
          п += 1;
        } інакше якщо спробувати_розібрати_дію(М, знаки, п, сполука_дії::адреса, п::адреса, позиція_помилки_дії::адреса) {
          методи.покласти(М, сполука_дії);
          п += 1;
        } інакше {
          вихід_позиції_помилки::вміст = позиція_помилки_параметра;
          стрибнути звільнити_і_вийти;
        }
        якщо зʼїсти_міжрядки(знаки, п, п::адреса) {
        } інакше якщо знаки.дані[п].вид == ВидЗнакуКінець {
          стрибнути ок;
        } інакше {
          звільнити_параметри(М, параметри.розмір, параметри.дані);
          вихід_позиції_помилки::вміст = п;
          стрибнути звільнити_і_вийти;
        }
      }
    ок:
      дані_сполуки_клас.кількість_параметрів = параметри.розмір;
      дані_сполуки_клас.параметри = параметри.дані;
      дані_сполуки_клас.методи = Сполуки {
        розмір = методи.розмір,
        дані = методи.дані
      };
      змінна сполука_клас = виділити<Сполука>(М, 1);
      сполука_клас.вид = ВидСполукиКлас;
      сполука_клас.дані = дані_сполуки_клас;
      сполука_клас.місцезнаходження = Місцезнаходження {
        позиція_початку
      };
      вихід::вміст = сполука_клас;
      вихід_позиції_кінця::вміст = п;
      вернути так;
    звільнити_і_вийти:
      звільнити_сполуку(М, дані_сполуки_клас.предок);
      звільнити_параметри(М, дані_сполуки_клас.кількість_параметрів, дані_сполуки_клас.параметри);
      вернути ні;
    }

    внутрішня дія спробувати_розібрати_модуль(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
      змінна дані_сполуки_модуль = ДаніСполукиМодуль {
        ідентифікатор = можливо<Ідентифікатор> { ні, ... },
        тіло = Сполуки { 0, пусто }
      };
      змінна п = позиція_початку;
      // модуль?
      якщо знаки.дані[п].вид != ВидЗнакуМодуль {
        вихід_позиції_помилки::вміст = п;
        стрибнути звільнити_і_вийти;
      }
      п += 1;
      // ідентифікатор модуля
      якщо знаки.дані[п].вид == ВидЗнакуІдентифікатор {
        дані_сполуки_модуль.ідентифікатор = можливо<Ідентифікатор> { так, Ідентифікатор { п } };
        п += 1;
      }
      якщо знаки.дані[п].вид != ВидЗнакуСимволМіжряд {
        вихід_позиції_помилки::вміст = п;
        стрибнути звільнити_і_вийти;
      }
      п += 1;
      // тіло модуля
      змінна позиція_помилки_тіла: природне = 0;
      якщо спробувати_розібрати_тіло(М, знаки, п, дані_сполуки_модуль.тіло::адреса, п::адреса, ВидЗнакуКінець, позиція_помилки_тіла::адреса) == ні {
        вихід_позиції_помилки::вміст = позиція_помилки_тіла;
        стрибнути звільнити_і_вийти;
      }
      змінна сполука_модуль = виділити<Сполука>(М, 1);
      сполука_модуль.вид = ВидСполукиМодуль;
      сполука_модуль.дані = дані_сполуки_модуль;
      сполука_модуль.місцезнаходження = Місцезнаходження {
        позиція_початку
      };
      вихід::вміст = сполука_модуль;
      вихід_позиції_кінця::вміст = п;
      вернути так;
      звільнити_і_вийти:
      звільнити_тіло(М, дані_сполуки_модуль.тіло);
      вернути ні;
    }

    внутрішня дія спробувати_розібрати_якщо(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
      змінна дані_сполуки_якщо = ДаніСполукиЯкщо {
        умова = пусто,
        тіло = Сполуки { 0, пусто },
        тіло_інакше = Сполуки { 0, пусто }
      };
      змінна п = позиція_початку;
      // якщо?
      якщо знаки.дані[п].вид != ВидЗнакуЯкщо {
        вихід_позиції_помилки::вміст = п;
        стрибнути звільнити_і_вийти;
      }
      п += 1;
      // умова якщо
      змінна позиція_помилки_умови: природне = 0;
      якщо спробувати_розібрати_операцію(М, знаки, п, дані_сполуки_якщо.умова::адреса, п::адреса, ні, позиція_помилки_умови::адреса) {
        п += 1;
      } інакше {
        вихід_позиції_помилки::вміст = позиція_помилки_умови;
        стрибнути звільнити_і_вийти;
      }
      якщо знаки.дані[п].вид != ВидЗнакуСимволМіжряд {
        вихід_позиції_помилки::вміст = п;
        стрибнути звільнити_і_вийти;
      }
      п += 1;
      // тіло якщо
      змінна тіло = зробити_накопичувач<*Сполука>(М, 0);
      поки п < знаки.розмір {
        якщо знаки.дані[п].вид == ВидЗнакуКінець {
          дані_сполуки_якщо.тіло.розмір = тіло.розмір;
          дані_сполуки_якщо.тіло.дані = тіло.дані;
          стрибнути після_тіла;
        }
        якщо знаки.дані[п].вид == ВидЗнакуІнакше {
          дані_сполуки_якщо.тіло.розмір = тіло.розмір;
          дані_сполуки_якщо.тіло.дані = тіло.дані;
          стрибнути розбір_інакше;
        }
        зʼїсти_міжрядки(знаки, п, п::адреса);
        змінна сполука_елемента_тіла: *Сполука = пусто;
        змінна позиція_помилки_елемента_тіла: природне = 0;
        якщо спробувати_розібрати_елемент_тіла(М, знаки, п, сполука_елемента_тіла::адреса, п::адреса, позиція_помилки_елемента_тіла::адреса) {
          тіло.покласти(М, сполука_елемента_тіла);
          п += 1;
          якщо зʼїсти_міжрядки(знаки, п, п::адреса) {
          } інакше якщо знаки.дані[п].вид == ВидЗнакуКінець {
            дані_сполуки_якщо.тіло.розмір = тіло.розмір;
            дані_сполуки_якщо.тіло.дані = тіло.дані;
            стрибнути після_тіла;
          } інакше якщо знаки.дані[п].вид == ВидЗнакуІнакше {
            дані_сполуки_якщо.тіло.розмір = тіло.розмір;
            дані_сполуки_якщо.тіло.дані = тіло.дані;
            стрибнути розбір_інакше;
          } інакше {
            дані_сполуки_якщо.тіло.розмір = тіло.розмір;
            дані_сполуки_якщо.тіло.дані = тіло.дані;
            вихід_позиції_помилки::вміст = п;
            стрибнути звільнити_і_вийти;
          }
        } інакше {
          дані_сполуки_якщо.тіло.розмір = тіло.розмір;
          дані_сполуки_якщо.тіло.дані = тіло.дані;
          вихід_позиції_помилки::вміст = позиція_помилки_елемента_тіла;
          стрибнути звільнити_і_вийти;
        }
      }
      вихід_позиції_помилки::вміст = п;
      стрибнути звільнити_і_вийти;
      розбір_інакше:
      п += 1;
      // інакше якщо
      якщо знаки.дані[п].вид == ВидЗнакуЯкщо {
        змінна сполука_інакше_якщо: *Сполука = пусто;
        змінна позиція_помилки_інакше_якщо: природне = 0;
        якщо спробувати_розібрати_якщо(М, знаки, п, сполука_інакше_якщо::адреса, п::адреса, позиція_помилки_інакше_якщо::адреса) {
          змінна накопичувач_інакше_якщо = зробити_накопичувач<*Сполука>(М, 0);
          накопичувач_інакше_якщо.покласти(М, сполука_інакше_якщо);
          дані_сполуки_якщо.тіло_інакше = Сполуки {
            накопичувач_інакше_якщо.розмір,
            накопичувач_інакше_якщо.дані
          };
          стрибнути після_тіла;
        }
        вихід_позиції_помилки::вміст = позиція_помилки_інакше_якщо;
        стрибнути звільнити_і_вийти;
      } інакше якщо зʼїсти_міжрядки(знаки, п, п::адреса) {
        // тіло інакше
        змінна позиція_помилки_інакше: природне = 0;
        якщо спробувати_розібрати_тіло(М, знаки, п, дані_сполуки_якщо.тіло_інакше::адреса, п::адреса, ВидЗнакуКінець, позиція_помилки_інакше::адреса) == ні {
          вихід_позиції_помилки::вміст = позиція_помилки_інакше;
          стрибнути звільнити_і_вийти;
        }
        стрибнути після_тіла;
      } інакше {
        вихід_позиції_помилки::вміст = п;
        стрибнути звільнити_і_вийти;
      }
      після_тіла:
      змінна сполука_якщо = виділити<Сполука>(М, 1);
      сполука_якщо.вид = ВидСполукиЯкщо;
      сполука_якщо.дані = дані_сполуки_якщо;
      сполука_якщо.місцезнаходження = Місцезнаходження {
        позиція_початку
      };
      вихід::вміст = сполука_якщо;
      вихід_позиції_кінця::вміст = п;
      вернути так;
      звільнити_і_вийти:
      звільнити_сполуку(М, дані_сполуки_якщо.умова);
      звільнити_тіло(М, дані_сполуки_якщо.тіло);
      звільнити_тіло(М, дані_сполуки_якщо.тіло_інакше);
      вернути ні;
    }

    внутрішня дія спробувати_розібрати_поки(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
      змінна дані_сполуки_поки = ДаніСполукиПоки {
        умова = пусто,
        тіло = Сполуки { 0, пусто }
      };
      змінна п = позиція_початку;
      // поки?
      якщо знаки.дані[п].вид != ВидЗнакуПоки {
        вихід_позиції_помилки::вміст = п;
        стрибнути звільнити_і_вийти;
      }
      п += 1;
      // умова поки
      змінна позиція_помилки_умови: природне = 0;
      якщо спробувати_розібрати_операцію(М, знаки, п, дані_сполуки_поки.умова::адреса, п::адреса, ні, позиція_помилки_умови::адреса) {
        п += 1;
      } інакше {
        вихід_позиції_помилки::вміст = позиція_помилки_умови;
        стрибнути звільнити_і_вийти;
      }
      // тіло поки
      якщо знаки.дані[п].вид == ВидЗнакуСимволМіжряд {
        стрибнути розбір_тіла;
      } інакше якщо знаки.дані[п].вид == ВидЗнакуСимволДвокрапка {
        стрибнути розбір_короткого_тіла;
      } інакше {
        вихід_позиції_помилки::вміст = п;
        стрибнути звільнити_і_вийти;
      }
      розбір_короткого_тіла:
      п += 1;
      змінна сполука_значення: *Сполука = пусто;
      змінна позиція_помилки_сполуки_значення: природне = 0;
      якщо спробувати_розібрати_елемент_тіла(М, знаки, п, сполука_значення::адреса, п::адреса, позиція_помилки_сполуки_значення::адреса) == ні {
        вихід_позиції_помилки::вміст = позиція_помилки_сполуки_значення;
        стрибнути звільнити_і_вийти;
      }
      дані_сполуки_поки.тіло.дані = перевиділити<*Сполука>(М, дані_сполуки_поки.тіло.дані, 1);
      дані_сполуки_поки.тіло.дані[0] = сполука_значення;
      дані_сполуки_поки.тіло.розмір = 1;
      стрибнути після_тіла;
      розбір_тіла:
      п += 1;
      змінна позиція_помилки_тіла: природне = 0;
      якщо спробувати_розібрати_тіло(М, знаки, п, дані_сполуки_поки.тіло::адреса, п::адреса, ВидЗнакуКінець, позиція_помилки_тіла::адреса) == ні {
        вихід_позиції_помилки::вміст = позиція_помилки_тіла;
        стрибнути звільнити_і_вийти;
      }
      після_тіла:
      змінна сполука_поки = виділити<Сполука>(М, 1);
      сполука_поки.вид = ВидСполукиПоки;
      сполука_поки.дані = дані_сполуки_поки;
      сполука_поки.місцезнаходження = Місцезнаходження {
        позиція_початку
      };
      вихід::вміст = сполука_поки;
      вихід_позиції_кінця::вміст = п;
      вернути так;
      звільнити_і_вийти:
      звільнити_сполуку(М, дані_сполуки_поки.умова);
      звільнити_тіло(М, дані_сполуки_поки.тіло);
      вернути ні;
    }

    внутрішня дія спробувати_розібрати_перебрати(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
      змінна дані_сполуки_перебрати = ДаніСполукиПеребрати {
        предмет = пусто,
        ідентифікатор = можливо<Ідентифікатор> { ні, ... },
        тіло = Сполуки { 0, пусто }
      };
      змінна п = позиція_початку;
      // перебрати?
      якщо знаки.дані[п].вид != ВидЗнакуПеребрати {
        вихід_позиції_помилки::вміст = п;
        стрибнути звільнити_і_вийти;
      }
      п += 1;
      // значення перебрати
      змінна позиція_помилки_операції: природне = 0;
      якщо спробувати_розібрати_операцію(М, знаки, п, дані_сполуки_перебрати.предмет::адреса, п::адреса, ні, позиція_помилки_операції::адреса) {
        п += 1;
      } інакше {
        вихід_позиції_помилки::вміст = позиція_помилки_операції;
        стрибнути звільнити_і_вийти;
      }
      якщо знаки.дані[п].вид == ВидЗнакуЯк {
        п += 1;
        якщо знаки.дані[п].вид != ВидЗнакуІдентифікатор {
          вихід_позиції_помилки::вміст = п;
          стрибнути звільнити_і_вийти;
        }
        дані_сполуки_перебрати.ідентифікатор = можливо<Ідентифікатор> {
          так,
          Ідентифікатор { п }
        };
        п += 1;
      }
      // тіло перебрати
      якщо знаки.дані[п].вид == ВидЗнакуСимволМіжряд {
        стрибнути розбір_тіла;
      } інакше якщо знаки.дані[п].вид == ВидЗнакуСимволДвокрапка {
        стрибнути розбір_короткого_тіла;
      } інакше {
        вихід_позиції_помилки::вміст = п;
        стрибнути звільнити_і_вийти;
      }
      розбір_короткого_тіла:
      п += 1;
      змінна сполука_значення: *Сполука = пусто;
      змінна позиція_помилки_сполуки_значення: природне = 0;
      якщо спробувати_розібрати_елемент_тіла(М, знаки, п, сполука_значення::адреса, п::адреса, позиція_помилки_сполуки_значення::адреса) == ні {
        вихід_позиції_помилки::вміст = позиція_помилки_сполуки_значення;
        стрибнути звільнити_і_вийти;
      }
      дані_сполуки_перебрати.тіло.дані = перевиділити<*Сполука>(М, дані_сполуки_перебрати.тіло.дані, 1);
      дані_сполуки_перебрати.тіло.дані[0] = сполука_значення;
      дані_сполуки_перебрати.тіло.розмір = 1;
      стрибнути після_тіла;
      розбір_тіла:
      п += 1;
      змінна позиція_помилки_тіла: природне = 0;
      якщо спробувати_розібрати_тіло(М, знаки, п, дані_сполуки_перебрати.тіло::адреса, п::адреса, ВидЗнакуКінець, позиція_помилки_тіла::адреса) == ні {
        вихід_позиції_помилки::вміст = позиція_помилки_тіла;
        стрибнути звільнити_і_вийти;
      }
      після_тіла:
      змінна сполука_перебрати = виділити<Сполука>(М, 1);
      сполука_перебрати.вид = ВидСполукиПеребрати;
      сполука_перебрати.дані = дані_сполуки_перебрати;
      сполука_перебрати.місцезнаходження = Місцезнаходження {
        позиція_початку
      };
      вихід::вміст = сполука_перебрати;
      вихід_позиції_кінця::вміст = п;
      вернути так;
      звільнити_і_вийти:
      звільнити_сполуку(М, дані_сполуки_перебрати.предмет);
      звільнити_тіло(М, дані_сполуки_перебрати.тіло);
      вернути ні;
    }

    внутрішня дія спробувати_розібрати_спробувати(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
      змінна дані_сполуки_спробувати = ДаніСполукиСпробувати {
        тіло = Сполуки { 0, пусто },
        ідентифікатор_зловити = можливо<Ідентифікатор> { ні, ... },
        тіло_зловити = Сполуки { 0, пусто }
      };
      змінна п = позиція_початку;
      // спробувати?
      якщо знаки.дані[п].вид != ВидЗнакуСпробувати {
        вихід_позиції_помилки::вміст = п;
        стрибнути звільнити_і_вийти;
      }
      п += 1;
      якщо знаки.дані[п].вид != ВидЗнакуСимволМіжряд {
        вихід_позиції_помилки::вміст = п;
        стрибнути звільнити_і_вийти;
      }
      п += 1;
      // тіло спробувати
      змінна позиція_помилки_тіла: природне = 0;
      якщо спробувати_розібрати_тіло(М, знаки, п, дані_сполуки_спробувати.тіло::адреса, п::адреса, ВидЗнакуЗловити, позиція_помилки_тіла::адреса) == ні {
        вихід_позиції_помилки::вміст = позиція_помилки_тіла;
        стрибнути звільнити_і_вийти;
      }
      п += 1;
      якщо знаки.дані[п].вид == ВидЗнакуІдентифікатор {
        дані_сполуки_спробувати.ідентифікатор_зловити = можливо<Ідентифікатор> {
          так,
          Ідентифікатор { п }
        };
        п += 1;
      }
      якщо знаки.дані[п].вид != ВидЗнакуСимволМіжряд {
        вихід_позиції_помилки::вміст = п;
        стрибнути звільнити_і_вийти;
      }
      п += 1;
      // тіло зловити
      змінна позиція_помилки_тіла_зловити: природне = 0;
      якщо спробувати_розібрати_тіло(М, знаки, п, дані_сполуки_спробувати.тіло_зловити::адреса, п::адреса, ВидЗнакуКінець, позиція_помилки_тіла_зловити::адреса) == ні {
        вихід_позиції_помилки::вміст = позиція_помилки_тіла_зловити;
        стрибнути звільнити_і_вийти;
      }
      змінна сполука_спробувати = виділити<Сполука>(М, 1);
      сполука_спробувати.вид = ВидСполукиСпробувати;
      сполука_спробувати.дані = дані_сполуки_спробувати;
      сполука_спробувати.місцезнаходження = Місцезнаходження {
        позиція_початку
      };
      вихід::вміст = сполука_спробувати;
      вихід_позиції_кінця::вміст = п;
      вернути так;
      звільнити_і_вийти:
      звільнити_тіло(М, дані_сполуки_спробувати.тіло);
      звільнити_тіло(М, дані_сполуки_спробувати.тіло_зловити);
      вернути ні;
    }

    дія розібрати_знаки_на_сполуки(М: *Машина, значення_кд: кд, знаки: Знаки, вихід: *Сполуки, вихід_помилки: *ПомилкаРозборуНаСполуки) -> логічне {
      змінна тіло = Сполуки { 0, пусто };
      змінна позиція_кінця: природне = 0;
      змінна позиція_помилки: природне = 0;
      якщо спробувати_розібрати_тіло(М, знаки, 0, тіло::адреса, позиція_кінця::адреса, ВидЗнакуКІНЕЦЬСЛІВ, позиція_помилки::адреса) {
        вихід::вміст = Сполуки {
          тіло.розмір,
          тіло.дані
        };
        вернути так;
      }
      вихід_помилки::вміст = ПомилкаРозборуНаСполуки {
        позиція_знаку = позиція_помилки,
        рядок = знаки.дані[позиція_помилки].позиція_початку.рядок,
        стовпець = знаки.дані[позиція_помилки].позиція_початку.стовпець
      };
      вернути ні;
    }

    дія звільнити_сполуки(М: *Машина, сполуки: Сполуки) {
      змінна п: природне = 0;
      поки п < сполуки.розмір {
        звільнити_сполуку(М, сполуки.дані[п]);
        п += 1;
      }
      звільнити(М, сполуки.дані);
    }

    дія звільнити_помилку_розбору_на_сполуки(М: *Машина, помилка: ПомилкаРозборуНаСполуки) {
      // ...
    }

    дія отримати_помилку_розбору_на_сполуки(М: *Машина, помилка: ПомилкаРозборуНаСполуки, вихід: *кд) -> логічне {
      виділити_копію_кд(М, "Не вдалось розібрати", вихід);
      вернути так;
    }

    дія отримати_рядок_помилки_розбору_на_сполуки(М: *Машина, помилка: ПомилкаРозборуНаСполуки) -> природне {
      вернути помилка.рядок;
    }

    дія отримати_стовпець_помилки_розбору_на_сполуки(М: *Машина, помилка: ПомилкаРозборуНаСполуки) -> природне {
      вернути помилка.стовпець;
    }
  }
}