Транслятор – це… Види трансляторів. Перетворення та трансляція програми. Стандарти мови програмування C. Узагальнена структура транслятора

Для перекладу з однієї мови на іншу програмам, як і людям, потрібен перекладач або, говорячи по-науковому, транслятор.

Транслятор: основні поняття

Така програма як транслятор є лінгвістичним уявленням обчислень I ->P ->P (i). Інтерпретатор є програмою, на вхід якої подається програма P з деякими вхідними даними X. Виконує він P на X: I(P, x)=P(x). Існує єдиний транслятор, який здатний виконувати все можливі програми(які можна у формальної системі). Це дуже значним і глибоким відкриттям Тьюринга. Процесор є інтерпретатором програм на машинною мовою. Писати інтерпретатори для мов високого рівня, як правило, занадто дорого, тому їх транслюють у форму, яку легше інтерпретувати. Деякі види трансляторів мають дуже дивні імена. Програма транслює програми на асемблері в машинну мову. Компілятор дозволяє транслювати з мови високого рівня мову нижчого рівня. Транслятор являє собою програму, яка як вхідні дані приймає програму деякою мовою S і після обробки видає програму мовою T. Таким чином, вони обидві мають ту ж семантику: P->X->Q. Таким чином, для будь-якого xP(x) = Q(x). Якщо транслювати всю програму на щось інтерпретоване, це називається компіляцією перед виконанням чи компіляцією AOT. Компілятори AOT можна використовувати послідовно. Останній дуже часто є асемблером. Так, розглянемо приклад: Вихідний код -> Компілятор (транслятор) -> Асемблерний код -> Асемблер (транслятор) -> Машинний код -> ЦПУ (інтерпретатор). Динамічна чи оперативна компіляція здійснюється у тому випадку, якщо частина програми транслюється, коли виконуються інші скомпільовані раніше частини. Транслятори JIT запам'ятовують те, що вони виконали раніше, щоб знову і знову не повторювати вихідний код. Вони навіть здатні виконувати адаптивну компіляцію та перекомпіляцію, яка заснована на поведінці середовища виконання програми. Багато мов дають можливість виконувати код під час трансляції, а також компілювати новий кодпід час виконання програми.

Трансляція: етапи

Процес трансляції складається з етапів синтезу та аналізу. Схематично цей процес виглядає приблизно так: Вихідний код -> Аналізатор -> Концептуальне уявлення -> Синтезатор (генератор) -> Цільовий код. Зумовлено це такими причинами:

- будь-який інший спосіб просто не підходить;

— переклад за словами просто не працює.

Можна використовувати наступне інженерне рішення: якщо необхідно написати транслятори M вихідних мов і N цільових, потрібно написати тільки M+N простих програм (напівкомпіляторів), а не MxN повних (комплексних) трансляторів. На практиці, проте, концептуальне уявлення досить рідко буває виразним і потужним, щоб охопити всі цільові і вихідні мови. Хоча деякі користувачі змогли наблизитись до цього. Реальні компілятори проходять через багато різних етапів. При створенні власного компілятора не потрібно буде знову проводити всю важку роботу, яку програмісти вже проробили при створенні генераторів і уявлень. Свою мову можна транслювати безпосередньо на JavaScript або C і використовувати для цієї мети існуючі компілятори мови C і JavaScript движки для того, щоб зробити все інше. Можна також використовувати існуючі проміжні уявлення та віртуальні машини.

Запис транслятора

Транслятор може являти собою технічний засіб або програму, в якій використовуються три мови: вихідна, цільова, базисна. Записати їх можна у формі T, розташувавши ліворуч вихідний, праворуч цільовий і нижче базисний. Усього існує три види компіляторів.

  1. Транслятор - це самокомпілятор, якщо вихідна мова у нього відповідає базисному.
  2. Саморезидентним називається компілятор, у якого цільова мова дорівнює базисному.
  3. Якщо цільовий та базовий мови різні, то транслятор – це крос-компілятор.

Чому важливо розрізняти ці типи компіляторів? Навіть якщо ви ніколи не створите по-справжньому якісний компілятор, непогано буде дізнатися про технологію його створення, оскільки всі концепції, що використовуються для цієї мети, застосовуються повсюдно в мовах запитів до баз даних, при форматуванні текстів, у розширених комп'ютерних архітектурах, графічних інтерфейсах, узагальнених задачах оптимізації, машинних перекладах, контролерах та у віртуальних машинах. Також, якщо необхідно написати препроцесори, завантажувачі, збирачі, відладчики або профільники, необхідно пройти через ті самі етапи, що і при написанні компілятора. Можна також дізнатися про те, як краще писати програми, оскільки розробка транслятора для мови програмування означає найкраще розуміння всіх його неясностей і тонкощів. Завдяки вивченню загальних принципів трансляції ви можете стати хорошим дизайнероммови. Але чи справді це важливо? Наскільки крута мова, якщо вона не може бути ефективно реалізована?

Масштабна технологія

Технологія компілятора охоплює широке коло різних галузей інформатики. У нього входять формальна теорія мови, граматика, комп'ютерна архітектура, парсинг, обчислюваність, набори інструкцій, CISC або RISC, конвеєрна обробка, тактові цикли, ядра тощо, а також управління послідовністю виконання, рекурсії, умовне виконання, функціональне розкладання, ітерації, модульність, синхронізація, метапрограмування, константи, область видимості, шаблони, тип виводу, анотації, прототипи, потоки, поштові скриньки, монади, групові символи, продовження, транзакційну пам'ять, регулярні вирази, поліморфізм, успадкування, режими параметрів і т.п. Також для створення компілятора необхідно розбиратися в абстрактних мовах програмування, алгоритмах та структурі даних, регулярних виразах, графічних алгоритмах, динамічному програмуванні.

Проектування компілятора Можливі проблеми, що виникають під час створення реального транслятора

Які проблеми можуть виникати із вихідною мовою? Чи легко його скомпілювати? Чи є для цього препроцесор? Як обробляються типи? Яке угруповання проходів компілятора використовується – одно- чи багатоходове? Також на особливу увагу заслуговує бажаний ступінь оптимізації. Швидка та нечиста трансляція програми практично без оптимізації може бути нормальною. Надмірна оптимізація може гальмувати компілятор, проте під час виконання найкращий кодможе того вартувати.

Ступінь виявлення помилок. Чи потрібно, щоб транслятор зупинився на першій помилці? Коли він має зупинитися? Чи варто довіряти компілятор процедуру виправлення помилок?

Необхідний набір інструментів

Якщо у вашому випадку вихідна мова є не дуже маленькою, то наявність генератора аналізаторів і сканера є обов'язковою умовою. Також існують і спеціальні генератори коду, але вони не набули надто великого поширення.

Щодо виду цільового коду для генерації, тут необхідно вибирати з чистого, доповненого або віртуального машинного коду. Також можна написати вхідну частину, яка створює популярні проміжні уявлення, такі як LLVM, JVM, RTL. Можна також зробити трансляцію з вихідного в вихідний код Java Script або C. Якщо говорити про формат цільового коду, тут тут можна вибрати переносний машинний код, машинний код пам'яті, мова асемблера.

Перенацілювання

При використанні великої кількості генераторів непогано було б мати загальну вхідну частину. Також з цієї причини для багатьох вхідних частин краще мати один генератор.

Компоненти компілятора

Перерахуємо головні функціональні компонентитранслятора, який генерує машинний код, якщо вихідною програмою є програма, написана мовою C або віртуальна машина:

- Вхідна програма надходить у лексичний аналізатор, або по-іншому сканер, який перетворює її на потік токенів;

— синтаксичний аналізатор (парсер) будує їх абстрактне синтаксичне дерево;

— семантичний аналізатор розкладає семантичну інформацію та перевіряє щодо наявності помилок вузли дерева;

— у результаті будується семантичний граф. Під цим терміном розуміють абстрактне синтаксичне дерево із встановленими посиланнями та додатковими властивостями;

- Генератор проміжного коду будує граф потоку (кортежі групуються в основні блоки);

- машинонезалежний оптимізатор проводить локальну та глобальну оптимізацію, але в основному залишається в рамках підпрограм, при цьому спрощує обчислення та скорочує надлишковий код. В результаті має вийти модифікований граф потоку;

— для зв'язку базових блоків прямолінійний код з передачею управління використовується генератор цільового коду. Він створює на асемблері об'єктний файл із візуальними регістрами, можливо не надто ефективними;

— для розподілу пам'яті між віртуальними регістрами та виконання планування команд використовується машинозалежний оптимізатор-компонувальник. Він також здійснює перетворення програми, написаної на асемблері, справжній асемблер із застосуванням конвеєрної обробки.

- використовуються підсистеми виявлення помилок та менеджер таблиць символів;

- сканування та лексичний аналіз. Сканер використовується для конвертації потоку символів вихідного коду в потік токенів, забираючи коментарі, пробіли та розширюючи макроси. Досить часто сканери зустрічаються з такою проблемою, чи брати до уваги відступи, регістр, вкладені коментарі.

Ті помилки, які можуть зустрітися під час сканування, називаються лексичними. Вони включають такі:

- Відсутні в алфавіті символи;

- Перевищення кількості знаків у рядку або слові;

- Не закритий рядковий літерал або знак;

- Кінець файлу в коментарі.

Синтаксичний аналіз або парсинг застосовується для перетворення послідовності токенів на абстрактне синтаксичне дерево. У цьому кожен вузол дерева зберігається як об'єкт із іменованими полями. Багато хто з них сам є вузлами дерева. Цикли цьому етапі відсутні. При створенні парсера потрібно в першу чергу звертати увагу на рівень складності граматики (LR або LL) та з'ясувати, чи є якісь правила зняття неоднозначності. Деякі мови вимагають проведення семантичного аналізу. Помилки, що зустрічаються на даному етапі, називаються синтаксичними.

Семантичний аналіз

При проведенні семантичного аналізу необхідно передусім перевірити правила допустимості і зв'язати в одне ціле частини синтаксичного дерева для формування семантичного графа шляхом вставки операції для неявного приведення типів, дозволу посилань імен тощо. Зрозуміло, різні мови програмування мають різний набір правил допустимості. Якщо компіляція Java-подібних мов здійснюється, транслятори можуть виявити такі помилки:

- множинні оголошення змінної в межах сфери її дії;

- Порушення правил доступності;

- Наявність посилань на неоголошене ім'я;

— надто велика чи, навпаки, недостатня кількість аргументів під час виклику методу;

- Невідповідність типів.

Генерація

Шляхом генерації проміжного коду виробляється граф потоку, що складається з кортежів, згрупованих у базові блоки. Після створення коду виходить реальний машинний код. На першому етапі у традиційних компіляторах для машин RISC на першому етапі створюється асемблер з нескінченною кількістю віртуальних регістрів. Ймовірно, цього не станеться для машин CISC.

  • Адресний. Функціональний пристрій, що перетворює віртуальну адресу (англ. Virtual address) на реальну адресу.
  • Діалоговий. Забезпечує використання мови програмування в режимі розподілу часу.
  • Багатопрохідний. Формує об'єктний модуль за декілька переглядів вихідної програми.
  • Зворотній. Те саме, що детранслятор. також: декомпілятор, дизассемблер.
  • Однопрохідний. Формує об'єктний модуль за послідовний перегляд вихідної програми.
  • Оптимізуючий. Виконує оптимізацію коду в об'єктному модулі, що створюється.
  • Синтаксично-орієнтований (синтаксично-керований).Отримує на вхід опис синтаксису та семантики мови та текст описаною мовою, який і транслюється відповідно до заданого опису.
  • Тестовий. Набір макрокоманд мови асемблера, що дозволяють задавати різні процедури налагодження в програмах, складених мовою асемблера.

Мета трансляції- перетворити текст з однієї мови на іншу, яка зрозуміла адресату тексту. У випадку програм-трансляторів адресатом є технічний пристрій (процесор) або програма-інтерпретатор.

Мова процесорів (машинний код) зазвичай є низькорівневим. Існують платформи, що використовують як машинну мову високого рівня (наприклад, iAPX-432), але вони є винятком з правила через складність і дорожнечу. Транслятор, який перетворює програми на машинну мову, який приймається і виконується безпосередньо процесором, називається компілятором.

Процес компіляції зазвичай складається з кількох етапів: лексичного, синтаксичного та семантичного аналізів (англ. Semantic analysis), генерації проміжного коду, оптимізації та генерації результуючого машинного коду. Крім цього, програма зазвичай залежить від сервісів, що надаються операційною системою та сторонніми бібліотеками (наприклад, файлове введення-виведення або графічний інтерфейс), і машинний код програми необхідно зв'язати з цими сервісами. Зв'язування зі статичними бібліотеками виконується редактором зв'язків або компонувальником (який може являти собою окрему програмуабо бути частиною компілятора), а з операційною системою та динамічними бібліотеками зв'язування виконується на початку виконання програми завантажувачем.

Перевага компілятора: програма компілюється один раз і при кожному виконанні не потрібно додаткових перетворень. Відповідно, не потрібна наявність компілятора на цільовій машині, на яку компілюється програма. Недолік: окремий етап компіляції уповільнює написання та налагодження та ускладнює виконання невеликих, нескладних чи разових програм.

Інший метод реалізації – коли програма виконується за допомогою інтерпретаторавзагалі без трансляції. Інтерпретатор програмно моделює машину, цикл вибірки виконання якої працює з командами мовами високого рівня, а не з машинними командами. Таке програмне моделюваннястворює віртуальну машину, що реалізує мову. Цей підхід називається чистою інтерпретацією. Чиста інтерпретація застосовується зазвичай для мов із простою структурою (наприклад, АПЛ чи Лисп). Інтерпретатори командного рядкаобробляють команди в скриптах UNIX або в пакетних файлах(.bat) в MS-DOS також зазвичай у режимі чистої інтерпретації.

Гідність інтерпретатора: відсутність проміжних дій для трансляції спрощує реалізацію інтерпретатора і робить його зручнішим у використанні, у тому числі в діалоговому режимі. Недолік - інтерпретатор має бути в наявності на цільовій машині, де має виконуватися програма.

Існують компромісні між компіляцією та чистою інтерпретацією варіанти реалізації мов програмування, коли інтерпретатор перед виконанням програми транслює її на проміжну мову (наприклад, у байт-код або p-код), більш зручний для інтерпретації (тобто йдеться про інтерпретатора з вбудованим транслятором) . Такий метод називається змішаною реалізацією. Прикладом змішаної реалізації мови може бути Perl. Цей підхід поєднує як переваги компілятора та інтерпретатора (велика швидкість виконання та зручність використання), так і недоліки (для трансляції та зберігання програми проміжною мовою потрібні додаткові ресурси; для виконання програми на цільовій машині має бути представлений інтерпретатор). Також, як і у випадку компілятора, змішана реалізація вимагає, щоб перед виконанням вихідний код не містив помилок (лексичних, синтаксичних та семантичних).

Трансляціяі інтерпретація - різні процеси: трансляція займається перекладом програм з однієї мови на іншу, а інтерпретація відповідає за виконання програм. Однак, оскільки метою трансляції зазвичай є підготовка програми до інтерпретації, ці процеси зазвичай розглядаються разом. Наприклад, мови програмування часто характеризуються як "компілювані" або "інтерпретовані", залежно від того, переважає при використанні мови компіляція або інтерпретація. Причому практично всі мови програмування низького рівня і третього покоління, на зразок асемблера, Сі або Модули-2, є компілюваними, а більш високорівневі мови, як Python або SQL, - інтерпретовані.

З іншого боку, існує взаємопроникнення процесів трансляції та інтерпретації: інтерпретатори можуть бути компілюючими (у тому числі з динамічною компіляцією), а в трансляторах може бути потрібна інтерпретація для конструкцій метапрограмування (наприклад, для макросів у мові асемблера, умовної компіляції у Сі або для шаблонів C ++).

Більше того, та сама мова програмування може і транслюватися, і інтерпретуватися, і в обох випадках повинні бути присутніми загальні етапи аналізу та розпізнавання конструкцій та директив вихідної мови. Це стосується і програмних реалізацій, і апаратних - так, процесори сімейства x86 перед виконанням інструкцій машинної мови виконують їх декодування, виділяючи в опкодах поля операндів (регістрів, адрес пам'яті, безпосередніх значень), розрядності тощо, а процесорах Pentium з архітектурою NetBurst машинний код перед збереженням у внутрішньому кеші взагалі транслюється у послідовність мікрооперацій.

Транслятор (англ. translator - перекладач)- Це програма-перекладач. Вона перетворює програму, написану однією з мов програмування, в бінарний файл програми, що з машинних команд, або безпосередньо виконує дії програми.

Транслятори реалізуються у вигляді компіляторів, інтерпретаторів, препроцесорів та емуляторів. З погляду виконання роботи компілятор та інтерпретатор суттєво різняться.

Компілятор (Compiler - укладач, збирач)- Читає всю програму повністю, робить її переклад і створює закінчений варіант програми машинною мовою, тобто бінарний файл, що містить перелік машинних команд. Бінарний файл може бути виконуваним, бібліотечним, об'єктним), він виконується операційною системою без участі компілятора.

Інтерпретатор (англ. interpreter - тлумач, перекладач)- Переводить програму рядковим (по одному оператору) в машинний код (команди процесора, ОС, іншого середовища), виконує перекладений оператор (рядок програми), а потім переходить до наступного рядка програмного тексту. Інтерпретатор не формує файлів, що виконуються, він сам виконує всі дії, записані в тексті вихідної програми.

Після того, як програма відкомпільована, ні вихідна програма, ні компілятор більше не потрібні. У той же час програма, що обробляється інтерпретатором, повинна заново перекладатися машинною мовою при кожному черговому запуску програми.

Відкомпіловані програми працюють швидше, але простіше виправляти і змінювати інтерпретовані.

Кожна конкретна мова орієнтована або на компіляцію, або на інтерпретацію - в залежності від того, для яких цілей він створювався. Наприклад, Паскаль зазвичай використовується на вирішення досить складних завдань, у яких важлива швидкість роботи програм. Тому ця мова зазвичай реалізується за допомогою компілятора.

З іншого боку, Бейсік створювався як мова для програмістів-початківців, для яких строкове виконання програми має незаперечні переваги.

Іноді однієї мови є і компілятор, і інтерпретатор. У цьому випадку для розробки та тестування програми можна скористатися інтерпретатором, а потім відкомпілювати налагоджену програму, щоб підвищити швидкість виконання.

Препроцесор— це транслятор з однієї мови програмування на іншу без створення виконуваного файлуабо виконання програми.

Препроцесори зручні для розширення можливостей мови та зручності програмування шляхом використання на етапі написання програми зручнішого для людини діалекту мови програмування та її перекладу препроцесором на текст стандартної мови програмування, яку можна відкомпілювати стандартним компілятором.

Емулятор- функціонує в деякій цільовій операційній системі та апаратній платформі програмне та/або апаратний засіб, призначене для виконання програм, виготовлених в іншій операційній системі або працюючих на відмінному від цільового апаратного забезпечення, але що дозволяє здійснювати ті ж самі операції в цільовому середовищі, що і в системі, що імітується.

До емулюючих мов відносяться такі системи, як Java, .Net, Mono, в яких на етапі створення програми проводиться її компіляція в спеціальний байт-код та отримання бінарного файлу, Придатного для виконання в будь-якому операційному та апаратному середовищі, а виконання отриманого байт-коду проводиться на цільовій машині за допомогою простого та швидкого інтерпретатора (віртуальної машини).

Реасемблер, дизассемблер— програмний засіб, призначений для розшифровки бінарного коду з поданням його у вигляді тексту асемблера або тексту іншої мови програмування, що дозволяє проаналізувати алгоритм вихідної програми та використовувати отриманий текст для необхідної модифікації програми, наприклад, поміняти адреси зовнішніх пристроїв, звернення до системних та мережевих ресурсів, виявити приховані функціїбінарного коду (наприклад, комп'ютерного вірусу чи іншої шкідливої ​​програми: трояна, хробака, кейлоггера та ін.).

до алгоритмізації алгоритми, структури даних та програмування СУБД ЯіМП 3GL 4GL 5GL технології прогр.

Чи знаєте ви,що абстракція через параметризацію— це прийом програмування, що дозволяє, використовуючи параметри, уявити фактично необмежений набір різних обчислень однією програмою, що є абстракція цих наборів.

Транслятори

Так як текст записаної на Паскалі програми не зрозумілий комп'ютеру, потрібно перекласти його на машинну мову. Такий переклад програми з мови програмування на мову машинних кодів називається трансляцією (translation - переклад), а виконується він спеціальними програмами трансляторами.

Існує три види трансляторів: інтерпретатори, компілятори та асемблери.

Інтерпретаторомназивається транслятор, який проводить пооператорну (покомандну) обробку та виконання вихідної програми.

Компіляторперетворює (транслює) всю програму в модуль машинною мовою, після цього програма записується на згадку про комп'ютера і потім виконується.

Асемблерипереводять програму, записану мовою асемблера (автокода), у програму машинною мовою.

Будь-який транслятор вирішує такі основні завдання:

Аналізує програму, що транслюється, зокрема визначає, чи містить вона синтаксичні помилки;

Генерує вихідну програму (її часто називають об'єктною або робочою) мовою команд ЕОМ (у деяких випадках транслятор генерує вихідну програму проміжною мовою, наприклад, мовою асемблера);

Розподіляє пам'ять для вихідної програми (у найпростішому випадку це полягає у призначенні кожному фрагменту програми, змінним, константам, масивам та іншим об'єктам своїх адрес ділянок пам'яті).

Введення в.Net та c Sharp

Програміст пише програму мовою, зрозумілою програмісту, а комп'ютер виконує лише програми, написані мовою машинних кодів. Сукупність засобів написання, редагування та перетворення програми на машинні коди та її виконання називають середовищем розробки.

Середовище розробки містить:

    Текстовий редактор для введення та коригування тексту програми

    Компілятор для перекладу програми мовою машинних команд

    Засоби налагодження та запуску програми на виконання

    Загальні бібліотеки з програмними елементами, що багаторазово використовуються.

    Довідкову систему та ін.

Платформа.NET («дот нет»), розроблена компанією Microsoft, включає не тільки середовище розробки для кількох мов програмування, що називається Visual Studio .NET, але безліч інших засобів, таких як засоби підтримки баз даних, електронної поштита ін.

Найважливішими завданнями розробки сучасних програмних засобів є:

    Переносність-можливість виконання на різних типах комп'ютерів

    Безпека – неможливість несанкціонованих дій

    Надійність – безвідмовність роботи у заданих умовах

    Використання готових компонентівдля прискорення розробки

    Міжмовна взаємодія – застосування кількох мов програмування.

Усі ці завдання вирішують у рамках платформи.NET.

Для забезпечення переносимості компілятори платформи переводять програму не в машинний код, а в проміжну мову Microsoft Intermediate Language (MSIL) або просто в IL. IL не містить команд, що залежать від операційної системи чи типу комп'ютера. Програму на IL виконує середовище виконання CLR (Common Language Runtime), яке вже специфічне кожного типу комп'ютера. Переведення IL-програми в машинні коди конкретного комп'ютера виконує комп'ютер JIT (Just In Time).

Схему виконання програми на платформі.NET наведено на рис.1.

Компілятор створює складання програми - файл з розширення . exeабо . dll, який містить код IL. Виконання програми організує середовище CRL, яке слідкує за допустимістю операцій, виконує розподіл та очищення пам'яті та обробляє помилки виконання. Це забезпечує безпеку та надійність програм.

Платою за ці переваги є зниження швидкодії програм та необхідність встановлення на комп'ютері.NET для виконання готових програм.

Отже, .NET – це програмна платформа.

C# (Сі-Шарп) - це одна з мов програмування платформи.NET. Він входить у Visual Studio - Visual Studio.NET (Версії 2008, 2010, 2012). Крім C# Visual Studio.NET входять Visual Basic.NET і Visual C++.

Одна з причин розробки нової мови компанією Microsoft — створення компонентно-орієнтованої мови для платформи .NET Framework.

Рис.1 Схема виконання програми в.NET

NET Framework складається з двох частин:

    По-перше, вона включає величезну бібліотеку класів, які можна викликати із програм на C#. Класів дуже багато (близько кілька тисяч). Це позбавляє необхідності писати все самостійно. Тому програмування на С# полягає у написанні власного коду, який за необхідності викликає класи, що зберігаються у .NET Framework.

    По-друге, до її складу входить середовище виконання. NET Runtime, керуюча запускомта роботою готових програм.

Платформа.NET є відкритим середовищем – сторонні розробники створили для .NET десятки компіляторів мов Ada, COBOL, Fortran, Lisp, Oberon, Perl, Python та ін.

Платформа.NET активно розвивається – випускаються нові версії цієї платформи. За допомогою меню Project Properties з'ясуйте версію платформи .NET.

Теоретично програма для .NET може виконуватися під будь-якою операційною системою, в якій .NET встановлена. Але на практиці єдина офіційна платформа для цього – це операційна система Windows. Однак існують неофіційні реалізації .NET для Unix-подібних ОС Linux, Mac OS X та інших (Mono – проект системи .NET Framework на базі вільного програмного забезпечення).

Слово рапіра

Слово рапіра англійськими літерами (транслітом)

Слово рапіра складається з 6 букв: а і п р р

Значення слова рапіра. Що таке рапіра?

Рапіра (нім. Rapier, від фр. rapière, спочатку ісп. espadas roperas - буквально, «меч для одягу» (тобто не для обладунку), спотворена у фр. la rapiere) - переважно холодна зброя, що коле, різновид шпаги…

ru.wikipedia.org

Рапіра (нім. Rapier, від франц. rapière), спортивна колюча зброя, складається із сталевого еластичного клинка та ефесу (захисної чашоподібної гарди та рукоятки).

ВРХ. - 1969-1978

РАПІРА (нім. Rapier, від франц. Rapiere). Спортивна колюча зброя. Складається із сталевого гнучкого клинка та ефесу (захисної чашоподібної гарди та рукоятки). Клинок прямокутного перерізу, що звужується до вершини.

Олімпійська енциклопедія - 2006

РАПІРА, Розширений Адаптований Поплан-Інтерпретатор, Редактор, Архів - навчально-виробнича мова програмування. Розроблено на початку 80-х років у СРСР. Рапіра є засобом.

Енциклопедія мов програмування

Рапіра (ЗРК)

Рапіра – ракетна система класу «земля-повітря», розроблена британськими збройними силамидля Королівських військово-повітряних сил Складається на озброєнні армій Австралії, Великобританії, Індонезії, Сінгапуру, Туреччини, Малайзії та Швейцарії.

ru.wikipedia.org

Рапіра бойова

Рапіра бойова - (від франц. rapiere) - колюче, різання колюче-рубающее длинноклинковое Х.0. з рукояткою, відомо у Європі з 2-ї половини 17 ст. Складалися з прямого плоского або гранованого сталевого клинка із загостреним (у дуельних Р.).

Рапіра спортивна

РАПІРА СПОРТИВНА – спортивна холодна зброя, що складається з гнучкого прямокутного в перерізі клинка та знімного черена з круглою чашкоподібною гардою.

weapon.slovaronline.com

Рапіра спортивна - спортивна холодна зброя, що складається з гнучкого прямокутного в перерізі клинка та знімного черена з круглою чашкоподібною гардою.

Петров А. Словник холодної зброї та обладунків

Рапіра (мова програмування)

РАПІРА - Розширений Адаптований Поплан-Інтерпретатор, Редактор, Архів - процедурна мова програмування. Розроблено на початку 80-х років у СРСР як засіб переходу від більш простих мов (зокрема, навчальної мови Робік).

ru.wikipedia.org

Фехтування на літніх Олімпійських іграх 1896 - рапіра

Змагання з фехтування на рапірах серед чоловіків на літніх Олімпійських іграх 1896 року пройшли 7 квітня.

Транслятор, компілятор, інтерпретатор

Взяли участь вісім спортсменів із двох країн. Спочатку вони змагалися у двох групах по чотири спортсмени.

ru.wikipedia.org

Фехтування на літніх Олімпійських іграх 1900 - рапіра

Змагання з фехтування на рапірах серед чоловіків на літніх Олімпійських іграх 1900 року пройшли з 14 по 19 та 21 травня. Взяли участь 54 спортсмени з десяти країн.

ru.wikipedia.org

Російська мова

Рапір/а.

Морфемно-орфографічний словник. - 2002

Фехтування на літніх Олімпійських іграх 1900 – рапіра серед маестро

Змагання з фехтування на рапірах серед чоловіків-маестро на літніх Олімпійських іграх 1900 року пройшли з 22 по 25 та з 27 по 28 травня.

Взяли участь 59 спортсменів із семи країн.

ru.wikipedia.org

Приклади вживання слова рапіра

Рапіра зроблена так, що всередину увійти не може, максимум, що може залишитися, це синець.

За маркуванням на рукоятці рапіри оперативники виходять на фехтувальний клуб і з'ясовують, що рапір звідти було вкрадено рік тому.

Лекція: Стандарти та ліцензії на програмне забезпечення

Стандарти сімейства UNIX. Стандарти мови програмування C. System V Interface Definition (SVID). Комітет POSIX. X/Open, OSF та Open Group. Ліцензії на програмне забезпечення та документацію.
Зміст

  • 3.1. Стандарти сімейства UNIX
    • Стандарти мови програмування C
    • System V Interface Definition (SVID)
    • Комітети POSIX
    • X/Open, OSF та Open Group
  • 3.2. Ліцензії на програмне забезпечення та документацію

3.1. Стандарти сімейства UNIX

Причиною появи стандартів на операційну систему UNIX стало те, що вона була перенесена на багато апаратних платформ. Її перші версії працювали на апаратурі PDP, але у 1976 та 1978 роках система була перенесена на Interdata та VAX. З 1977 по 1981 роки оформилися дві конкуруючі гілки: UNIX AT&T та BSD. Напевно, цілі розробки стандартів були різними. Одна з них – узаконити верховенство своєї версії, а інша – забезпечити переносимість системи та прикладних програм між різними апаратними платформами. У зв'язку з цим говорять і про мобільність програм. Такі властивості мають відношення як до вихідних текстів програм, так і до виконання програм.

Подальший матеріал наводиться у хронологічному порядку появи стандартів.

Стандарти мови програмування C

Цей стандарт не стосується безпосередньо UNIX. Але оскільки C є базовим як цього сімейства, і інших ОС, згадаємо про стандарті цієї мови програмування. Початок йому було покладено виходом у 1978 році першої редакції книги Б.Кернігана та Д.Рітчі. Цей стандарт часто називають K&R. Програмісти, автори цієї праці, працювали над UNIX разом із Кеном Томпсоном. При цьому перший із них запропонував назву системи, а другий винайшов цю мову програмування. Відповідний текст доступний в Інтернеті [ 45 ].

Однак, промисловий стандарт мови програмування С був випущений в 1989 році ANSI і мав ім'я X3. 159 - 1989. Ось що написано про цей стандарт [ 46 ]:

"Стандарт був прийнятий для покращення переносимості написаних мовою Сі програм між різними типамиОС. Таким чином, до стандарту, крім синтаксису та семантики мови Сі, увійшли рекомендації щодо змісту стандартної бібліотеки. Про наявність підтримки стандарту ANSI C говорить наперед визначене символьне ім'я _STDC".

У 1988 році на основі цього стандарту мови програмування була випущена друга редакція книги Кернігана та Рітчі про С. Зауважимо, що фірми, які виробляють програмні продукти для розробки програм мовою С, можуть формувати свій склад бібліотек і навіть дещо розширювати склад інших засобів мови.

^ System V Interface Definition (SVID)

Інший напрямок розвитку стандартів UNIX пов'язане з тим, що не тільки ентузіасти замислювалися про створення "еталонів". Основні розробники системи з появою багатьох "варіантів" вирішили видавати власні документи. Так з'являються стандарти USG, організацією, що розробляє документацію версій UNIX AT&T з того моменту, коли для створення операційної системи була утворена ця дочірня компанія. Перший документ з'явився у 1984 році на основі SVR2. Він мав назву SVID (System V Interface Definition). Чотиритомний опис було випущено після виходу версії SVR4. Ці стандарти доповнювалися набором тестових програм System V Verification Suite (SVVS). Основне призначення цих коштів полягало в тому, щоб розробники мали можливість судити, чи може їхня система претендувати на ім'я System V [ 14 ].

Зазначимо, що стан справ зі стандартом SVID у чомусь подібний до стандарту мови програмування С. Видана авторами цієї мови програмування книга є одним з еталонів, але не єдиним. Випущений пізніше стандарт є результатом колективної праці, пройшов етап обговорення широкої громадськості і, мабуть, може претендувати на провідну роль у списку стандартів. Так і SVVS є набором тестів, що дозволяють судити, чи гідна система відповідати імені System V тільки однієї з версій UNIX. При цьому не враховується весь досвід розробки операційних системвід різних виробників.

Комітети POSIX

Робота з оформлення стандартів UNIX розпочалася групою ентузіастів у 1980 році. Було сформульовано мету – формально визначити послуги, які операційні системи забезпечують додаткам. Такий стандарт програмного інтерфейсу став основою документа POSIX (Portable Operating System Interface for Computing Environment – ​​переносний інтерфейс операційної системи для обчислювального середовища) [ 14 ]. Перша робоча група POSIX була утворена в 1985 на основі UNIX-орієнтованого комітету зі стандартизації /usr/group, також званої UniForum [ 47 ]. Назва POSIX була запропонована родоначальником GNU Річардом Столменом.

Ранні версії POSIX визначають безліч системних сервісів, необхідні для функціонування прикладних програм, які описані в рамках інтерфейсу, специфікованого для мови С (інтерфейс системних викликів). Закладені у ньому ідеї використовувалися комітетом ANSI (American National Standards Institute) для створення стандарту мови C, згаданого раніше. Вихідний склад функцій, що закладається у перші версії, спирався на UNIX AT&T (версія SVR4 [ 48 ]). Але надалі відбувається відрив специфікацій стандартів POSIX від цієї конкретної ОС. Підхід до організації системи на основі множини базових системних функцій був застосований не тільки в UNIX (наприклад, WinAPI фірми Microsoft).

В 1988 був опублікований стандарт 1003.1 - 1988, що визначає API (Application Programming Interface, програмний інтерфейс додатків). Через два роки було прийнято новий варіант стандарту IEEE 1003.1 – 1990. У ньому було визначено загальні правила програмного інтерфейсу, як системних викликів, так бібліотечних функцій. Далі затверджуються доповнення до нього, що визначають сервіси для систем реального часу, "ниток" POSIX та ін. Важливим є стандарт POSIX 1003.2 – 1992 – визначення командного інтерпретатората утиліт.

Є переклад [ 1 ] цих двох груп документів, які отримали такі назви: POSIX.1 (інтерфейс прикладних програм) та POSIX.2 (командний інтерпретатор та утиліти – інтерфейс користувача). У згаданому перекладі містяться три розділи: основні поняття, системні послуги та утиліти. Глава " Системні послугирозділена на кілька частин, кожна з яких групує подібні за функціями послуги. Наприклад, в одному з розділів "Базове введення/виведення" сьома частина, присвячена операціям з каталогами, описує три функції (opendir, readdir і closedir). Вони визначаються в чотирьох пунктах: "Синтаксис", "Опис", "Повертане значення" та "Помилки".

Для тих, хто знайомий з алгоритмічною мовоюпрограмування, наведемо приклад фрагментів опису.

Мови програмування, транслятори, компілятори та інтерпретатори

Фактично такий опис дає уявлення про те, як специфікується "інтерфейс системних викликів". У пункті "Синтаксис" для функції readdir наведені такі рядки:

#include

#include

struct dirent *readdir(DIR *dirp);

Другий пункт ("Опис") містить наступний текст:

"Типи та структури даних, що використовуються у визначеннях з каталогами, визначаються у файлі dirent.h. Внутрішній склад каталогів визначається реалізацією. При читанні за допомогою функції readdir формується об'єкт типу struct dirent, що містить як поле символьний масив d_name, в якому знаходиться завершуване символом NUL локальне ім'яфайлу.

Readdir читає поточний елемент каталогу та встановлює вказівник позиції на наступний елемент. Відкритий каталог задається вказівником dirp. Елемент, що містить порожні імена, Пропускається".

А ось що наводиться у пункті "Повертане значення":

"Readdir при успішному завершенні повертає покажчик на об'єкт типу struct dirent, що містить прочитаний елемент каталогу. Прочитаний елемент може заноситись у статичну пам'ятьта перекривається черговим таким викликом, застосованим до того ж відкритого каталогу. Виклик readdir для різних відкритих каталогів не перекриває інформацію, що читається. У разі помилки або досягнення кінця файлу повертається нульовий покажчик.

У пункті "Помилки стандарту" зазначено:

"Readdir та closedir виявляють помилку. Dirp не є вказівником на відкритий каталог".

Цей приклад показує, як описуються послуги, що надаються додатком. Вимоги до операційної системи (реалізації) у тому, що вона " ... повинна підтримувати все обов'язкові службові програми, функції, заголовні файли із забезпеченням специфікованого у стандарті поведінки. Константа _POSIX_VERSION має значення 200112L [ 49 ]".

У світі комп'ютерних технологій існує таке словосполучення: програмування POSIX. Цьому можна навчитися, використовуючи різні керівництвапо системному програмуванню UNIX та операційним системам (наприклад, [ 5 ]). Є окрема книга з такою назвою [ 3 ]. Зауважимо, що у передмові до цієї книги сказано, що вона описує ". . . стандарт втричі. . ", оскільки вона спирається на останню версію POSIX 2003 року, в основі якої три стандарти: IEEE Std 1003.1, технічний стандарт Open Group та ISO/IEC 9945.

Як перевірити відповідність конкретної системи стандарту POSIX? Формалізація такого питання не така проста, як здається на перший погляд. У сучасних версіяхпропонується 4 види відповідності (чотири семантичні значення слова "відповідність": повне, міжнародне, національне, розширене).

У документах наводяться списки двох видів інтерфейсних засобів: обов'язкові (по можливості передбачається його компактність) і факультативні. Останні повинні або оброблятися вказаним чином, або повертати фіксоване значення коду ENOSYS, що означає, що функція не реалізована.

Зазначимо, що набір документів POSIX змінюється багато років. Але розробники нових версій завжди намагаються максимально зберегти наступність із попередніми версіями. У свіжих редакціях може з'явитися щось нове. Наприклад, у документі 2004 року було об'єднано чотири частини [ 50 ]:

  • Base Definitions volume (XBD) – визначення термінів, концепцій та інтерфейсів, загальних всім томів даного стандарту;
  • System Interfaces volume (XSH) – інтерфейси системного рівня та їх прив'язка до мови Сі, де описуються обов'язкові інтерфейси між прикладними програмами та операційною системою, зокрема – специфікації системних викликів;
  • Shell and Utilities volume (XCU) – визначення стандартних інтерфейсів командного інтерпретатора (т.зв. POSIX-shell), і навіть базової функціональності Unix-утиліт;
  • Rationale (Informative) volume (XRAT) – додаткова інформація, зокрема історична, про стандарт.

Як і перші редакції, документ у своїй основній частині описує групи послуг, що надаються. Кожен елемент там описаний у наступних пунктах: NAME (Ім'я), SINOPSIS (Синтаксис), DISCRIPTION (Опис), RETURN VALUE (Повертане значення), ERRORS (Помилки) та у висновку EXAMPLE (Приклади).

Сучасні версії стандарту визначають вимоги як до операційної системи, і до прикладних програм. Наведемо приклад [ 51 ].

Функція readdir() повинна повертати покажчик на структуру, що належить до чергового елементу каталогу. Чи повертаються елементи каталогу з іменами "крапка" і "крапка-крапка", стандартом не специфіковано. У цьому прикладі можливі чотири результати, а вимога до прикладної програми полягає в тому, що вона повинна бути розрахована на будь-який з них.

І на закінчення наведемо уривок з курсу лекцій Сухомлінова ("ВВЕДЕННЯ В АНАЛІЗ ІНФОРМАЦІЙНИХ ТЕХНОЛОГІЙ", Сухомлінов В.А. Частина V. Методологія та система стандартів POSIX OSE), присвяченим галузі застосування стандартів [ 52 ]:

"Область застосування стандартів POSIX OSE (Open System Environment) – забезпечення наступних можливостей (називаються ще властивостями відкритості) для інформаційних систем, що розробляються:

  • Переносність додатків рівні вихідних текстів (Application Portability at the Source Code Level), тобто. надання можливості перенесення програм та даних, представлених на вихідних текстах мов програмування, з однієї платформи на іншу.
  • Системна интероперабельность (System Interoperability), тобто. підтримка взаємозв'язку між системами.
  • Перенесення користувачів (User Portability), тобто. забезпечення можливості для користувачів працювати на різних платформах без перенавчання.
  • Адаптованість до нових стандартів (Accommodation of Standards), пов'язаних із досягненням цілей відкритості систем.
  • Адаптованість до нових інформаційних технологій (Accommodation of new System Technology) на основі універсальності класифікаційної структури сервісів та незалежності моделі від механізмів реалізації.
  • Масштабованість прикладних платформ (Application Platform Scalability), що відображає можливість перенесення та повторного використання прикладного програмного забезпечення стосовно різних типів і конфігурацій прикладних платформ.
  • Масштабованість розподілених систем (Distributed System Scalability), що відображає можливість функціонування прикладного програмного забезпечення незалежно від розвитку топології та ресурсів розподілених систем.
  • Прозорість реалізацій (Implementation Transparency), тобто. приховування від користувачів за інтерфейсами систем особливостей реалізації.
  • Системність та точність специфікацій функціональних вимог користувачів (User Functional Requirements), що забезпечує повноту та ясність визначення потреб користувачів, у тому числі у визначенні складу застосовуваних стандартів."

Це дозволяє вирішувати такі завдання:

  • інтеграція інформаційних систем із компонентів різних виробників;
  • ефективність реалізацій та розробок, завдяки точності специфікацій та відповідності стандартним рішенням, що відбиває передовий науково-технічний рівень;
  • ефективність перенесення прикладного програмного забезпечення завдяки використанню стандартизованих інтерфейсів та прозорості механізмів реалізації сервісів систем.

Також у стандартах формально визначаються такі важливі поняття операційних систем: • користувач; файл; процес; термінал; хост; вузол мережі; час; мовно-культурне середовище. Там не наводяться формулювання такого визначення, але вводяться застосовувані до них операції та властиві їм атрибути.

Усього у списку стандартів POSIX більше трьох десятків елементів. Їхні імена традиційно починаються буквою "Р", після якої розташоване чотиризначне число з додатковими символами.

Існують також групові імена стандартів POSIX1, POSIX2 тощо. Наприклад, POSIX1 пов'язаний із стандартами на базові інтерфейси ОС (Р1003.1х, де замість х або порожньо, або символи від a до g; таким чином, у цій групі 7 документів), а POSIX3 – методи тестування (два документи – Р2003 та Р2003n ).

Транслятор зазвичай виконує також діагностику помилок, форує словники ідентифікаторів, видає для друку тексти програми тощо.

Трансляція програми- Перетворення програми, представленої однією з мов програмування, в програму іншою мовою і, в певному сенсі, рівносильну першій.

Мова, на якій представлена ​​вхідна програма, називається вихідною мовою, а сама програма - вихідним кодом. Вихідна мова називається цільовою мовоюабо об'єктним кодом.

Поняття трансляції відноситься не тільки до мов програмування, але і до інших комп'ютерних мов, на кшталт мов розмітки, аналогічних HTML, і до природних мов, на кшталт англійської чи російської. Однак дана стаття лише про мови програмування, про природних мовахдив: Переклад .

Види трансляторів

  • Адресний. Функціональний пристрій, що перетворює віртуальну адресу (Virtual address) на реальну адресу пам'яті (Memory address).
  • Діалоговий. Забезпечує використання мови програмування в режимі розподілу часу.
  • Багатопрохідний. Формує об'єктний модуль за декілька переглядів вихідної програми.
  • Зворотній. Те саме, що детранслятор. також: декомпілятор, дизассемблер.
  • Однопрохідний. Формує об'єктний модуль за послідовний перегляд вихідної програми.
  • Оптимізуючий. Виконує оптимізацію коду в об'єктному модулі, що створюється.
  • Синтаксично-орієнтований (синтаксично-керований). Отримує на вхід опис синтаксису та семантики мови та текст описаною мовою, який і транслюється відповідно до заданого опису.
  • Тестовий. Набір макрокоманд мови асемблера , що дозволяють задавати різні процедури налагодження в програмах, складених мовою асемблера.

Реалізації

Мета трансляції - перетворити текст з однієї мови на іншу, яка зрозуміла адресату тексту. У випадку програм-трансляторів адресатом є технічний пристрій (процесор) або програма-інтерпретатор.

Можна навести низку інших прикладів, у яких архітектура розроблених серій обчислювальних машинбазувалася чи сильно залежала від деякої моделі структури програми. Так, серія GE/Honeywell Multics ґрунтувалася на семантичній моделі виконання програм, написаних мовою ПЛ/1. В Шаблон: Не перекладено B5500, B6700 … B7800 прототипом послужила модель програми етапу виконання, написаної розширеною мовою Алгол. …

Процесор i432, подібно до цих ранніх архітектур, також базується на семантичній моделі структури програми. Однак, на відміну від своїх попередників, i432 не ґрунтується на моделі деякої конкретної мови програмування. Натомість, основною метою розробників було забезпечення безпосередньої підтримки на етапі виконання як для абстрактних даних(тобто програмування з абстрактними типами даних), і для доменно-орієнтованих операційних систем. …

Перевага компілятора: програма компілюється один раз і при кожному виконанні не потрібно додаткових перетворень. Відповідно, не потрібна наявність компілятора на цільовій машині, на яку компілюється програма. Недолік: окремий етап компіляції уповільнює написання та налагодження та ускладнює виконання невеликих, нескладних чи разових програм.

Якщо вихідна мова є мовою асемблера ( низькорівневою мовою, близьким до машинної мови), то компілятор такої мови називається асемблером.

Протилежний метод реалізації – коли програма виконується за допомогою інтерпретаторавзагалі без трансляції. Інтерпретатор програмно моделює машину, цикл вибірки виконання якої працює з командами мовами високого рівня, а не з машинними командами. Таке програмне моделювання створює віртуальну машину, що реалізує мову. Цей підхід називається чистою інтерпретацією. Чиста інтерпретація застосовується зазвичай для мов із простою структурою (наприклад, АПЛ чи Лисп). Інтерпретатори командного рядка обробляють команди у скриптах UNIX або пакетних файлах (.bat) в MS-DOS також зазвичай у режимі чистої інтерпретації.

Гідність інтерпретатора: відсутність проміжних дій для трансляції спрощує реалізацію інтерпретатора і робить його зручнішим у використанні, у тому числі в діалоговому режимі. Недолік - інтерпретатор має бути в наявності на цільовій машині, де має виконуватися програма. А властивість чистого інтерпретатора, що помилки в програмі, що інтерпретується, виявляються тільки при спробі виконання команди (або рядка) з помилкою, можна визнати як недоліком, так і гідністю.

Існують компромісні між компіляцією та чистою інтерпретацією варіанти реалізації мов програмування, коли інтерпретатор перед виконанням програми транслює її на проміжну мову (наприклад, у байт-код або p-код), більш зручний для інтерпретації (тобто йдеться про інтерпретатора з вбудованим транслятором) . Такий метод називається змішаною реалізацією. Прикладом змішаної реалізації мови може бути Perl. Цей підхід поєднує як переваги компілятора та інтерпретатора (більша швидкість виконання та зручність використання), так і недоліки (для трансляції та зберігання програми проміжною мовою потрібні додаткові ресурси; для виконання програми на цільовій машині має бути представлений інтерпретатор). Також, як і у випадку компілятора, змішана реалізація вимагає, щоб перед виконанням вихідний код не містив помилок (лексичних, синтаксичних та семантичних).

У міру збільшення ресурсів комп'ютерів та розширення гетерогенних мереж (у тому числі інтернету), що зв'язують комп'ютери різних типів та архітектур, виділився новий видінтерпретації, у якому вихідний (чи проміжний) код компілюється в машинний код безпосередньо під час виконання, «на лету». Вже скомпіловані ділянки коду кешуються, щоб при повторному зверненні до них вони одразу отримували управління без перекомпіляції. Цей підхід отримав назву динамічної компіляції.

Перевагою динамічної компіляції є те, що швидкість інтерпретації програм стає порівнянною зі швидкістю виконання програм у звичайних мовах, що компілюються, при цьому сама програма зберігається і поширюється в єдиному вигляді, незалежному від цільових платформ. Недоліком є ​​більша складність реалізації та більші вимоги до ресурсів, ніж у випадку простих компіляторівчи чистих інтерпретаторів.

Цей метод добре підходить для

Цілі та завдання дисципліни. Основні поняття та визначення. Загальні особливості мов програмування та трансляторів. Узагальнена структура транслятора. Варіанти взаємодії блоків транслятора.

Цілі та завдання дисципліни

В даний час штучні мови, що використовують для опису предметної області текстове уявлення, широко застосовуються у програмуванні, а й у інших областях. З їх допомогою описується структура різноманітних документів, тривимірних віртуальних світів, графічних інтерфейсів користувача та багатьох інших об'єктів, що використовуються в моделях та реальному світі. Для того, щоб ці текстові описи були коректно складені, а потім правильно розпізнані та інтерпретовані, використовуються спеціальні методи їх аналізу та перетворення. В основі методів лежить теорія мов та формальних граматик, а також теорія автоматів. Програмні системи, призначені для аналізу та інтерпретації текстів, називаються трансляторами.

Незважаючи на те, що до теперішнього часу розроблено тисячі різних мов та їх трансляторів, процес створення нових додатків у цій галузі не припиняється. Це як з розвитком технології виробництва обчислювальних систем, і з необхідністю вирішення дедалі складніших прикладних завдань. Крім того, елементи теорії мов та формальних граматик застосовні і в інших різноманітних областях, наприклад, при описі структур даних, файлів, зображень, представлених не в текстовому, а в двійковому форматі. Ці методи корисні і розробки своїх трансляторів навіть там, де вже є відповідні аналоги. Така розробка може бути зумовлена ​​різними причинами, зокрема функціональними обмеженнями, відсутністю локалізації, низькою ефективністю. Наприклад, однією з останніх розробок компанії Microsoft є мова програмування C#, а однією з причин створення є прагнення до зниження популярності мови програмування Java. Можна навести безліч інших прикладів, коли розробка свого транслятора може бути актуальною. Тому, основи теорії мов та формальних граматик, а також практичні методирозробки трансляторів лежать у фундаменті інженерної освіти з інформатики та обчислювальної техніки.

Пропонований матеріал торкається основ методів розробки трансляторів і містить відомості, необхідні для вивчення логіки їх функціонування, використовуваного математичного апарату (теорії формальних мов і формальних граматик, метамов). Він використовується в рамках семестрових лекційних курсів, які читаються для різних спеціальностей, на факультеті інформатики та обчислювальної техніки Красноярського державного технічного університету. У ході лабораторних робіт здійснюється безпосереднє ознайомлення з окремими методами створення трансляторів.

Мета дисципліни: надати знання з основ теорії мов та формальних граматик, теорії автоматів, методів розробки трансляторів.

Досягнення поставленої мети під час викладання дисципліни вирішуються такі:

  1. У ході лекційного курсу розглядаються загальні принципи організації процесу трансляції та структури трансляторів. Вивчаються основи теорії побудови трансляторів.
  2. на лабораторних заняттяхта в ході самостійної роботиздійснюється практичне закріплення одержаних теоретичних знань: розробляється транслятор для простої мови програмування.

Основні поняття та визначення

Більшість визначених визначень запозичено з [АРНФТС Англо-російсько-німецько-французький тлумачний словник з обчислювальної техніки та обробки даних, 4132 терміни. Під. ред. А.А. Дородніцина. М.: 1978. 416 с.) ].

Транслятор - обслуговуюча програма, що перетворює вихідну програму, надану вхідною мовою програмування, робочу програму, представлену об'єктною мовою.

Наведене визначення відноситься до всіх різновидів транслюючих програм. Однак кожна з таких програм може мати свої особливості щодо організації процесу трансляції. В даний час транслятори поділяються на три основні групи: асемблери, компілятори та інтерпретатори.

Асемблер - системна обслуговуюча програма, яка перетворює символічні конструкції на команди машинної мови. Специфічною рисою асемблерів є те, що вони здійснюють дослівну трансляцію однієї символічної команди на одну машинну. Таким чином, мова асемблера (ще називається автокодом) призначена для полегшення сприйняття системи команд комп'ютера та прискорення програмування в цій системі команд. Програмістові набагато легше запам'ятати менімонічне позначення машинних команд, ніж їхній двійковий код. Тому основний виграш досягається не за рахунок збільшення потужності окремих команд, а за рахунок підвищення ефективності їх сприйняття.

Разом з тим, мова асемблера, крім аналогів машинних команд, містить безліч додаткових директив, що полегшують, зокрема, управління ресурсами комп'ютера, написання фрагментів, що повторюються, побудова багатомодульних програм. Тому виразність мови набагато багатша, ніж просто мови символічного кодування, що значно підвищує ефективність програмування.

Компілятор - це обслуговуюча програма, що виконує трансляцію машинною мовою програми, записаної на вихідною мовоюпрограмування. Так само як і асемблер, компілятор забезпечує перетворення програми з однієї мови на іншу (найчастіше в мову конкретного комп'ютера). Разом з тим, команди вихідної мови значно відрізняються за організацією та потужністю від команд машинної мови. Існують мови, у яких одна команда вихідної мови транслюється у 7-10 машинних команд. Проте є й такі мови, у яких кожній команді може відповідати 100 і більше машинних команд (наприклад, Пролог). Крім того, у вихідних мовах досить часто використовується сувора типізація даних, що здійснюється через їх попередній опис. Програмування може спиратися не так на кодування алгоритму, але в ретельне обдумування структур даних чи класів. Процес трансляції з таких мов зазвичай називається компіляцією, а вихідні мови зазвичай належать до мов програмування високого рівня (або високорівневим мовам). Абстрагування мови програмування від системи команд комп'ютера призвело до незалежного створення найрізноманітніших мов, орієнтованих рішення конкретних завдань. З'явилися мови для наукових розрахунків, економічних розрахунків, доступу до баз даних та інші.

Інтерпретатор - програма або пристрій, що здійснює пооператорну трансляцію та виконання вихідної програми. На відміну від компілятора, інтерпретатор не породжує на виході програму машинною мовою. Розпізнавши команду вихідної мови, він одразу виконує її. Як у компіляторах, і у інтерпретаторах використовуються однакові методи аналізу вихідного тексту програми. Але інтерпретатор дозволяє розпочати обробку даних після написання навіть однієї команди. Це робить процес розробки та налагодження програм більш гнучким. Крім того, відсутність вихідного машинного коду дозволяє не "захаращувати" зовнішні пристроїдодатковими файлами, а сам інтерпретатор можна досить легко адаптувати до будь-яких машинних архітектур, розробивши його лише один раз широко поширеною мовою програмування. Тому, інтерпретовані мови, типу Java Script, VB Script, набули широкого поширення. Недоліком інтерпретаторів є низька швидкість виконання програм. Зазвичай інтерпретовані програми виконуються у 50-100 разів повільніше програм, написаних у машинних кодах.

Емулятор - програма або програмно-технічний засіб, що забезпечує можливість без перепрограмування виконувати на даній ЕОМ програму, яка використовує коди або способи виконання операцій, відмінні від даної ЕОМ. Емулятор схожий на інтерпретатор тим, що безпосередньо виконує програму, написану деякою мовою. Однак найчастіше це машинна мова або проміжний код. І той і інший представляють команди в двійковому коді, які можуть одночасно виконуватися після розпізнавання коду операцій. На відміну від текстових програм, не потрібно розпізнавати структуру програми, виділяти операнди.

Емулятори використовуються досить часто в різних цілях. Наприклад, при розробці нових обчислювальних систем спочатку створюється емулятор, що виконує програми, що розробляються для ще неіснуючих комп'ютерів. Це дозволяє оцінити систему команд та напрацювати базове програмне забезпечення ще до того, як буде створено відповідне обладнання.

Дуже часто емулятор використовується для виконання старих програм на нових обчислювальних машинах. Зазвичай нові комп'ютери мають більш високу швидкодію і мають більш якісне периферійне обладнання. Це дозволяє емулювати старі програми більш ефективно, ніж їх виконання на старих комп'ютерах. Прикладом такого підходу є розробка емуляторів домашнього комп'ютера ZX Spectrum із мікропроцесором Z80. Досі знаходяться любителі пограти на емуляторі в застарілі, але все ще не втратили колишню привабливість, ігрові програми. Емулятор також може використовуватися як більш дешевий аналог сучасних комп'ютерних систем, забезпечуючи при цьому прийнятну продуктивність, еквівалентну молодшим моделям деякого сімейства архітектур. Як приклад можна навести емулятори IBM PC сумісних комп'ютерів, реалізовані на більш потужних комп'ютерахфірми Apple. Ряд емуляторів, написаних для IBM PC, успішно замінюють різні ігрові приставки.

Емулятор проміжного уявлення, як і інтерпретатор, можуть легко переноситися з однієї комп'ютерної архітектури в іншу, що дозволяє створювати мобільне програмне забезпечення. Саме ця властивість зумовила успіх мови програмування Java, з якого програма транслюється у проміжний код. Виконує цей код віртуальна Javaмашина є нічим іншим як емулятором, що працює під управлінням будь-якої сучасної операційної системи.

Перекодувальник - програма або програмний пристрій, що перекладають програми, написані машинною мовою однієї ЕОМ в програми машинною мовою іншої ЕОМ. Якщо емулятор є менш інтелектуальним аналогом інтерпретатора, то перекодувальник виступає в тій же якості по відношенню до компілятора. Точно також вихідний (і зазвичай двійковий) машинний код або проміжне уявлення перетворюються на інший аналогічний код по одній команді і без будь-якого загального аналізу структури вихідної програми. Перекодувальники бувають корисні при перенесенні програм з одних комп'ютерних архітектур на інші. Вони можуть також використовуватися для відновлення тексту програми мовою високого рівня за наявним двійковим кодом.

Макропроцесор - програма, що забезпечує заміну однієї послідовності символів на іншу[Браун]. Це різновид компілятора. Він здійснює генерацію вихідного тексту шляхом обробки спеціальних вставок, розміщених у вихідному тексті. Ці вставки оформляються спеціальним чином і належать конструкціям мови, яку називають макромовою. Макропроцесори часто використовуються як надбудови мов програмування, збільшуючи функціональні можливості систем програмування. Практично будь-який асемблер містить макропроцесор, що підвищує ефективність розробки машинних програм. Такі системи програмування зазвичай називаються макроассемблерів.

Макропроцесори використовують і з мовами високого рівня. Вони збільшують функціональні можливості мов PL/1, C, C++. Особливо широко макропроцесори застосовуються C і C++, дозволяючи спростити написання програм. Приклад широкого використання макропроцесорів є бібліотека класів Microsoft Foundation Classes (MFC). Через макровставки у ній реалізовані карти повідомлень та інші програмні об'єкти. При цьому макропроцесори підвищують ефективність програмування без зміни синтаксису та семантики мови.

Синтаксис сукупність правил деякої мови, визначальних формування її елементів.Інакше кажучи, це сукупність правил освіти семантично значимих послідовностей символів у цій мові. Синтаксис задається за допомогою правил, що описують поняття деякої мови. Прикладами понять є: змінна, вираз, оператор, процедура. Послідовність понять та його допустиме використання у правилах визначає синтаксично правильні структури, що утворюють програми. Саме ієрархія об'єктів, а чи не те, як вони взаємодіють між собою, визначаються через синтаксис. Наприклад, оператор може зустрічатися тільки у процедурі, а вираз в операторі, змінна може складатися з імені та необов'язкових індексів тощо. Синтаксис не пов'язаний з такими явищами у програмі як "перехід на неіснуючу мітку" або "змінна з цим ім'ям не визначена". Цим займається семантика.

Семантика - правила та умови, що визначають співвідношення між елементами мови та їх смисловими значеннями, а також інтерпретацію змістовного значення синтаксичних конструкцій мови. Об'єкти мови програмування як розміщуються у тексті відповідно до деякої ієрархією, а й додатково пов'язані між собою у вигляді інших понять, що утворюють різноманітні асоціації. Наприклад, змінна, для якої синтаксис визначає допустиме місцезнаходження тільки в описах і деяких операторах, має певний тип, може використовуватися з обмеженою кількістю операцій, має адресу, розмір і повинна бути описана до того, як буде використовуватися в програмі.

Синтаксичний аналізатор компонента компілятора, що здійснює перевірку вихідних операторів на відповідність синтаксичним правилам та семантиці даної мовипрограмування. Незважаючи на назву, аналізатор займається перевіркою і синтаксису, і семантики. Він складається з кількох блоків, кожен із яких вирішує свої завдання. Докладніше буде розглянуто під час опису структури транслятора.

Загальні особливості мов програмування та трансляторів

Мови програмування досить сильно відрізняються одна від одної за призначенням, структурою, семантичною складністю, методами реалізації. Це накладає свої особливості на розробку конкретних трансляторів.

Мови програмування є інструментами на вирішення завдань у різних предметних галузях, що визначає специфіку їх організації та відмінності за призначенням. Як приклад можна навести такі мови як Фортран, орієнтований на наукові розрахунки, C, призначений для системного програмування, Пролог, що ефективно описує завдання логічного висновку, Лісп, що використовується для рекурсивної обробки списків. Ці приклади можна продовжити. p align="justify"> Кожна з предметних областей пред'являє свої вимоги до організації самої мови. Тому можна відзначити різноманітність форм подання операторів та виразів, відмінність у наборі базових операцій, зниження ефективності програмування при вирішенні завдань, не пов'язаних з предметною областю. Мовні відмінності відбиваються у структурі трансляторів. Лісп і Пролог найчастіше виконуються як інтерпретації через те, що використовують динамічне формування типів даних під час обчислень. Для трансляторів з мови Фортран характерна агресивна оптимізація результуючого машинного коду, яка стає можливою завдяки відносно простій семантиці конструкцій мови - зокрема, через відсутність механізмів альтернативного іменування змінних через покажчики або посилання. Наявність вказівників у мові C пред'являє специфічні вимогидо динамічного розподілу пам'яті.

Структура мови характеризує ієрархічні відносини між його поняттями, що описуються синтаксичними правилами. Мови програмування можуть відрізнятися друг від друга з організації окремих понять і з відносинам з-поміж них. Мова програмування PL/1 допускає довільне вкладення процедур та функцій, тоді як у C всі функції повинні знаходитись на зовнішньому рівні вкладеності. Мова C++ допускає опис змінних у будь-якій точці програми перед першим її використанням, а Паскале змінні мають бути визначені у спеціальній області описи. Ще далі у цьому питанні йде PL/1, який допускає опис змінної після її використання. Або опис можна взагалі опустити та керуватися правилами, прийнятими за умовчанням. Залежно від прийнятого рішення, транслятор може аналізувати програму за один чи кілька проходів, що впливає швидкість трансляції.

Семантика мов програмування змінюється у дуже широких межах. Вони відрізняються як по особливостям реалізації окремих операцій, а й у парадигмам програмування, визначальним важливі розбіжності у методах розробки програм. Специфіка реалізації операцій може стосуватися як структури даних, що обробляються, так і правил обробки одних і тих же типів даних. Такі мови, як PL/1 та APL підтримують виконання матричних та векторних операцій. Більшість мов працюють в основному зі скалярами, надаючи для обробки масивів процедури та функції, написані програмістами. Але навіть при виконанні операції додавання двох цілих чисел такі мови, як C і Паскаль можуть поводитися по-різному.

Поряд із традиційним процедурним програмуванням, званим також імперативним, існують такі парадигми як функціональне програмування, логічне програмуваннята об'єктно-орієнтоване програмування. Сподіваюся, що в цьому ряду займе своє місце і запропонована процедурно-параметрична парадигма програмування [Легалов2000]. Структура понять та об'єктів мов залежить від обраної парадигми, що також впливає реалізацію транслятора.

Навіть той самий мову може бути реалізований декількома способами. Це з тим, що теорія формальних граматик допускає різні способи аналізу тих самих пропозицій. Відповідно до цього транслятори різними способами можуть отримувати той самий результат ( об'єктну програму) за початковим вихідним текстом.

Разом з тим, всі мови програмування мають ряд загальних характеристик та параметрів. Ця спільність визначає і схожі всім мов принципи організації трансляторів.

  1. Мови програмування призначені для полегшення програмування. Тому їхні оператори та структури даних потужніші, ніж у машинних мовах.
  2. Для підвищення наочності програм замість числових кодів використовуються символічні або графічні уявленняконструкцій мови, зручніші їхнього сприйняття людиною.
  3. Для будь-якої мови визначається:
  • Безліч символів, які можна використовувати для запису правильних програм (алфавіту), є основними елементами.
  • Безліч правильних програм (синтаксис).
  • "Сенс" кожної правильної програми (семантика).

Незалежно від специфіки мови будь-який транслятор можна вважати функціональним перетворювачем F, що забезпечує однозначне відображення X в Y, де X - програма вихідною мовою, Y - програма вихідною мовою. Тому сам процес трансляції формально можна уявити досить просто і зрозуміло:

Формально кожна правильна програма X - це ланцюжок символів з деякого алфавіту A, що перетворюється на відповідний їй ланцюжок Y, складений із символів алфавіту B.

Мова програмування, як будь-яка складна система, визначається через ієрархію понять, що задає взаємозв'язку між його елементами. Ці поняття пов'язані між собою відповідно до синтаксичними правилами. Кожна із програм, побудована за цими правилами, має відповідну ієрархічну структуру.

У зв'язку з цим для всіх мов та їх програм можна додатково виділити такі загальні риси: кожна мова повинна містити правила, що дозволяють створювати програми, що відповідають цій мові або розпізнавати відповідність між написаними програмами та заданою мовою.

Зв'язок структури програми з мовою програмування називається синтаксичним відображенням.

Як приклад розглянемо залежність між ієрархічною структурою та ланцюжком символів, що визначає наступне арифметичне вираз:

У більшості мов програмування цей вираз визначає ієрархію програмних об'єктів, яку можна відобразити у вигляді дерева (рис. 1.1):

У гуртках представлені символи, які у ролі елементарних конструкцій, а прямокутниках задаються складові поняття, мають ієрархічну і, можливо, рекурсивну структуру. Ця ієрархія визначається за допомогою синтаксичних правил, записаних спеціальною мовою, яка називається метамовою (докладніше метамови будуть розглянуті при вивченні формальних граматик):

<выражение> ::= <слагаемое> | <выражение> + <слагаемое>

<слагаемое> ::= <множитель> | <слагаемое> * <множитель>

<множитель> ::= <буква> | (<выражение>)

<буква>

Примітка. Знак "::=" читається як "це є". Вертикальна характеристика "|" читається як "або".

Якщо правила будуть записані інакше, то зміниться ієрархічна структура. Як приклад можна навести наступні спосібзаписи правил:

<выражение> ::= <операнд> | <выражение> + < операнд > | <выражение> * < операнд >

<операнд> ::= <буква> | (<выражение>)

<буква>::= a | b | з | d | i | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | y | z

В результаті синтаксичного аналізу того ж арифметичного виразу буде побудовано ієрархічну структуру, представлену на рис. 1.2.


Слід зазначити, що ієрархічна структура у випадку може бути жодним чином пов'язані з семантикою висловлювання. І в тому й іншому випадку пріоритет виконання операцій може бути реалізований відповідно до загальноприйнятих правил, коли множення передує додаванню (або навпаки, всі операції можуть мати однаковий пріоритет при будь-якому наборі правил). Однак перша структура явно підтримує подальшу реалізацію загальноприйнятого пріоритету, тоді як друга більше підходить для реалізації операцій з однаковим пріоритетом та їх виконання праворуч наліво.

Процес знаходження синтаксичної структури заданої програминазивається синтаксичним розбором.

Синтаксична структура, правильна для однієї мови, може бути помилковою для іншої. Наприклад, у мові Форт наведеної вираз не буде розпізнано. Однак для цієї мови коректним буде постфіксний вираз:

Його синтаксична структура описується правилами:

<выражение> ::= <буква> | <операнд> <операнд> <операция>

< операнд > ::= < буква > | < выражение >

< операция > ::= + | *

<буква>::= a | b | з | d | i | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | y | z

Ієрархічне дерево, що визначає синтаксичну структуру, представлене на рис. 1.3.

Інший характерною рисою всіх мов є їхня семантика. Вона визначає зміст операцій мови, коректність операндів. Ланцюжки, що мають однакову синтаксичну структуру в різних мовах програмування, можуть різнитися за семантикою (що, наприклад, спостерігається в C++, Pascal, Basic для наведеного вище фрагмента арифметичного виразу).

Знання семантики мови дозволяє відокремити її від його синтаксису та використовувати для перетворення на іншу мову (здійснити генерацію коду).

Опис семантики і розпізнавання її коректності зазвичай є трудомісткою і об'ємною частиною транслятора, оскільки необхідно здійснити перебір та аналіз безлічі варіантів допустимих комбінацій операцій та операндів.

Узагальнена структура транслятора

Загальні властивості та закономірності притаманні як різним мовам програмування, і трансляторам з цих мов. Вони протікають подібні процеси перетворення вихідного тексту. Незважаючи на те, що взаємодія цих процесів може бути організована різним шляхом, можна виділити функції, виконання яких призводить до однакових результатів. Назвемо такі функції фазами процесу трансляції.

Враховуючи схожість компілятора та інтерпретатора, розглянемо фази, що існують у компіляторі. У ньому виділяються:

  1. Фаза лексичного аналізу.
  2. Фаза синтаксичного аналізу, що складається з:
  • розпізнавання синтаксичної структури;
  • семантичного розбору, у якого здійснюється робота з таблицями, породження проміжного семантичного уявлення чи об'єктної моделі мови.
  • Фаза генерації коду, що здійснює:
    • семантичний аналіз компонент проміжного уявлення чи об'єктної моделі мови;
    • переведення проміжного подання або об'єктної моделі в об'єктний код.

    Поряд із основними фазами процесу трансляції можливі також додаткові фази:

      2а. Фаза дослідження та оптимізації проміжного уявлення, що складається з:
    2а.1. аналізу коректності проміжного уявлення;
    2а.2. оптимізації проміжного уявлення.
      3а. Фаза оптимізації об'єктного коду

    Інтерпретатор відрізняється тим, що фаза генерації коду зазвичай замінюється фазою емуляції елементів проміжного уявлення чи об'єктної моделі мови. Крім того, в інтерпретаторі зазвичай не проводиться оптимізація проміжного уявлення, а одразу здійснюється його емуляція.

    Крім цього можна виділити єдиний для всіх фаз процес аналізу та виправлення помилок, що існують в оброблюваному вихідному тексті програми.

    Узагальнена структура компілятора, що враховує існуючі фази, представлена ​​на рис. 1.4.

    Він складається із лексичного аналізатора, синтаксичного аналізатора, генератора коду, аналізатора помилок. В інтерпретаторі замість генератора коду використовується емулятор (рис. 1.5), який, крім елементів проміжного подання, передаються вихідні дані. На вихід емулятора видається результат обчислень.

    Лексичний аналізатор (відомий також як сканер) здійснює читання вхідного ланцюжка символів та їх угруповання елементарні конструкції, звані лексемами. Кожна лексема має клас та значення. Зазвичай претендентами на роль лексем виступають елементарні конструкції мови, наприклад ідентифікатор, дійсне число, коментар. Отримані лексеми передаються синтаксичному аналізатору. Сканер не є обов'язковою частиною транслятора. Однак він дозволяє підвищити ефективність процесу трансляції. Докладніше лексичний аналіз розглянуто у темі: "Організація лексичного аналізу".

    Синтаксичний аналізатор здійснює розбір вихідної програми, використовуючи лексеми, що надходять, побудова синтаксичної структури програми і семантичний аналіз з формуванням об'єктної моделі мови. Об'єктна модель є синтаксичною структурою, доповненою семантичними зв'язками між існуючими поняттями. Цими зв'язками можуть бути:

    • посилання на змінні, типи даних та імена процедур, що розміщуються в таблицях імен;
    • зв'язки, що визначають послідовність виконання команд;
    • зв'язки, що визначають вкладеність елементів об'єктної моделі мови та інші.

    Таким чином, синтаксичний аналізатор є складним блоком транслятора. Тому його можна розбити на такі:

    • розпізнавач;
    • блок семантичного аналізу;
    • об'єктну модель, або проміжне уявлення, що складаються з таблиці імен та синтаксичної структури.

    Узагальнена структура синтаксичного аналізатора наведена на рис. 1.6.

    Розпізнавач отримує ланцюжок лексем і її основі здійснює розбір відповідно до використовуваними правилами. Лексеми, за успішного розбору правил, передаються семантичному аналізатору, який будує таблицю імен і фіксує фрагменти синтаксичної структури. Крім цього, між таблицею імен та синтаксичною структурою фіксуються додаткові семантичні зв'язки. У результаті формується об'єктна модель програми, яка звільнена від прив'язки до синтаксису мови програмування. Досить часто замість синтаксичної структури, що повністю копіює ієрархію об'єктів мови, створюється її спрощений аналог, який називається проміжним уявленням.

    Аналізатор помилок отримує інформацію про помилки, що виникають у різних блокахтранслятор. Використовуючи отриману інформацію, він формує повідомлення користувачеві. Крім цього, цей блок може спробувати виправити помилку, щоб продовжити розбір далі. На нього також покладаються дії, пов'язані з коректним завершенням програми, якщо подальшу трансляцію продовжувати неможливо.

    Генератор коду будує код об'єктної машини з урахуванням аналізу об'єктної моделі чи проміжного представлення. Побудова коду супроводжується додатковим семантичним аналізом, пов'язаним із необхідністю перетворення узагальнених команд на коди конкретної обчислювальної машини. На етапі такого аналізу остаточно визначається можливість перетворення, та вибираються ефективні варіанти. Сама генерація коду є перекодуванням одних команд до інших.

    Варіанти взаємодії блоків транслятора

    Організація процесів трансляції, що визначає реалізацію основних фаз, може здійснюватися по-різному. Це визначається різними варіантами взаємодії блоків транслятора: лексичного аналізатора, синтаксичного аналізатора та генератора коду. Незважаючи на однаковий кінцевий результат, різні варіантивзаємодії блоків транслятора забезпечують різні варіанти зберігання проміжних даних. Можна виділити два основні варіанти взаємодії блоків транслятора:

    • багатопрохідну організацію, при якій кожна фаза є незалежним процесом, що передає управління наступній фазі тільки після закінчення повної обробки своїх даних;
    • однопрохідну організацію, коли всі фази представляють єдиний процес і передають одна одній дані невеликими фрагментами.

    На основі двох основних варіантів можна також створювати їх різноманітні поєднання.

    Багатопрохідна організація взаємодії блоків транслятора

    Даний варіант взаємодії блоків, з прикладу компілятора, представлений на рис 1.7.


    Лексичний аналізатор повністю обробляє вихідний текст, формуючи на виході ланцюжок, що складається зі всіх отриманих лексем. Тільки після цього управління передається синтаксичному аналізатору. Синтаксичний аналізатор отримує сформований ланцюжок лексем і її основі формує проміжне уявлення чи об'єктну модель. Після отримання всієї об'єктної моделі він передає керування генератору коду. Генератор коду, на основі об'єктної моделі мови, будує необхідний машинний код

    До переваг такого підходу можна віднести:

    1. Відокремленість окремих фаз, що дозволяє забезпечити їхню незалежну один від одного реалізацію та використання.
    2. Можливість зберігання даних, одержуваних в результаті роботи кожної з фаз, на зовнішніх пристроях, що запам'ятовують, і їх використання при необхідності.
    3. Можливість зменшення обсягу оперативної пам'яті, необхідної роботи транслятора, з допомогою послідовного виклику фаз.

    До недоліків слід зарахувати.

    1. Наявність великих обсягівпроміжної інформації, з якої на даний момент часу потрібно лише невелика частина.
    2. Уповільнення швидкості трансляції через послідовне виконання фаз і використання для економії оперативної пам'яті зовнішніх пристроїв.

    Цей підхід може бути зручним при побудові трансляторів з мов програмування, що має складну синтаксичну та семантичну структуру (наприклад, PL/I). У таких ситуаціях трансляцію складно здійснити один прохід, тому результати попередніх проходів простіше представляти як додаткових проміжних даних. Слід зазначити, що складні семантична та синтаксична структури мови можуть призвести до додаткових проходів, необхідних встановлення необхідних залежностей. Загальна кількість проходів може бути понад десять. На число проходів може також впливати використання у програмі конкретних можливостей мови, таких як оголошення змінних та процедур після їх використання, застосування правил оголошення за умовчанням тощо.

    Однопрохідна організація взаємодії блоків транслятора

    Один із варіантів взаємодії блоків компілятора при однопрохідній організації представлено на рис. 1.8.

    У цьому випадку процес трансляції протікає в такий спосіб. Лексичний аналізатор читає фрагмент вихідного тексту, необхідний отримання однієї лексеми. Після формування лексеми їм здійснюється виклик синтаксичного аналізатора та передача йому створеної лексеми як параметр. Якщо синтаксичний аналізатор може побудувати черговий елемент проміжного уявлення, він робить це і передає побудований фрагмент генератору коду. В іншому випадку синтаксичний аналізатор повертає управління сканеру, даючи тим самим зрозуміти, що чергова лексема оброблена і потрібні нові дані.

    Генератор коду функціонує аналогічно. За отриманим фрагментом проміжного подання він створює відповідний фрагмент об'єктного коду. Після цього керування повертається синтаксичному аналізатору.

    Після закінчення вихідного тексту та завершення обробки всіх проміжних даних кожним із блоків лексичний аналізатор ініціює процес завершення програми.

    Найчастіше в однопрохідних трансляторах використовується інша схема управління, у якій роль основного блоку грає синтаксичний аналізатор (рис. 1.9).

    Лексичний аналізатор і генератор коду виступають у ролі викликаних ним підпрограм. Щойно синтаксичному аналізатору потрібна чергова лексема, він викликає сканер. При отриманні фрагмента проміжного подання здійснюється звернення до генератора коду. Завершення процесу трансляції відбувається після отримання та обробки останньої лексеми та ініціюється синтаксичним аналізатором.

    До переваг однопрохідної схеми слід віднести відсутність великих обсягів проміжних даних, високу швидкістьобробки через суміщення фаз в єдиному процесі і відсутність звернень у зовнішніх пристроїв, що запам'ятовують.

    До недоліків належать: неможливість реалізації такої схеми трансляції для складних за структурою мов та відсутність проміжних даних, які можна використовувати для комплексного аналізу та оптимізації.

    Така схема часто застосовується для простих за семантичною та синтаксичною структурами мов програмування, як у компіляторах, так і в інтерпретаторах. Прикладами таких мов можуть бути Basic і Pascal. Класичний інтерпретатор зазвичай будується за однопрохідною схемою, оскільки безпосереднє виконання складає рівні окремих фрагментів проміжного представлення. Організація взаємодії блоків такого інтерпретатора представлена ​​на рис. 1.10.

    Комбіновані взаємодії блоків транслятора

    Поєднання багатопрохідної та однопрохідної схем трансляції породжують різноманітні комбіновані варіанти, багато з яких успішно використовуються. Як приклад, можна розглянути деякі з них.

    На рис. 1.11 представлена ​​схема взаємодії блоків транслятора, що розбиває весь процес на два проходи. У першому проході породжується повне проміжне уявлення програми, але в другому здійснюється генерація коду. Використання такої схеми дозволяє легко переносити транслятор з однієї обчислювальної системи в іншу шляхом переписування генератора коду.

    Крім цього, замість генератора коду легко підключити емулятор проміжного уявлення, що досить просто дозволяє розробити систему програмування деякою мовою, орієнтовану на різні середовища виконання. Приклад такої організації взаємодії блоків транслятора подано на рис. 1.12.


    Поряд із схемами, що передбачають заміну генератора коду на емулятор, існують транслятори, що допускають їхнє спільне використання. Одна з таких схем представлена ​​на рис. 1.13.

    Процес трансляції, включаючи генерацію коду, може бути виконаний за будь-яке число проходів (у прикладі використовується однопрохідна трансляція, представлена ​​раніше на ). Однак сформований об'єктний код не виконується на відповідній обчислювальній системі, а емулюється на комп'ютері з іншою архітектурою. Така схема застосовується у середовищі побудованої навколо мови програмуванні Java. Сам транслятор генерує код віртуальної Java-машини, емуляція якого здійснюється спеціальними засобамияк автономно, і у середовищі Internet браузера.

    Подана схема може мати і ширше тлумачення стосовно будь-якого компілятора, що породжує машинний код. Справа в тому, що більшість сучасних обчислювальних машин реалізовані з використанням мікропрограмного управління. А мікропрограмний пристрій керування можна розглядати як програму, що емулює машинний код. Це дозволяє говорити про повсюдне використання останньої схеми.

    Контрольні питання та завдання

    1. Назвіть відмінності:
      • інтерпретатора від компілятора;
      • компілятора від асемблера;
      • перекодувальника від транслятора;
      • емулятора від інтерпретатора;
      • синтаксису від семантики.
    1. Розкажіть про відомі Вам останні розробки мов програмування. Наведіть основні характеристики цих мов.
    2. Наведіть конкретні прикладивикористання методів трансляції у галузях, які пов'язані з мовами програмування.
    3. Наведіть конкретні приклади компілюваних мов програмування.
    4. Наведіть конкретні приклади інтерпретованих мов програмування.
    5. Наведіть конкретні приклади мов програмування, для яких є компілятори, так і інтерпретатори.
    6. Основні переваги та недоліки компіляторів.
    7. Основні переваги та недоліки інтерпретаторів.
    8. Опишіть основні відмінності у синтаксисі двох відомих мов програмування.
    9. Опишіть основні відмінності в семантиці двох відомих мов програмування.
    10. Назвіть основні фази процесу трансляції та їх призначення.
    11. Назвіть специфічні особливості однопрохідної трансляції.
    12. Назвіть специфічні особливості багатопрохідної трансляції.
    13. Наведіть приклади можливих комбінацій однопрохідної та багатопрохідної трансляції. Розкажіть про практичному використанніцих схем.