Програмне забезпечення для перекладу початкового коду з одних мов програмування на інші

Міністерство  освіти і науки України

Національний  авіаційний університет

Факультет комп'ютерних систем 
 
 
 
 
 
 
 
 
 
 
 

Курсова робота

з  системного програмного забезпечення 

Пояснювальна  записка 
 
 

Тема: Програмне забезпечення для перекладу початкового коду з одних мов програмування на інші. 
 
 
 
 
 
 
 
 
 
 
 

                  Виконала:

                  студентка ФКС - 307

                  Бундзяк Олександра 

                  Прийняв: Глазок О.М.  
                   
                   
                   
                   

Київ  – 2009 
Зміст
 

  1. Завдання  на курсову роботу        3 
  2. Теоретична частина          4
  3. Практична частина          6

      3.1 Конвертери мов програмування для ОС Linux        6

      3.1.1 Програма  OpenCobol        6

         3.1.1 Програма F2C         13

      3.2 Конвертери мов програмування для ОС Windows    15

         3.2.1 Програма BCX         15

  1. Висновки           22
  2. Список використаної літератури        23
 

 

       1. Завдання на курсову роботу 

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

     Розглянути  відповідні засоби для ОС Windows та Linux.

 

      2. Теоретична частина 

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

     Багато  фірм-розробників ставили перед собою ціль «розробити конвертери, які б працювали в режимі простого майстра, і з якими могла б працювати люба секретарка», але це виявилося зовсім не легко.

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

     

     Рис.1 Відображення мовних конструкцій 

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

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

        

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

     На  сьогодні вже існує велике різноманіття таких утиліт-конвертерів, але досконалих майже не існує. 

 

     3. Практична частина 

     Розглянемо  роботу конвертерів мов програмування  на прикладі програми BCX (перетворення програмного коду з мови програмування Basic на мову C) для операційної системи Windows та програм f2cpp (fortran to C++) та Open-cobol (компілятор для мови програмування Cobol та конвертер з мови Cobol на мову C) для ОС Linux. 
 

3.1 Конвертери мов програмування для ОС Linux 

3.1.1 Програма OpenСobol

     OpenCOBOL є відкритим вихідним COBOL компілятор. OpenCOBOL реалізує значну частину COBOL 85 і COBOL 2002 стандартів, а також багато розширень існуючих компіляторів COBOL. 

     Також, OpenCOBOL перекладає COBOL в С і компілює перекладений код за допомогою власного компілятора C. Ми можете працювати з цією програмою на різних платформах, включаючи Unix / Linux, Mac OS X і Microsoft Windows. 

     Для ознайомлення з програмою, я встановила пакет Open-cobol-1.1.0 на Ubuntu 8 – дистрибутиві ОС Linux. 

     Ознайомлення я почала з написаної простої програми на мові Cobol (рис. 2), яку я зберегла у файлі під назвою Hello.cob:

Рис. 2 Код програми на мові Cobol 

     Для перевірки її роботи, за допомогою командного рядка і команди cobc –x hello.cob створимо виконувану програму  hello і запустимо її на виконання з допомогою команди ./hello. В результаті отримаємо: Hello World! (рис. 3)

Рис. 3 Результат виконання команд cobc –x hello.cob та ./hello 

     Для перекладу коду програми Hello, написаного на мові Cobol в мову програмування C використаємо команду cobc –C hello.cob . В директорії, де знаходився файл hello.cob з’явилося ще три файли hello.c, hello.c.h та hello.c.l.h .

     Відкривши файл hello.c ми вже побачили програмний код, написаний на мові C. І зразу замітили різницю між кодом, написаним вручну і кодом, перекладеним автоматично мовним конвертером. Об’єм коду є значно більшим.  

/* Generated by            cobc 1.1.0 */

/* Generated from          hello.cob */

/* Generated at            Дек 17 2009 02:22:57 EET */

/* OpenCOBOL build date    Dec 13 2009 20:50:05 */

/* OpenCOBOL package date  Feb 06 2009 10:30:55 CET */

/* Compile command         cobc -C hello.cob */ 

#define  __USE_STRING_INLINES 1

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <math.h>

#include <libcob.h> 

#define COB_SOURCE_FILE  "hello.cob"

#define COB_PACKAGE_VERSION "1.1"

#define COB_PATCH_LEVEL  0 

/* Global variables */

#include "hello.c.h" 

/* Function prototypes */ 

int HELLO (void);

static int HELLO_ (const int); 

/* Functions */ 

int

HELLO ()

{

  return HELLO_ (0);

} 

static int

HELLO_ (const int entry)

{

  /* Local variables */

  #include "hello.c.l.h" 

  static int initialized = 0;

  static cob_field *cob_user_parameters[COB_MAX_FIELD_PARAMS];

  static struct cob_module module = { NULL, NULL, NULL, NULL, cob_user_parameters, 0, '.', '$', ',', 1, 1, 1, 0 }; 

  /* Start of function code */ 

  /* CANCEL callback handling */

  if (unlikely(entry < 0)) {

   if (!initialized) {

    return 0;

   }

   initialized = 0;

   return 0;

  } 

  /* Initialize frame stack */

  frame_ptr = &frame_stack[0];

  frame_ptr->perform_through = 0; 

  /* Push module stack */

  module.next = cob_current_module;

  cob_current_module = &module; 

  /* Initialize program */

  if (unlikely(initialized == 0))

    {

      if (!cob_initialized) {

        cob_fatal_error (COB_FERROR_INITIALIZED);

      }

      cob_check_version (COB_SOURCE_FILE, COB_PACKAGE_VERSION, COB_PATCH_LEVEL);

      if (module.next)

        cob_set_cancel ((const char *)"HELLO", (void *)HELLO, (void *)HELLO_);

      (*(int *) (b_1)) = 0;

      initialized = 1;

    }

  cob_save_call_params = cob_call_params; 

  /* Entry dispatch */

  goto l_2; 

  /* PROCEDURE DIVISION */

  /* Entry HELLO */ 

  l_2:; 

  /* MAIN SECTION */

  /* MAIN PARAGRAPH */ 

  /* hello.cob:7: DISPLAY */

  {

    cob_display (0, 1, 1, &c_1);

  }

  /* hello.cob:8: GOBACK */

  {

    goto exit_program;

  }

  /* Program exit */ 

  exit_program: 

  /* Pop module stack */

  cob_current_module = cob_current_module->next; 

  /* Program return */

  return (*(int *) (b_1));

} 

/* End functions */

Вмістиме файла  hello.c.h: 

/* Generated by            cobc 1.1.0 */

/* Generated from          hello.cob */

/* Generated at            Дек 17 2009 02:22:57 EET */

/* OpenCOBOL build date    Dec 13 2009 20:50:05 */

/* OpenCOBOL package date  Feb 06 2009 10:30:55 CET */

/* Compile command         cobc -C hello.cob */ 

/* Frame stack declaration */

struct cob_frame {

      int perform_through;

      void *return_address;

}; 

/* Union for CALL statement */

union cob_call_union {

      void *(*funcptr)();

      int  (*funcint)();

      void *func_void;

};

union cob_call_union cob_unifunc; 
 

/* Storage */ 

/* PROGRAM-ID : HELLO */

static unsigned char b_1[4] __attribute__((aligned)); /* RETURN-CODE */ 

/* End of storage */ 
 

/* Attributes */ 

static const cob_field_attr a_1 = {33, 0, 0, 0, NULL};

/* Constants */

static cob_field c_1 = {12, (unsigned char *)"Hello World!", &a_1}; 
 
 

     Також за допомогою програми Open-cobol ми можемо перекласти код на машинну мову, на мову assembler. Зробимо це за допомогою команди cobc –S hello.cob. (рис. 4) 

Рис. 4 Команда cobc –S hello.cob 

 

      Ми бачимо, що в нас з’явився файл hello.s. Відкривши його ми вже побачимо цю ж програму Hello world, але перекладену вже на асемблер: 

     .file "cob6941_0.c"

      .section .rodata

      .align 4

      .type a_1, @object

      .size a_1, 8

a_1:

      .byte 33

      .byte 0

      .byte 0

      .byte 0

      .long 0

.LC0:

      .string "Hello World!"

      .data

      .align 4

      .type c_1, @object

      .size c_1, 12

c_1:

      .long 12

      .long .LC0

      .long a_1

      .text

.globl HELLO

      .type HELLO, @function

HELLO:

      pushl %ebp

      movl %esp, %ebp

      subl $8, %esp

      movl $0, (%esp)

      call HELLO_

      leave

      ret

      .size HELLO, .-HELLO

      .data

      .align 4

      .type module.6240, @object

      .size module.6240, 28

module.6240:

      .long 0

      .long 0

      .long 0

      .long 0

      .long cob_user_parameters.6239

      .byte 0

      .byte 46

      .byte 36

      .byte 44

      .byte 1

      .byte 1

      .byte 1

      .byte 0

      .local cob_user_parameters.6239

      .comm cob_user_parameters.6239,256,32

      .local initialized.6238

      .comm initialized.6238,4,4

      .section .rodata

.LC1:

      .string "1.1"

.LC2:

      .string "hello.cob"

.LC3:

      .string "HELLO"

      .text

      .type HELLO_, @function

HELLO_:

      pushl %ebp

      movl %esp, %ebp

      subl $2072, %esp

      movl 8(%ebp), %eax

      shrl $31, %eax

      testl %eax, %eax

      je .L4

      movl initialized.6238, %eax

      testl %eax, %eax

      jne .L6

      movl $0, -2052(%ebp)

      jmp .L8

.L6:

      movl $0, initialized.6238

      movl $0, -2052(%ebp)

      jmp .L8

.L4:

      leal -2044(%ebp), %eax

      movl %eax, -4(%ebp)

      movl -4(%ebp), %eax

      movl $0, (%eax)

      movl cob_current_module, %eax

      movl %eax, module.6240

      movl $module.6240, cob_current_module

      movl initialized.6238, %eax

      testl %eax, %eax

      sete %al

      movzbl %al, %eax

      testl %eax, %eax

      je .L9

      movl cob_initialized, %eax

      testl %eax, %eax

      jne .L11

      movl $0, (%esp)

      call cob_fatal_error

.L11:

      movl $0, 8(%esp)

      movl $.LC1, 4(%esp)

      movl $.LC2, (%esp)

      call cob_check_version

      movl module.6240, %eax

      testl %eax, %eax

      je .L13

      movl $HELLO_, 8(%esp)

      movl $HELLO, 4(%esp)

      movl $.LC3, (%esp)

      call cob_set_cancel

.L13:

      movl $b_1, %eax

      movl $0, (%eax)

      movl $1, initialized.6238

.L9:

      movl cob_call_params, %eax

      movl %eax, cob_save_call_params

.L15:

      movl $c_1, 12(%esp)

      movl $1, 8(%esp)

      movl $1, 4(%esp)

      movl $0, (%esp)

      call cob_display

.L16:

      movl cob_current_module, %eax

      movl (%eax), %eax

      movl %eax, cob_current_module

      movl $b_1, %eax

      movl (%eax), %eax

      movl %eax, -2052(%ebp)

.L8:

      movl -2052(%ebp), %eax

      leave

      ret

      .size HELLO_, .-HELLO_

      .local b_1

      .comm b_1,4,16

      .comm cob_unifunc,4,4

      .ident "GCC: (GNU) 4.2.4 (Ubuntu 4.2.4-1ubuntu4)"

      .section .note.GNU-stack,"",@progbits 
 
 

 

3.1.2 Програма F2С 

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

     f2c - досить відомий конвертер з  Fortran 77 в C, який розповсюджується  у вихідному коді (реалізований на мові C). Дозволяє створити програму на мові C з вихідного коду на Fortran 77.  

Переваги f2c:

є безкоштовним

добре налагоджений

генерує досить швидкий код 

     Я випробувала конвертер f2c також на Ubuntu 8. Він є вбудованою утилітою в Linux.

     Розглянемо його роботу на такій же програмі hello world, що й в попередньому розділі, але написану на мові програмування Fortran. Збережемо її у файлі hello.f. Вона буде мати вигляд (рис. 5  )

Рис. 5 Вигляд програми “hello world” на мові Fortran 

     Скомпілюємо файл проекта конвертером f2c з допомогою команди

     f2c -a -C++ -p hello.f (рис. 6) 

Рис. 6 Задання команди f2c -a -C++ -p hello.f

 

      Створиться файл hello.c, після відкриття якого ми побачимо код програми на мові програмування С: 

/* hello.f -- translated by f2c (version 20050501).

   You must link the resulting object file with libf2c:

      on Microsoft Windows system, link with libf2c.lib;

      on Linux or Unix systems, link with .../path/to/libf2c.a -lm

      or, if you install libf2c.a in a standard place, with -lf2c -lm

      -- in that order, at the end of the command line, as in

            cc *.o -lf2c -lm

      Source for libf2c is in /netlib/f2c/libf2c.zip, e.g., 

            http://www.netlib.org/f2c/libf2c.zip

*/ 

#ifdef __cplusplus

extern "C" {

#endif

#include "f2c.h" 

/* Table of constant values */ 

static integer c__9 = 9;

static integer c__1 = 1; 

/* Main program */ int MAIN__()

{

    /* Builtin functions */

    integer s_wsle(cilist *), do_lio(integer *, integer *, char *, ftnlen),

          e_wsle(); 

    /* Fortran I/O blocks */

    static cilist io___1 = { 0, 6, 0, 0, 0 }; 
 

    s_wsle(&io___1);

    do_lio(&c__9, &c__1, "Hello World!", (ftnlen)12);

    e_wsle();

    return 0;

} /* MAIN__ */ 

/* Main program alias */ int hello_ () { MAIN__ (); return 0; }

#ifdef __cplusplus

      }

#endif 
 
 
 

 

3.2 Конвертери мов програмування для ОС Windows 

3.2.1 Програма BCX 

     Безкоштовний  транслятор Basic в C. Для компіляції програм  необхідно встановити С компілятор LCC-Win32. Мова являє собою суміш Qbasic, PowerBasic, та VB. Можна використовувати всі можливості наявні в мові С. Транслятор може створювати GUI, консольні і DLL програми. BCX зручний для Бейсік-програмістів , які вивчають мову С, можна ввести програму на Бейсіку, відтранслювати її в С, а потім порівнювати два лістинги.

        

     Перед початком роботи, установимо програму BCX та компілятор LCC-Win32, необхідний для компіляції С програм. Тепер почнемо ознайомлення з самою програмою. 

     До пакету BCX входять такі додатки:

     BCX Code Editor

     BCX to EXE Tool

     Menu Maker

     BCX MsgBox Builder

     Jen's File Editor 

     BCX Code Editor

     BCX Code Editor – редактор коду BCX. Для ознайомлення з роботою конвертера напишемо в ньому код простої програми на мові Basiс (рис. 7) яка буде виводити на екран текст: ”Hello World!” , та збережемо його під назвою hello.bas 

      Рис. 7 Вікно редактора  коду BCX з кодом  програми 
 

     BCX to EXE Tool

     За  допомогою цього додатку можна  відкомпілювати програму написану на мові Basic, перекласти її на мову С та створити виконуючі файли. Що ми й зробили.

       В розділі Tool Path ми вказали шлях до файлу BC.exe, за допомогою якого виконується переклад коду з мови програмування Basic на мову С, та файлу lcc.exe, за допомогою якого вже компілюється код, перекладений на мову С. В розділі My Program Path вкажемо директорію файлу hello.bas, який ми створили на попередньому етапі роботи за допомогою BCX Code Editor.

     Після натиснення на кнопку Start, можна побачити етапи роботи програми:

    • Creating C files… На цьому етапі код, який знаходиться у файлі hello.bas, перекладається на мову С і створюється файл hello.c.
    • Compiling. На другому етапі відбувається компіляція файлу hello.c за допомогою С компілятора Lcc-win32.
    • Linking obj files and creating executable… Створення obj файлів і виконуваного
    • Якщо не виявлено жодних помилок в коді, компіляція пройшла успішно, можна побачити повідомлення Ready – Compiled successfully!
Програмне забезпечення для перекладу початкового коду з одних мов програмування на інші