Mengubah kode Fortran 77 menjadi C #

14

Saya mencoba mengonversi program Fortan77 ke C #. Saya memiliki subrutin dengan sekitar 650 baris kode dan pernyataan GOTO yang mengerikan di semua tempat. Saya mengalami banyak masalah bahkan mulai memvisualisasikan aliran subrutin untuk mencari tahu apa yang dilakukannya.

Adakah orang yang berpengalaman dalam hal semacam ini yang bisa memberi saya saran tentang cara mendapatkan gambaran umum tentang subrutin ini? Apakah ada beberapa alat yang tersedia untuk mempercepat atau memfasilitasi konversi jenis ini?

pengguna643192
sumber
1
Karena pertanyaan ini lebih terbuka dan mencari saran, itu akan lebih sesuai untuk Programmer SE
4
sudahkah Anda mempertimbangkan untuk mengkompilasinya ke .NET menggunakan silverfrost.com/11/ftn95/ftn95_fortran_95_for_windows.aspx dan kemudian hanya merujuk perakitan?
@ Samun, itu ide bagus Shaun. Saya akan melihat itu jika saya tidak bisa ke mana pun dengan pemrograman ulang.
user643192
2
Aku merasa kasihan untuk Anda ...
marko
1
Saya sudah di tempat Anda. Itu adalah hari terburuk dalam karier saya.
pengguna

Jawaban:

10

Dalam pengalaman saya, cara yang baik untuk melakukannya adalah membuat diagram alur dari kode Fortran. Cobalah untuk memisahkan target pernyataan GOTO menjadi blok-blok terpisah, dan gunakan diagram untuk mencoba memahami kode pada tingkat tinggi.

Lihat apakah Anda dapat mengganti GOTO secara logis dengan loop atau panggilan fungsi; jika diagram yang dihasilkan dalam bentuk struktur pohon, relatif mudah untuk dikonversi ke C # tanpa beralih ke GOTO. Pada akhirnya, Anda harus memahami kode secara intim untuk dapat mempertahankan dan menggunakan hasilnya dengan percaya diri.

Daniel B
sumber
Saran yang bagus, terima kasih! Pernyataan GOTO harus dilarang.
user643192
6
@ user643192, gotoadalah hal yang sangat berguna jika diterapkan dengan bijak. Anda tidak akan menerapkan otomaton negara besar yang efisien tanpa a goto. Anda pasti akan membutuhkannya dalam kode yang Anda hasilkan juga.
SK-logika
3
Ada alat yang bisa menggambar diagram alur dari kode Fortran. Contoh: home.comcast.net/~lchen223621
NoChance
OP: Anda tidak dapat melarang retro-efektif. @EmmadKareem: Saran yang sangat berguna.
Kris
Saya akhirnya melakukan apa yang disarankan Daniel B di sini dan membuat versi blok dari kode Fortran. Ini sangat membantu, jadi terima kasih untuk itu. Untuk SK-logika, Anda mungkin benar tentang GOTO. Komentar saya dibuat setelah sore pertama saya melihat kode ... dan ada BANYAK GOTO di dalamnya: o (
user643192
12

Selain apa yang ditulis Daniel B di atas, saya akan mengatakan yang berikut:

Pertama, dapatkan kode Fortran Anda untuk bekerja dengan Fortran untuk DotNet. Tidak jika Anda "tidak dapat pergi ke mana pun dengan pemrograman ulang", tetapi sebelum Anda mencoba pemrograman ulang apa pun. Ini akan menjadi langkah kecil, tetapi ke arah yang benar.

Kemudian, tulis suite uji dalam C # yang mengumpankan kode Fortran dengan input apa pun yang dibuat untuk mengunyah, dan menyimpan hasilnya. Jalankan test suite satu kali, dan simpan hasilnya. Kemudian, rentangkan test suite untuk menguji output yang dihasilkan terhadap output yang disimpan. Dengan asumsi bahwa kode Fortran selalu menghasilkan output yang sama ketika diberi input yang sama, tes tentu saja harus berhasil.

Kemudian, ketika Anda menulis ulang kode dalam C #, Anda akan menjalankan kode Anda di bawah test suite, dan itu akan memberi tahu Anda apakah kode Anda berfungsi dengan baik atau tidak, artinya, apakah itu menghasilkan output yang sama persis seperti Fortran kode yang diberikan input yang sama. Tanpanya, Anda akan terhilang.

Saya tidak setuju dengan @ SK-logic, Anda TIDAK harus menggunakan semua goto sama sekali dalam kode C # Anda.

(Tapi mudah-mudahan setelah Anda membuat kode Fortran berfungsi di bawah DotNet, Anda tidak akan melihat alasan untuk terus membuang-buang waktu mengonversi sepotong kode spaghetti ke C #.)

Mike Nakis
sumber
1
pikiran menjelaskan, mengapa "kamu TIDAK BISA"? Setiap rasional argumen, selain "semua orang percaya bahwa itu adalah kejahatan"? Saya menyebutkan dua kasus yang sangat penting di mana Anda harus menggunakan goto, jika tidak, Anda akhirnya akan menulis kode yang tidak dapat dibaca atau tidak efisien (atau keduanya).
SK-logic
@ SK-logika saya tidak menulis "Anda tidak boleh", saya menulis "Anda tidak harus". Dalam kasus apa pun, ini dia: pernyataan goto membuat kode sangat sulit untuk memahami dan memverifikasi kebenarannya dalam hampir semua keadaan, dan manfaat efisiensi yang diharapkan mereka adalah sesuatu antara mitos dan kesalahpahaman. Tentu saja ini dapat diklarifikasi lebih lanjut, tetapi tolong jangan melakukan itu, ini bukan tempat untuk diskusi ini. Mari kita setuju untuk tidak setuju.
Mike Nakis
2
tidak adanya gotostatemens juga dapat membuat Anda kode sangat sulit untuk dipahami dalam beberapa kasus (dan mesin negara adalah contoh paling penting dari kasus seperti itu). Saya tidak tahan dengan agama pemukul goto-bodoh ini - orang-orang terus mengulangi BS yang sama tidak berarti tanpa pernah mencoba memahami alasan mengapa goto dianggap berbahaya.
SK-logic
Anda adalah salah satu dari orang-orang yang tidak tahan jika mereka tidak memiliki kata terakhir, eh? C -: =
Mike Nakis
1
@ ridecar2, saya menulis mesin-mesin bagus sepanjang waktu. Saya menggunakan enum dan beralih pernyataan, dan saya membiarkan kompiler menulis GOTO dalam bahasa mesin yang dihasilkan. Saya sebenarnya belum pernah melihat contoh mesin negara yang secara eksplisit ditulis dengan GOTO. Mau memposting pointer ke contoh?
John R. Strohm
3

Tugas Anda rumit. Anda benar-benar perlu mengenal Fortran dengan baik. Anda harus berhati-hati tentang seberapa mirip / berbeda Fortran melakukan perhitungan dan aturan pemotongan dan pembulatan apa yang berlaku. Juga, Anda harus berhati-hati tentang makna tipe primitif dalam C # dan Fortran.

Pendekatan lain dari apa yang telah saran (belum tentu yang lebih baik, itu hanya satu lagi):

A - Pertimbangkan menulis ulang kode dalam C # berdasarkan pada pengetahuan bisnis dan fungsinya, gunakan kode Fortran hanya sebagai referensi

B -Pertimbangkan menggunakan alat komersial yang melakukan pekerjaan konversi - Contoh: DataTek

Jika rutin merepresentasikan fungsi standar atau fungsi yang dapat Anda beli dll yang siap pakai (seperti integrasi numerik), gunakan fungsi standar atau produk komersial alih-alih terjemahan manual, dan masalah Anda telah terpecahkan.

Jika hal di atas tidak memotongnya, jawab pertanyaan ini:

Apakah saya perlu mengoptimalkan kode atau menjalankannya. Dengan kata lain, apa nilai bisnis dari menghabiskan 500 jam untuk membuat kode lebih baik?

jika tidak ada nilai dalam optimasi, terjemahkan kode baris demi baris dan Anda selesai.

Jika ini masih tidak baik, maka:

0-Konversi kode Fortran baris demi baris menjadi C # (atau gunakan Fortan CLR)

1-Lakukan tes cepat pastikan itu berjalan

2-Gunakan re-factoring (alat komersial tersedia) untuk membantu Anda menulis kode dengan cara yang lebih optimal.

Semoga berhasil.

Tidak mungkin
sumber
2

Cara sederhana pengodean ulang barang dengan banyak foto adalah dengan menggambar diagram alur dan menarik tali lurus. Terkadang, program F77 hanyalah program F66 lama atau program FII yang lebih buruk. F66 tidak memiliki konstruksi if-then-else sehingga goto diperlukan. Yang perlu Anda lakukan adalah membalikkan kondisi untuk mendapatkan if-then.

F66 juga tidak memiliki do-sementara tetapi F77 tidak. Itu tergantung pada apakah coder adalah konversi dari F66 ke F77 (seperti banyak hari ini adalah C ke C ++ atau C ++ ke C #) di mana mereka menggunakan F77 seperti F66. Jika Anda dapat menemukan polanya, dalam pengkodeannya, jauh lebih mudah untuk dikonversi.

cangkir
sumber
1

Sebelum Anda mulai, buat test suite untuk menguji kode yang ada. Jadilah sangat teliti karena ini akan membantu menjelaskan perilaku. Anda kemudian dapat menggunakan suite ini untuk mengukur efektivitas konversi Anda.

Selain itu, bersikaplah metodis , jangan terburu-buru, dan gunakan banyak kertas untuk melacak fungsionalitasnya.

Bryan Oakley
sumber
1

Inilah cara saya sebenarnya menerjemahkan kode ke dalam C #. Sejak .NET mendukung pernyataan goto, saya pertama-tama mengambil seluruh kode Fortran dan menempelkannya ke metode baru, juga, sebanyak metode yang ada seperti rutinitas dan subrutin Fortran.

Kompilator menghasilkan sejuta kesalahan, kebanyakan tentang variabel yang tidak dideklarasikan dan pemformatan pernyataan blok yang salah, yang saya selesaikan satu per satu. Saya juga harus menulis ulang beberapa kode khusus Fortran, seperti pernyataan I / O dan hal-hal seperti itu. Ketika itu selesai saya memiliki replika yang tepat dari kode asli.

Berkat pemformatan yang bagus dari Visual Studio blok logis jauh lebih mudah untuk diidentifikasi daripada di kode aslinya. Dan saya bisa mulai mengungkap pernyataan goto satu per satu.

Dari pengalaman ini saya harus mengatakan bahwa ada beberapa kasus di mana pernyataan goto sebenarnya SANGAT berguna untuk menghindari keharusan menulis ulang kode yang sama berulang kali, walaupun dalam banyak kasus hal yang sama dapat dicapai dengan menggunakan metode dan memanggil mereka berulang kali .

Saya juga menggunakan versi gratis Silverfrost untuk mengkompilasi kode asli dan melakukan pemeriksaan reguler pada kode yang diformat ulang untuk memastikan bahwa pemformatan ulang tidak menghasilkan kesalahan.

pengguna643192
sumber
0

Pendekatan umum untuk "mendekompilasi" kode seperti itu adalah sebagai berikut:

  • kompilasi dulu ke bentuk level yang lebih rendah (mis., LLVM)
  • melakukan SSA-transform di atasnya (itu akan membantu untuk membersihkan variabel lokal Anda)
  • pisahkan aliran kontrol yang tidak dapat direduksi (jika ada)
  • mendeteksi loop dan jika dan menggantinya dengan konstruksi tingkat tinggi yang tepat

Backend C LLVM sendiri dapat memberi Anda konsep pertama.

Logika SK
sumber
0

Cara terbaik tanpa ragu adalah dengan menulis ulang / refactor kode FORTRAN terlebih dahulu menjadi cara yang lebih terstruktur dan logis. Ini akan memaksa Anda untuk memahami logika asli sebelum mencoba mengirimnya ke C #.

Inilah cara saya mendekatinya:

  • Pahami kode yang ada dan jika perlu refactor dan bahkan menulis ulang dalam FORTRAN sehingga Anda dapat dengan mudah menguji bahwa itu berfungsi.
  • Port kode yang sudah di-refactored ke C #

Jangan buang waktu Anda dengan konverter kode otomatis yang hanya akan berakhir dengan kekacauan pernyataan goto yang sama dengan FORTRAN asli karena C # mendukung gotos dan label, seperti halnya C.

dodgy_coder
sumber
0

Gagal apa pun, Anda dapat menggunakan pernyataan goto di C # .

The goto Pernyataan mentransfer kontrol program langsung ke pernyataan berlabel.

Penggunaan umum dari goto adalah untuk mentransfer kontrol ke label kasus sakelar tertentu atau label default dalam pernyataan sakelar .

The goto Pernyataan ini juga berguna untuk keluar dari loop sangat bersarang ...

Wyatt Barnett
sumber
-2

Untuk mengonversi kode FORTRAN lama ke bahasa baru seseorang harus melalui beberapa langkah dasar dalam kode lawas Anda (1) untuk pemeriksaan tipe statis, konversikan kode tersebut menjadi "IMPLICIT NONE" (2) ubah semua terpotong umum menjadi sepenuhnya umum (3) Hapus kesetaraan (4) dikonversi umum ke Modul FORTRAN 90

Kemudian Anda dapat mencoba mengonversi ke bahasa lain.

Debiprasad Ghosh
sumber