// 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;
вихід_позиції_кінця::вміст = п;
вернути так;
}
структура Накопичувач<Т> {
розмір: природне;
дані: *Т;
вмісткість: природне;
}
внутрішня дія покласти_в_накопичувач<Т>(М: *Машина, накопичувач: *Накопичувач<Т>, елемент: Т) {
якщо накопичувач.розмір == накопичувач.вмісткість {
накопичувач.вмісткість += 1;
накопичувач.дані = перевиділити<Т>(М, накопичувач.дані, накопичувач.вмісткість);
}
накопичувач.дані[накопичувач.розмір] = елемент;
накопичувач.розмір += 1;
}
внутрішня дія зробити_накопичувач<Т>(М: *Машина) -> Накопичувач<Т> {
вернути Накопичувач<Т> { 0, пусто, 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
};
}
дія отримати_значення_тексту(значення_кд: кд, знаки: Знаки, знак: Знак) -> кд {
змінна значення_знаку = отримати_значення_знаку(значення_кд, знаки, знак);
вернути кд { значення_знаку.розмір - 2, значення_знаку.дані[1]::адреса як *п8 };
}
дія отримати_значення_символу(значення_кд: кд, знаки: Знаки, знак: Знак) -> кд {
змінна значення_знаку = отримати_значення_знаку(значення_кд, знаки, знак);
вернути кд { значення_знаку.розмір - 2, значення_знаку.дані[1]::адреса як *п8 };
}
дія отримати_рядок_з_місцезнаходження(значення_кд: кд, знаки: Знаки, місцезнаходження: Місцезнаходження) -> природне {
вернути знаки.дані[місцезнаходження.позиція_знаку].позиція_початку.рядок;
}
дія отримати_стовпець_з_місцезнаходження(значення_кд: кд, знаки: Знаки, місцезнаходження: Місцезнаходження) -> природне {
вернути знаки.дані[місцезнаходження.позиція_знаку].позиція_початку.стовпець;
}
}
}
простір мавка {
простір розбирач {
внутрішня дія зробити_повну_копію_сполуки(М: *Машина, сполука: *Сполука) -> *Сполука;
внутрішня дія зробити_повну_копію_тіла(М: *Машина, тіло: Сполуки) -> Сполуки;
внутрішня дія зробити_повну_копію_типу(М: *Машина, тип: Тип) -> Тип;
внутрішня дія зробити_повну_копію_можливо_типу(М: *Машина, тип: можливо<Тип>) -> можливо<Тип>;
внутрішня дія зробити_повну_копію_параметра(М: *Машина, параметр: Параметр) -> Параметр;
внутрішня дія зробити_повну_копію_параметрів(М: *Машина, кількість_параметрів: природне, параметри: *Параметр) -> *Параметр;
внутрішня дія зробити_повну_копію_аргумента(М: *Машина, аргумент: Аргумент) -> Аргумент;
внутрішня дія зробити_повну_копію_аргументів(М: *Машина, кількість_аргументів: природне, аргументи: *Аргумент) -> *Аргумент;
внутрішня дія зробити_повну_копію_гілок(М: *Машина, кількість_гілок: природне, сполуки: **Сполука) -> **Сполука;
внутрішня дія зробити_повну_копію_елемента_словника(М: *Машина, елемент: ЕлементСловника) -> ЕлементСловника;
внутрішня дія зробити_повну_копію_елементів_словника(М: *Машина, кількість_елементів: природне, елементи: *ЕлементСловника) -> *ЕлементСловника;
внутрішня дія зробити_повну_копію_ідентифікаторів(М: *Машина, кількість_ідентифікаторів: природне, ідентифікатори: *Ідентифікатор) -> *Ідентифікатор;
внутрішня дія зробити_повну_копію_елемента_взяти(М: *Машина, елемент: ЕлементВзяти) -> ЕлементВзяти;
внутрішня дія зробити_повну_копію_елементів_взяти(М: *Машина, кількість_елементів: природне, елементи: *ЕлементВзяти) -> *ЕлементВзяти;
внутрішня дія зробити_повну_копію_елемента_дати(М: *Машина, елемент: ЕлементДати) -> ЕлементДати;
внутрішня дія зробити_повну_копію_елементів_дати(М: *Машина, кількість_елементів: природне, елементи: *ЕлементДати) -> *ЕлементДати;
внутрішня дія звільнити_сполуку(М: *Машина, сполука: *Сполука);
внутрішня дія звільнити_тіло(М: *Машина, тіло: Сполуки);
внутрішня дія звільнити_тип(М: *Машина, тип: Тип);
внутрішня дія звільнити_параметри(М: *Машина, кількість_параметрів: природне, параметри: *Параметр);
внутрішня дія звільнити_аргументи(М: *Машина, кількість_аргументів: природне, аргументи: *Аргумент);
внутрішня дія звільнити_елементи_словника(М: *Машина, кількість_елементів: природне, елементи: *ЕлементСловника);
внутрішня дія зробити_повну_копію_сполуки(М: *Машина, сполука: *Сполука) -> *Сполука {
якщо сполука == пусто {
вернути пусто;
}
змінна копія = виділити<Сполука>(М, 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;
зʼїсти_міжрядки(знаки, п, п::адреса);
змінна сполука_гнізда: *Сполука = пусто;
змінна позиція_помилки_сполуки_гнізда: природне = 0;
якщо спробувати_розібрати_значення(М, знаки, п, сполука_гнізда::адреса, п::адреса, так, позиція_помилки_сполуки_гнізда::адреса) {
п += 1;
зʼїсти_міжрядки(знаки, п, п::адреса);
якщо знаки.дані[п].вид == ВидЗнакуСимволЗакритаДужка {
вихід::вміст = сполука_гнізда;
вихід_позиції_кінця::вміст = п;
вернути так;
} інакше {
позиція_помилки_сполуки_гнізда = п;
звільнити_сполуку(М, сполука_гнізда);
}
}
вихід_позиції_помилки::вміст = позиція_помилки_сполуки_гнізда;
вернути ні;
}
п = позиція_початку;
якщо знаки.дані[п].вид == ВидЗнакуІдентифікатор {
змінна позиція_ідентифікатора = п;
п += 1;
якщо знаки.дані[п].вид == ВидЗнакуТекст {
змінна сполука_тексту = виділити<Сполука>(М, 1);
сполука_тексту.вид = ВидСполукиТекст;
сполука_тексту.дані = ДаніСполукиТекст {
ідентифікатор = можливо<Ідентифікатор> { так, Ідентифікатор { позиція_ідентифікатора } },
позиція_знаку = п
};
сполука_тексту.місцезнаходження = Місцезнаходження { позиція_ідентифікатора };
вихід::вміст = сполука_тексту;
вихід_позиції_кінця::вміст = п;
вернути так;
} інакше якщо знаки.дані[п].вид == ВидЗнакуСимвол {
змінна сполука_символа = виділити<Сполука>(М, 1);
сполука_символа.вид = ВидСполукиСимвол;
сполука_символа.дані = ДаніСполукиСимвол {
ідентифікатор = можливо<Ідентифікатор> { так, Ідентифікатор { позиція_ідентифікатора } },
позиція_знаку = п
};
сполука_символа.місцезнаходження = Місцезнаходження { позиція_ідентифікатора };
вихід::вміст = сполука_символа;
вихід_позиції_кінця::вміст = п;
вернути так;
} інакше якщо знаки.дані[п].вид == ВидЗнакуПочатокЗбитогоТексту {
п += 1;
змінна накопичувач_гілок = зробити_накопичувач<*Сполука>(М);
поки п < знаки.розмір {
змінна сполука_значення: *Сполука = пусто;
змінна позиція_помилки_збитого_тексту: природне = 0;
якщо знаки.дані[п].вид == ВидЗнакуЧастинаЗбитогоТексту {
змінна сполука_тексту = виділити<Сполука>(М, 1);
сполука_тексту.вид = ВидСполукиТекст;
сполука_тексту.дані = ДаніСполукиТекст {
ідентифікатор = можливо<Ідентифікатор> { так, Ідентифікатор { позиція_ідентифікатора } },
позиція_знаку = п
};
сполука_тексту.місцезнаходження = Місцезнаходження { позиція_ідентифікатора };
покласти_в_накопичувач<*Сполука>(М, накопичувач_гілок::адреса, сполука_тексту);
п += 1;
} інакше якщо спробувати_розібрати_значення(М, знаки, п, сполука_значення::адреса, п::адреса, ні, позиція_помилки_збитого_тексту::адреса) {
покласти_в_накопичувач<*Сполука>(М, накопичувач_гілок::адреса, сполука_значення);
п += 1;
} інакше {
вихід_позиції_помилки::вміст = позиція_помилки_збитого_тексту;
звільнити_сполуки(М, Сполуки { накопичувач_гілок.розмір, накопичувач_гілок.дані });
вернути ні;
}
якщо знаки.дані[п].вид == ВидЗнакуРоздільникЗбитогоТексту {
п += 1;
} інакше якщо знаки.дані[п].вид == ВидЗнакуКінецьЗбитогоТексту {
стрибнути вихід_збитого_тексту_з_ідентифікатором;
} інакше {
вихід_позиції_помилки::вміст = п;
звільнити_сполуки(М, Сполуки { накопичувач_гілок.розмір, накопичувач_гілок.дані });
вернути ні;
}
}
вихід_збитого_тексту_з_ідентифікатором:
якщо накопичувач_гілок.розмір == 1 {
змінна сполука = накопичувач_гілок.дані[0];
звільнити(М, накопичувач_гілок.дані);
вихід::вміст = сполука;
вихід_позиції_кінця::вміст = п;
вернути так;
} інакше {
змінна сполука_збитого_тексту = виділити<Сполука>(М, 1);
сполука_збитого_тексту.вид = ВидСполукиЗбитийТекст;
сполука_збитого_тексту.дані = ДаніСполукиЗбитийТекст {
ідентифікатор = можливо<Ідентифікатор> { так, Ідентифікатор { позиція_ідентифікатора } },
кількість_гілок = накопичувач_гілок.розмір,
сполуки = накопичувач_гілок.дані,
};
сполука_збитого_тексту.місцезнаходження = Місцезнаходження { п };
вихід::вміст = сполука_збитого_тексту;
вихід_позиції_кінця::вміст = п;
вернути так;
}
} інакше {
п -= 1;
}
змінна сполука_звернення = виділити<Сполука>(М, 1);
сполука_звернення.вид = ВидСполукиЗвернутись;
сполука_звернення.дані = ДаніСполукиЗвернутись {
ідентифікатор = Ідентифікатор { п }
};
сполука_звернення.місцезнаходження = Місцезнаходження { п };
вихід::вміст = сполука_звернення;
вихід_позиції_кінця::вміст = п;
вернути так;
}
якщо знаки.дані[п].вид == ВидЗнакуЧисло {
змінна сполука_числа = виділити<Сполука>(М, 1);
сполука_числа.вид = ВидСполукиЧисло;
сполука_числа.дані = ДаніСполукиЧисло {
позиція_знаку = п
};
сполука_числа.місцезнаходження = Місцезнаходження { п };
вихід::вміст = сполука_числа;
вихід_позиції_кінця::вміст = п;
вернути так;
}
якщо знаки.дані[п].вид == ВидЗнакуТекст {
змінна сполука_тексту = виділити<Сполука>(М, 1);
сполука_тексту.вид = ВидСполукиТекст;
сполука_тексту.дані = ДаніСполукиТекст {
ідентифікатор = можливо<Ідентифікатор> { ні, ... },
позиція_знаку = п
};
сполука_тексту.місцезнаходження = Місцезнаходження { п };
вихід::вміст = сполука_тексту;
вихід_позиції_кінця::вміст = п;
вернути так;
}
якщо знаки.дані[п].вид == ВидЗнакуСимвол {
змінна сполука_символа = виділити<Сполука>(М, 1);
сполука_символа.вид = ВидСполукиСимвол;
сполука_символа.дані = ДаніСполукиСимвол {
ідентифікатор = можливо<Ідентифікатор> { ні, ... },
позиція_знаку = п
};
сполука_символа.місцезнаходження = Місцезнаходження { п };
вихід::вміст = сполука_символа;
вихід_позиції_кінця::вміст = п;
вернути так;
}
якщо знаки.дані[п].вид == ВидЗнакуПочатокЗбитогоТексту {
п += 1;
змінна накопичувач_гілок = зробити_накопичувач<*Сполука>(М);
поки п < знаки.розмір {
змінна сполука_значення: *Сполука = пусто;
змінна позиція_помилки_збитого_тексту: природне = 0;
якщо знаки.дані[п].вид == ВидЗнакуЧастинаЗбитогоТексту {
змінна сполука_тексту = виділити<Сполука>(М, 1);
сполука_тексту.вид = ВидСполукиТекст;
сполука_тексту.дані = ДаніСполукиТекст {
ідентифікатор = можливо<Ідентифікатор> { ні, ... },
позиція_знаку = п
};
сполука_тексту.місцезнаходження = Місцезнаходження { п };
покласти_в_накопичувач<*Сполука>(М, накопичувач_гілок::адреса, сполука_тексту);
п += 1;
} інакше якщо спробувати_розібрати_значення(М, знаки, п, сполука_значення::адреса, п::адреса, ні, позиція_помилки_збитого_тексту::адреса) {
покласти_в_накопичувач<*Сполука>(М, накопичувач_гілок::адреса, сполука_значення);
п += 1;
} інакше {
вихід_позиції_помилки::вміст = позиція_помилки_збитого_тексту;
звільнити_сполуки(М, Сполуки { накопичувач_гілок.розмір, накопичувач_гілок.дані });
вернути ні;
}
якщо знаки.дані[п].вид == ВидЗнакуРоздільникЗбитогоТексту {
п += 1;
} інакше якщо знаки.дані[п].вид == ВидЗнакуКінецьЗбитогоТексту {
стрибнути вихід_збитого_тексту;
} інакше {
вихід_позиції_помилки::вміст = п;
звільнити_сполуки(М, Сполуки { накопичувач_гілок.розмір, накопичувач_гілок.дані });
вернути ні;
}
}
вихід_збитого_тексту:
якщо накопичувач_гілок.розмір == 1 {
змінна сполука = накопичувач_гілок.дані[0];
звільнити(М, накопичувач_гілок.дані);
вихід::вміст = сполука;
вихід_позиції_кінця::вміст = п;
вернути так;
} інакше {
змінна сполука_збитого_тексту = виділити<Сполука>(М, 1);
сполука_збитого_тексту.вид = ВидСполукиЗбитийТекст;
сполука_збитого_тексту.дані = ДаніСполукиЗбитийТекст {
ідентифікатор = можливо<Ідентифікатор> { ні, ... },
кількість_гілок = накопичувач_гілок.розмір,
сполуки = накопичувач_гілок.дані,
};
сполука_збитого_тексту.місцезнаходження = Місцезнаходження { п };
вихід::вміст = сполука_збитого_тексту;
вихід_позиції_кінця::вміст = п;
вернути так;
}
}
вихід_позиції_помилки::вміст = п;
вернути ні;
}
внутрішня дія спробувати_розібрати_атом(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
змінна п = позиція_початку;
якщо знаки.дані[п].вид == ВидЗнакуСимволКвадратнаВідкритаДужка {
змінна позиція_початку_списку = п;
п += 1;
зʼїсти_міжрядки(знаки, п, п::адреса);
якщо знаки.дані[п].вид == ВидЗнакуСимволКвадратнаЗакритаДужка {
змінна сполука_списку = виділити<Сполука>(М, 1);
сполука_списку.вид = ВидСполукиСписок;
сполука_списку.дані = ДаніСполукиСписок {
кількість_елементів = 0,
елементи = пусто
};
сполука_списку.місцезнаходження = Місцезнаходження { позиція_початку_списку };
вихід::вміст = сполука_списку;
вихід_позиції_кінця::вміст = п;
вернути так;
}
змінна елементи_списку = зробити_накопичувач<*Сполука>(М);
поки п < знаки.розмір {
змінна сполука_значення_елемента: *Сполука = пусто;
змінна позиція_помилки_елемента: природне = 0;
якщо спробувати_розібрати_значення(М, знаки, п, сполука_значення_елемента::адреса, п::адреса, ні, позиція_помилки_елемента::адреса) {
п += 1;
зʼїсти_міжрядки(знаки, п, п::адреса);
} інакше {
звільнити_сполуки(М, Сполуки { елементи_списку.розмір, елементи_списку.дані });
вихід_позиції_помилки::вміст = позиція_помилки_елемента;
вернути ні;
}
покласти_в_накопичувач<*Сполука>(М, елементи_списку::адреса, сполука_значення_елемента);
зʼїсти_міжрядки(знаки, п, п::адреса);
якщо знаки.дані[п].вид == ВидЗнакуСимволКома {
п += 1;
зʼїсти_міжрядки(знаки, п, п::адреса);
якщо знаки.дані[п].вид == ВидЗнакуСимволКвадратнаЗакритаДужка {
змінна сполука_списку = виділити<Сполука>(М, 1);
сполука_списку.вид = ВидСполукиСписок;
сполука_списку.дані = ДаніСполукиСписок {
кількість_елементів = елементи_списку.розмір,
елементи = елементи_списку.дані
};
сполука_списку.місцезнаходження = Місцезнаходження { позиція_початку_списку };
вихід::вміст = сполука_списку;
вихід_позиції_кінця::вміст = п;
вернути так;
}
} інакше якщо знаки.дані[п].вид == ВидЗнакуСимволКвадратнаЗакритаДужка {
змінна сполука_списку = виділити<Сполука>(М, 1);
сполука_списку.вид = ВидСполукиСписок;
сполука_списку.дані = ДаніСполукиСписок {
кількість_елементів = елементи_списку.розмір,
елементи = елементи_списку.дані
};
сполука_списку.місцезнаходження = Місцезнаходження { позиція_початку_списку };
вихід::вміст = сполука_списку;
вихід_позиції_кінця::вміст = п;
вернути так;
} інакше {
звільнити_сполуки(М, Сполуки { елементи_списку.розмір, елементи_списку.дані });
вихід_позиції_помилки::вміст = п;
вернути ні;
}
}
звільнити_сполуки(М, Сполуки { елементи_списку.розмір, елементи_списку.дані });
вихід_позиції_помилки::вміст = п;
вернути ні;
} інакше якщо знаки.дані[п].вид == ВидЗнакуСимволФігурнаВідкритаДужка {
змінна позиція_початку_словника = п;
п += 1;
зʼїсти_міжрядки(знаки, п, п::адреса);
якщо знаки.дані[п].вид == ВидЗнакуСимволФігурнаЗакритаДужка {
змінна сполука_словника = виділити<Сполука>(М, 1);
сполука_словника.вид = ВидСполукиСловник;
сполука_словника.дані = ДаніСполукиСловник {
кількість_елементів = 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;
зʼїсти_міжрядки(знаки, п, п::адреса);
змінна аргументи = зробити_накопичувач<Аргумент>(М);
якщо знаки.дані[п].вид == ВидЗнакуСимволЗакритаДужка {
п += 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;
змінна сполука_значення: *Сполука = пусто;
змінна позиція_помилки_сполуки_значення: природне = 0;
якщо не спробувати_розібрати_значення(М, знаки, п, сполука_значення::адреса, п::адреса, ні, позиція_помилки_сполуки_значення::адреса) {
п -= 1;
}
змінна сполука_впасти = виділити<Сполука>(М, 1);
сполука_впасти.вид = ВидСполукиВпасти;
сполука_впасти.дані = ДаніСполукиВпасти {
значення = сполука_значення
};
сполука_впасти.місцезнаходження = Місцезнаходження { позиція_початку };
вихід::вміст = сполука_впасти;
вихід_позиції_кінця::вміст = п;
вернути так;
}
внутрішня дія спробувати_розібрати_елемент_взяти(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: *ЕлементВзяти, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
змінна п = позиція_початку;
змінна позиція_ідентифікатора = п;
якщо знаки.дані[п].вид != ВидЗнакуІдентифікатор {
вихід_позиції_помилки::вміст = п;
вернути ні;
}
п += 1;
змінна має_ідентифікатор_як = ні;
змінна позиція_ідентифікатора_як = п + 1;
якщо знаки.дані[п].вид == ВидЗнакуЯк {
п += 1;
якщо знаки.дані[п].вид != ВидЗнакуІдентифікатор {
вихід_позиції_помилки::вміст = п;
вернути ні;
}
має_ідентифікатор_як = так;
позиція_ідентифікатора_як = п;
} інакше {
п -= 1;
}
вихід::вміст = ЕлементВзяти {
ідентифікатор = Ідентифікатор { позиція_ідентифікатора },
ідентифікатор_як = можливо<Ідентифікатор> { має_ідентифікатор_як, Ідентифікатор { позиція_ідентифікатора_як } },
місцезнаходження = Місцезнаходження { позиція_початку }
};
вихід_позиції_кінця::вміст = п;
вернути так;
}
внутрішня дія спробувати_розібрати_взяти(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
змінна п = позиція_початку;
змінна шлях = зробити_накопичувач<Ідентифікатор>(М);
якщо знаки.дані[п].вид != ВидЗнакуВзяти {
звільнити_накопичувач<Ідентифікатор>(М, шлях);
вихід_позиції_помилки::вміст = п;
вернути ні;
}
п += 1;
змінна позиція_виду_взяти = п;
якщо знаки.дані[п].вид == ВидЗнакуМодуль {
п += 1;
} інакше якщо знаки.дані[п].вид == ВидЗнакуІдентифікатор {
п += 1;
} інакше {
звільнити_накопичувач<Ідентифікатор>(М, шлях);
вихід_позиції_помилки::вміст = п;
вернути ні;
}
поки п < знаки.розмір {
якщо знаки.дані[п].вид == ВидЗнакуІдентифікатор {
покласти_в_накопичувач<Ідентифікатор>(М, шлях::адреса, Ідентифікатор { п });
п += 1;
якщо знаки.дані[п].вид == ВидЗнакуСимволКрапка {
п += 1;
} інакше {
стрибнути після_шляху;
}
} інакше {
звільнити_накопичувач<Ідентифікатор>(М, шлях);
вихід_позиції_помилки::вміст = п;
вернути ні;
}
}
після_шляху:
якщо знаки.дані[п].вид == ВидЗнакуЯк {
п += 1;
змінна ідентифікатор_як = п;
якщо знаки.дані[п].вид != ВидЗнакуІдентифікатор {
звільнити_накопичувач<Ідентифікатор>(М, шлях);
вихід_позиції_помилки::вміст = п;
вернути ні;
}
змінна сполука_взяти = виділити<Сполука>(М, 1);
сполука_взяти.вид = ВидСполукиВзяти;
сполука_взяти.дані = ДаніСполукиВзяти {
тип = можливо<Ідентифікатор> { так, Ідентифікатор { позиція_виду_взяти } },
довжина_шляху = шлях.розмір,
шлях = шлях.дані,
ідентифікатор_як = можливо<Ідентифікатор> { так, Ідентифікатор { ідентифікатор_як } },
кількість_елементів = 0,
елементи = пусто
};
сполука_взяти.місцезнаходження = Місцезнаходження { позиція_початку };
вихід::вміст = сполука_взяти;
вихід_позиції_кінця::вміст = п;
вернути так;
} інакше якщо знаки.дані[п].вид == ВидЗнакуСимволКвадратнаВідкритаДужка {
п += 1;
змінна елементи = зробити_накопичувач<ЕлементВзяти>(М);
поки п < знаки.розмір {
змінна елемент_взяти = ЕлементВзяти { ... };
змінна позиція_помилки_елемента_взяти: природне = 0;
якщо спробувати_розібрати_елемент_взяти(М, знаки, п, елемент_взяти::адреса, п::адреса, позиція_помилки_елемента_взяти::адреса) {
покласти_в_накопичувач<ЕлементВзяти>(М, елементи::адреса, елемент_взяти);
п += 1;
якщо знаки.дані[п].вид == ВидЗнакуСимволКома {
п += 1;
} інакше якщо знаки.дані[п].вид == ВидЗнакуСимволКвадратнаЗакритаДужка {
змінна сполука_взяти = виділити<Сполука>(М, 1);
сполука_взяти.вид = ВидСполукиВзяти;
сполука_взяти.дані = ДаніСполукиВзяти {
тип = можливо<Ідентифікатор> { так, Ідентифікатор { позиція_виду_взяти } },
довжина_шляху = шлях.розмір,
шлях = шлях.дані,
ідентифікатор_як = можливо<Ідентифікатор> { ні, ... },
кількість_елементів = елементи.розмір,
елементи = елементи.дані
};
сполука_взяти.місцезнаходження = Місцезнаходження { позиція_початку };
вихід::вміст = сполука_взяти;
вихід_позиції_кінця::вміст = п;
вернути так;
} інакше {
звільнити_накопичувач<Ідентифікатор>(М, шлях);
звільнити_накопичувач<ЕлементВзяти>(М, елементи);
вихід_позиції_помилки::вміст = п;
вернути ні;
}
} інакше {
звільнити_накопичувач<Ідентифікатор>(М, шлях);
звільнити_накопичувач<ЕлементВзяти>(М, елементи);
вихід_позиції_помилки::вміст = позиція_помилки_елемента_взяти;
вернути ні;
}
}
звільнити_накопичувач<Ідентифікатор>(М, шлях);
звільнити_накопичувач<ЕлементВзяти>(М, елементи);
вихід_позиції_помилки::вміст = п;
вернути ні;
} інакше {
змінна сполука_взяти = виділити<Сполука>(М, 1);
сполука_взяти.вид = ВидСполукиВзяти;
сполука_взяти.дані = ДаніСполукиВзяти {
тип = можливо<Ідентифікатор> { так, Ідентифікатор { позиція_виду_взяти } },
довжина_шляху = шлях.розмір,
шлях = шлях.дані,
ідентифікатор_як = можливо<Ідентифікатор> { ні, ... },
кількість_елементів = 0,
елементи = пусто
};
сполука_взяти.місцезнаходження = Місцезнаходження { позиція_початку };
вихід::вміст = сполука_взяти;
вихід_позиції_кінця::вміст = п - 1;
вернути так;
}
звільнити_накопичувач<Ідентифікатор>(М, шлях);
вихід_позиції_помилки::вміст = п;
вернути ні;
}
внутрішня дія спробувати_розібрати_елемент_дати(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: *ЕлементДати, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
змінна п = позиція_початку;
змінна позиція_ідентифікатора = п;
якщо знаки.дані[п].вид != ВидЗнакуІдентифікатор {
вихід_позиції_помилки::вміст = п;
вернути ні;
}
п += 1;
змінна має_ідентифікатор_як = ні;
змінна позиція_ідентифікатора_як = п + 1;
якщо знаки.дані[п].вид == ВидЗнакуЯк {
п += 1;
якщо знаки.дані[п].вид != ВидЗнакуІдентифікатор {
вихід_позиції_помилки::вміст = п;
вернути ні;
}
має_ідентифікатор_як = так;
позиція_ідентифікатора_як = п;
} інакше {
п -= 1;
}
вихід::вміст = ЕлементДати {
ідентифікатор = Ідентифікатор { позиція_ідентифікатора },
ідентифікатор_як = можливо<Ідентифікатор> { має_ідентифікатор_як, Ідентифікатор { позиція_ідентифікатора_як } },
місцезнаходження = Місцезнаходження { позиція_початку }
};
вихід_позиції_кінця::вміст = п;
вернути так;
}
внутрішня дія спробувати_розібрати_дати(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
змінна п = позиція_початку;
якщо знаки.дані[п].вид != ВидЗнакуДати {
вихід_позиції_помилки::вміст = п;
вернути ні;
}
п += 1;
змінна елементи = зробити_накопичувач<ЕлементДати>(М);
поки п < знаки.розмір {
змінна елемент_дати = ЕлементДати { ... };
змінна позиція_помилки_елемента_дати: природне = 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;
якщо спробувати_розібрати_елемент_тіла(М, знаки, п, сполука_елемента_тіла::адреса, п::адреса, позиція_помилки_елемента_тіла::адреса) {
покласти_в_накопичувач<*Сполука>(М, елементи::адреса, сполука_елемента_тіла);
п += 1;
якщо зʼїсти_міжрядки(знаки, п, п::адреса) {
} інакше якщо знаки.дані[п].вид == вид_знаку_закінчення {
вихід::вміст = Сполуки { елементи.розмір, елементи.дані };
вихід_позиції_кінця::вміст = п;
вернути так;
} інакше {
звільнити_сполуки(М, Сполуки { елементи.розмір, елементи.дані });
вихід_позиції_помилки::вміст = п;
вернути ні;
}
} інакше {
звільнити_сполуки(М, Сполуки { елементи.розмір, елементи.дані });
вихід_позиції_помилки::вміст = позиція_помилки_елемента_тіла;
вернути ні;
}
}
звільнити_сполуки(М, Сполуки { елементи.розмір, елементи.дані });
вихід_позиції_помилки::вміст = п;
вернути ні;
}
внутрішня дія спробувати_розібрати_тип(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: *Тип, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
змінна п = позиція_початку;
змінна типи = зробити_накопичувач<*Сполука>(М);
поки п < знаки.розмір {
змінна сполука_типу: *Сполука = пусто;
змінна позиція_помилки_молекули: природне = 0;
якщо спробувати_розібрати_молекулу(М, знаки, п, сполука_типу::адреса, п::адреса, позиція_помилки_молекули::адреса) {
покласти_в_накопичувач<*Сполука>(М, типи::адреса, сполука_типу);
п += 1;
якщо знаки.дані[п].вид == ВидЗнакуАбо {
п += 1;
} інакше {
вихід::вміст = Тип {
кількість_гілок = типи.розмір,
сполуки = типи.дані,
};
вихід_позиції_кінця::вміст = п - 1;
вернути так;
}
} інакше {
звільнити_сполуки(М, Сполуки { типи.розмір, типи.дані });
вихід_позиції_помилки::вміст = позиція_помилки_молекули;
вернути ні;
}
}
звільнити_сполуки(М, Сполуки { типи.розмір, типи.дані });
вихід_позиції_помилки::вміст = п;
вернути ні;
}
внутрішня дія спробувати_розібрати_параметр(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: *Параметр, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
змінна п = позиція_початку;
змінна сполука_значення: *Сполука = пусто;
// ідентифікатор параметра
змінна позиція_ідентифікатора = п;
якщо знаки.дані[п].вид != ВидЗнакуІдентифікатор і знаки.дані[п].вид != ВидЗнакуЧисло {
вихід_позиції_помилки::вміст = п;
вернути ні;
}
п += 1;
// тип параметра
змінна тип = Тип { ... };
змінна позиція_помилки_типу: природне = 0;
якщо спробувати_розібрати_тип(М, знаки, п, тип::адреса, п::адреса, позиція_помилки_типу::адреса) {
п += 1;
якщо знаки.дані[п].вид == ВидЗнакуСимволРівно {
п += 1;
змінна позиція_помилки_сполуки_значення: природне = 0;
якщо спробувати_розібрати_значення(М, знаки, п, сполука_значення::адреса, п::адреса, ні, позиція_помилки_сполуки_значення::адреса) {
} інакше {
звільнити_тип(М, тип);
вихід_позиції_помилки::вміст = позиція_помилки_сполуки_значення;
вернути ні;
}
} інакше {
п -= 1;
}
вихід::вміст = Параметр {
ідентифікатор = Ідентифікатор { позиція_ідентифікатора },
тип = можливо<Тип> { так, тип },
значення = сполука_значення,
місцезнаходження = Місцезнаходження { позиція_початку }
};
вихід_позиції_кінця::вміст = п;
} інакше {
якщо знаки.дані[п].вид == ВидЗнакуСимволРівно {
п += 1;
змінна позиція_помилки_сполуки_значення: природне = 0;
якщо спробувати_розібрати_значення(М, знаки, п, сполука_значення::адреса, п::адреса, ні, позиція_помилки_сполуки_значення::адреса) {
} інакше {
звільнити_сполуку(М, сполука_значення);
вихід_позиції_помилки::вміст = позиція_помилки_сполуки_значення;
вернути ні;
}
} інакше {
п -= 1;
}
вихід::вміст = Параметр {
ідентифікатор = Ідентифікатор { позиція_ідентифікатора },
тип = можливо<Тип> { ні, ... },
значення = сполука_значення,
місцезнаходження = Місцезнаходження { позиція_початку }
};
вихід_позиції_кінця::вміст = п;
}
вернути так;
}
внутрішня дія спробувати_розібрати_дію(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
змінна дані_сполуки_дія = ДаніСполукиДія {
тривала = ні,
власна = ні,
клас = пусто,
ідентифікатор = можливо<Ідентифікатор> { ні, ... },
кількість_параметрів = 0,
параметри = пусто,
тип_результату = можливо<Тип> { ні, ... },
тіло = Сполуки { 0, пусто }
};
змінна п = позиція_початку;
// дія власна?
якщо знаки.дані[п].вид == ВидЗнакуВласна {
дані_сполуки_дія.власна = так;
п += 1;
}
// дія тривала?
якщо знаки.дані[п].вид == ВидЗнакуТривала {
дані_сполуки_дія.тривала = так;
п += 1;
}
// дія?
якщо знаки.дані[п].вид != ВидЗнакуДія {
вихід_позиції_помилки::вміст = п;
стрибнути звільнити_і_вийти;
}
п += 1;
// клас та/або ідентифікатор дії
якщо знаки.дані[п].вид == ВидЗнакуІдентифікатор {
дані_сполуки_дія.ідентифікатор = можливо<Ідентифікатор> { так, Ідентифікатор { п } };
п += 1;
якщо знаки.дані[п].вид == ВидЗнакуСимволКрапка {
п += 1;
якщо знаки.дані[п].вид == ВидЗнакуІдентифікатор {
змінна сполука_звернення = виділити<Сполука>(М, 1);
сполука_звернення.вид = ВидСполукиЗвернутись;
сполука_звернення.дані = ДаніСполукиЗвернутись {
ідентифікатор = дані_сполуки_дія.ідентифікатор.значення
};
сполука_звернення.місцезнаходження = Місцезнаходження { п };
дані_сполуки_дія.клас = сполука_звернення;
дані_сполуки_дія.ідентифікатор = можливо<Ідентифікатор> { так, Ідентифікатор { п } };
п += 1;
} інакше {
вихід_позиції_помилки::вміст = п;
стрибнути звільнити_і_вийти;
}
}
}
якщо знаки.дані[п].вид != ВидЗнакуСимволВідкритаДужка {
вихід_позиції_помилки::вміст = п;
стрибнути звільнити_і_вийти;
}
п += 1;
зʼїсти_міжрядки(знаки, п, п::адреса);
// параметри дії
змінна параметри = зробити_накопичувач<Параметр>(М);
поки п < знаки.розмір {
якщо знаки.дані[п].вид == ВидЗнакуСимволЗакритаДужка {
п += 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;
якщо спробувати_розібрати_параметр(М, знаки, п, параметр::адреса, п::адреса, позиція_помилки_параметра::адреса) {
покласти_в_накопичувач<Параметр>(М, параметри::адреса, параметр);
п += 1;
} інакше якщо спробувати_розібрати_дію(М, знаки, п, сполука_дії::адреса, п::адреса, позиція_помилки_дії::адреса) {
покласти_в_накопичувач<*Сполука>(М, методи::адреса, сполука_дії);
п += 1;
} інакше {
вихід_позиції_помилки::вміст = позиція_помилки_параметра;
стрибнути звільнити_і_вийти;
}
якщо зʼїсти_міжрядки(знаки, п, п::адреса) {
} інакше якщо знаки.дані[п].вид == ВидЗнакуКінець {
стрибнути ок;
} інакше {
звільнити_параметри(М, параметри.розмір, параметри.дані);
вихід_позиції_помилки::вміст = п;
стрибнути звільнити_і_вийти;
}
}
ок:
дані_сполуки_клас.кількість_параметрів = параметри.розмір;
дані_сполуки_клас.параметри = параметри.дані;
дані_сполуки_клас.методи = Сполуки {
розмір = методи.розмір,
дані = методи.дані
};
змінна сполука_клас = виділити<Сполука>(М, 1);
сполука_клас.вид = ВидСполукиКлас;
сполука_клас.дані = дані_сполуки_клас;
сполука_клас.місцезнаходження = Місцезнаходження {
позиція_початку
};
вихід::вміст = сполука_клас;
вихід_позиції_кінця::вміст = п;
вернути так;
звільнити_і_вийти:
звільнити_сполуку(М, дані_сполуки_клас.предок);
звільнити_параметри(М, дані_сполуки_клас.кількість_параметрів, дані_сполуки_клас.параметри);
вернути ні;
}
внутрішня дія спробувати_розібрати_модуль(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
змінна дані_сполуки_модуль = ДаніСполукиМодуль {
ідентифікатор = можливо<Ідентифікатор> { ні, ... },
тіло = Сполуки { 0, пусто }
};
змінна п = позиція_початку;
// модуль?
якщо знаки.дані[п].вид != ВидЗнакуМодуль {
вихід_позиції_помилки::вміст = п;
стрибнути звільнити_і_вийти;
}
п += 1;
// ідентифікатор модуля
якщо знаки.дані[п].вид == ВидЗнакуІдентифікатор {
дані_сполуки_модуль.ідентифікатор = можливо<Ідентифікатор> { так, Ідентифікатор { п } };
п += 1;
}
якщо знаки.дані[п].вид != ВидЗнакуСимволМіжряд {
вихід_позиції_помилки::вміст = п;
стрибнути звільнити_і_вийти;
}
п += 1;
// тіло модуля
змінна позиція_помилки_тіла: природне = 0;
якщо спробувати_розібрати_тіло(М, знаки, п, дані_сполуки_модуль.тіло::адреса, п::адреса, ВидЗнакуКінець, позиція_помилки_тіла::адреса) == ні {
вихід_позиції_помилки::вміст = позиція_помилки_тіла;
стрибнути звільнити_і_вийти;
}
змінна сполука_модуль = виділити<Сполука>(М, 1);
сполука_модуль.вид = ВидСполукиМодуль;
сполука_модуль.дані = дані_сполуки_модуль;
сполука_модуль.місцезнаходження = Місцезнаходження {
позиція_початку
};
вихід::вміст = сполука_модуль;
вихід_позиції_кінця::вміст = п;
вернути так;
звільнити_і_вийти:
звільнити_тіло(М, дані_сполуки_модуль.тіло);
вернути ні;
}
внутрішня дія спробувати_розібрати_якщо(М: *Машина, знаки: Знаки, позиція_початку: природне, вихід: **Сполука, вихід_позиції_кінця: *природне, вихід_позиції_помилки: *природне) -> логічне {
змінна дані_сполуки_якщо = ДаніСполукиЯкщо {
умова = пусто,
тіло = Сполуки { 0, пусто },
тіло_інакше = Сполуки { 0, пусто }
};
змінна п = позиція_початку;
// якщо?
якщо знаки.дані[п].вид != ВидЗнакуЯкщо {
вихід_позиції_помилки::вміст = п;
стрибнути звільнити_і_вийти;
}
п += 1;
// умова якщо
змінна позиція_помилки_умови: природне = 0;
якщо спробувати_розібрати_операцію(М, знаки, п, дані_сполуки_якщо.умова::адреса, п::адреса, ні, позиція_помилки_умови::адреса) {
п += 1;
} інакше {
вихід_позиції_помилки::вміст = позиція_помилки_умови;
стрибнути звільнити_і_вийти;
}
якщо знаки.дані[п].вид != ВидЗнакуСимволМіжряд {
вихід_позиції_помилки::вміст = п;
стрибнути звільнити_і_вийти;
}
п += 1;
// тіло якщо
змінна тіло = зробити_накопичувач<*Сполука>(М);
поки п < знаки.розмір {
якщо знаки.дані[п].вид == ВидЗнакуКінець {
дані_сполуки_якщо.тіло.розмір = тіло.розмір;
дані_сполуки_якщо.тіло.дані = тіло.дані;
стрибнути після_тіла;
}
якщо знаки.дані[п].вид == ВидЗнакуІнакше {
дані_сполуки_якщо.тіло.розмір = тіло.розмір;
дані_сполуки_якщо.тіло.дані = тіло.дані;
стрибнути розбір_інакше;
}
зʼїсти_міжрядки(знаки, п, п::адреса);
змінна сполука_елемента_тіла: *Сполука = пусто;
змінна позиція_помилки_елемента_тіла: природне = 0;
якщо спробувати_розібрати_елемент_тіла(М, знаки, п, сполука_елемента_тіла::адреса, п::адреса, позиція_помилки_елемента_тіла::адреса) {
покласти_в_накопичувач<*Сполука>(М, тіло::адреса, сполука_елемента_тіла);
п += 1;
якщо зʼїсти_міжрядки(знаки, п, п::адреса) {
} інакше якщо знаки.дані[п].вид == ВидЗнакуКінець {
дані_сполуки_якщо.тіло.розмір = тіло.розмір;
дані_сполуки_якщо.тіло.дані = тіло.дані;
стрибнути після_тіла;
} інакше якщо знаки.дані[п].вид == ВидЗнакуІнакше {
дані_сполуки_якщо.тіло.розмір = тіло.розмір;
дані_сполуки_якщо.тіло.дані = тіло.дані;
стрибнути розбір_інакше;
} інакше {
дані_сполуки_якщо.тіло.розмір = тіло.розмір;
дані_сполуки_якщо.тіло.дані = тіло.дані;
вихід_позиції_помилки::вміст = п;
стрибнути звільнити_і_вийти;
}
} інакше {
дані_сполуки_якщо.тіло.розмір = тіло.розмір;
дані_сполуки_якщо.тіло.дані = тіло.дані;
вихід_позиції_помилки::вміст = позиція_помилки_елемента_тіла;
стрибнути звільнити_і_вийти;
}
}
вихід_позиції_помилки::вміст = п;
стрибнути звільнити_і_вийти;
розбір_інакше:
п += 1;
// інакше якщо
якщо знаки.дані[п].вид == ВидЗнакуЯкщо {
змінна сполука_інакше_якщо: *Сполука = пусто;
змінна позиція_помилки_інакше_якщо: природне = 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;
}
звільнити(М, сполуки.дані);
}
дія звільнити_помилку_розбору_на_сполуки(М: *Машина, помилка: ПомилкаРозборуНаСполуки) {
// ...
}
дія отримати_помилку_розбору_на_сполуки(М: *Машина, помилка: ПомилкаРозборуНаСполуки, вихід: *кд) -> логічне {
виділити_копію_кд(М, "Не вдалось розібрати", вихід);
вернути так;
}
дія отримати_рядок_помилки_розбору_на_сполуки(М: *Машина, помилка: ПомилкаРозборуНаСполуки) -> природне {
вернути помилка.рядок;
}
дія отримати_стовпець_помилки_розбору_на_сполуки(М: *Машина, помилка: ПомилкаРозборуНаСполуки) -> природне {
вернути помилка.стовпець;
}
}
}