Fortran 77 kodunu C # 'ya dönüştürme


14

Bir Fortan77 programı C # dönüştürmek çalışıyorum. Her yerde yaklaşık 650 satır kod ve korkunç GOTO ifadeleri ile bir altyordam var. Ne yaptığını anlamak için altyordamın akışını görselleştirmeye başlamakta bile çok sorun yaşıyorum.

Bu tür bir deneyime sahip olan ve bu alt rutine nasıl genel bir bakış getirebileceğim konusunda tavsiyede bulunabilecek biri var mı? Bu tür bir dönüşümü hızlandırmak veya kolaylaştırmak için kullanılabilecek bazı araçlar var mı?


1
Bu soru daha açık uçlu olduğu ve tavsiye aradığı için, Programcılar SE


@Shaun, bu güzel bir fikir Shaun. Yeniden programlamayla hiçbir yere varamazsam buna bakacağım.
user643192

2
Senin için üzülüyorum ...
Marko

1
Ben senin yerindeydim. Kariyerimin en kötü günleriydi.
kullanıcı

Yanıtlar:


10

Deneyimlerime göre, bunun için iyi bir yol Fortran kodunun bir akış şeması oluşturmaktır. GOTO ifadelerinin hedeflerini ayrı bloklara ayırmaya çalışın ve kodu yüksek düzeyde anlamaya çalışmak için diyagramı kullanın.

GOTO'ları mantıksal olarak döngülerle veya işlev çağrılarıyla değiştirip değiştiremeyeceğinize bakın; ortaya çıkan diyagram bir ağaç yapısı biçimindeyse, GOTO'lara başvurmadan C # 'a dönüştürmek nispeten kolaydır. Sonunda, sonucu güvenle korumak ve kullanmak için kodu iyice anlamanız gerekir.


İyi öneri, teşekkürler! GOTO ifadeleri yasaklanmalıdır.
user643192

6
@ user643192, gotoakıllıca uygulanırsa son derece yararlı bir şeydir. Olmadan, verimli, büyük devlet otomatı uygulamak gitmek olmaz goto. Ürettiğiniz kodda da kesinlikle onlara ihtiyacınız olacak.
SK-logic

3
Fortran kodundan akış şemaları çizebilen araçlar vardır. Örnek: home.comcast.net/~lchen223621
NoChance

OP: Retro-etkin olarak yasaklayamazsınız. @EmmadKareem: Çok faydalı bir öneri.
Kris

Daniel B'nin burada önerdiği şeyi yaparak sonunda Fortran kodunun blok versiyonunu yaptım. Çok yardımcı oldu, bunun için teşekkürler. SK-mantığına göre, muhtemelen GOTO'lar konusunda haklısınız. Yorumum ilk öğleden sonra koda baktıktan sonra yapıldı ... ve içinde çok sayıda GOTO var: o (
user643192 2:11

12

Daniel B'nin yukarıda yazdıklarına ek olarak, aşağıdakileri söyleyebilirim:

İlk olarak, Fortran kodunuzu DotNet için Fortran ile çalışacak şekilde alın. "Yeniden programlama ile hiçbir yere varamazsanız" değil, herhangi bir yeniden programlama girişiminde bulunmadan önce. Küçük bir adım olacak, ancak doğru yönde.

Ardından, C # 'da, test etmek için yapılan girişle Fortran kodunu besleyen ve çıktıyı saklayan bir test paketi yazın. Test paketini bir kez çalıştırın ve çıktıyı kaydedin. Ardından, üretilen çıktıyı kaydedilen çıktıya karşı test etmek için test takımını genişletin. Fortran kodunun aynı girişle beslendiğinde her zaman aynı çıkışı ürettiği varsayılarak, test elbette başarılı olmalıdır.

Daha sonra, kodu C # 'da yeniden yazarken, kodunuzu test paketinin altında çalıştırırsınız ve kodunuzun düzgün çalışıp çalışmadığını, yani Fortran ile aynı çıktıyı üretip üretmediğini size söyleyecektir. kod aynı girdi verildi. Onsuz, kaybolacaksınız.

@ SK-logic ile aynı fikirde değilim, C # kodunuzda hiç goto kullanmamalısınız.

(Ama umarım Fortran kodunu DotNet altında çalıştırdıktan sonra, bir parça spagetti kodunu C # 'a dönüştürerek zamanınızı boşa harcamayı sürdürmek için hiçbir neden göremezsiniz.)


1
zihin açıklayan, neden "yapmamalısın?" Herhangi bir rasyonel argüman, “herkes kötülük olduğuna inanıyor” mu? Gitmeniz gereken son derece önemli iki durumu adlandırdım , aksi takdirde okunamayan veya verimsiz kod (veya her ikisi) yazacaksınız.
SK-logic

@ SK-mantık "yazmamalısın" yazmadım, "yazmamalısın" yazdım. Her durumda, işte gidiyor: goto ifadeleri, kodu hemen hemen her koşulda doğruluğunu kavramak ve doğrulamak için çok zorlaştırıyor ve sözde verimlilik faydaları bir efsane ve bir yanlış anlama arasında bir şey. Tabii ki bunlar daha fazla açıklığa kavuşturulabilir, ancak lütfen bunu yapmaktan kaçınalım, bu tartışma için yer burası değil. Kabul etmemeyi kabul edelim.
Mike Nakis

2
bir durum eksikliği, gotobazı durumlarda kodlamayı anlamak için çok zor olabilir (ve durum makinesi böyle bir durumun en önemli örneğidir). Bu aptal goto-dayak dine dayanamıyorum - insanlar goto'nun zararlı olarak kabul edilmesinin nedenini anlamaya çalışmadan aynı anlamsız BS'yi tekrarlamaya devam ediyorlar.
SK-logic

Son sözleri yoksa dayanamayan insanlardan birisin, değil mi? C -: =
Mike Nakis

1
@ ridecar2, TÜM ZAMAN iyi durum makineleri yazıyorum. Enums ve switch deyimlerini kullanıyorum ve derleyicinin GOTO'ları oluşturulan makine dilinde yazmasına izin veriyorum. Aslında GOTO'larla açıkça yazılmış bir devlet makinesi örneği görmedim. Bir örneğe bir işaretçi yayınlamak ister misiniz?
John R. Strohm

3

Göreviniz zor. Gerçekten Fortran'ı iyi tanımalısın. Benzer / farklı Fortran'ın hesaplamaları nasıl yaptığı ve hangi kesme ve yuvarlama kurallarının geçerli olduğuna dikkat etmelisiniz. Ayrıca, C # ve Fortran'daki ilkel tipler konusunda dikkatli olmanız gerekir.

Öneri olandan başka bir yaklaşım (ille de daha iyi olanı değil, sadece başka bir yaklaşımdır):

C - İş bilgisi ve fonksiyonuna göre kodu C # olarak yeniden yazmayı düşünün, Fortran kodunu referans olarak kullanın

B -Dönüştürme işini yapan ticari bir araç kullanmayı düşünün - Örnek: DataTek

Rutin standart bir işlevi veya hazır bir dll (sayısal entegrasyon gibi) satın alabileceğiniz bir işlevi temsil ediyorsa, standart işlevi veya manuel çeviri yerine ticari ürünü kullanın ve sorununuz çözüldü.

Yukarıdakiler kesmezse, bu soruyu cevaplayın:

Kodu optimize etmem veya sadece çalıştırmam gerekiyor mu? Başka bir deyişle, kodu daha iyi hale getirmek için 500 saat harcamanın iş değeri nedir?

optimizasyonda bir değer yoksa, kodu satır satır çevirin ve işiniz bitti.

Bu hala iyi değilse, o zaman:

0-Fortran kodunu satır satır C # 'a dönüştürün (veya Fortan CLR kullanın)

1-Hızlı bir test yapın ve çalıştığından emin olun

2-Kodu daha optimize bir şekilde yazmanıza yardımcı olması için bir yeniden faktoring (ticari araçlar mevcuttur) kullanın.

İyi şanslar.


2

Çok sayıda gotos içeren şeyleri yeniden kodlamanın basit bir yolu, bir akış şeması çizmek ve ipi düz olarak çekmektir. Bazen F77 programları sadece eski F66 programları veya daha da kötüsü FII programlarıdır. F66'da bir if-then-else yapısı yoktu, bu yüzden gotolar gerekliydi. Tek yapmanız gereken bir if-then elde etmek için koşulu tersine çevirmektir.

F66'da da bir süre yoktu ama F77 de var. Kodlayıcının F66 gibi F77'yi kullandıkları F66'dan F77'ye (bugün C gibi C ++ veya C ++ ila C #) dönüştürülüp dönüştürülmediğine bağlıdır. Desenleri tespit edebiliyorsanız, kodlamada dönüştürmek çok daha kolaydır.


1

Başlamadan önce, mevcut kodu test etmek için bir test paketi yapın. Çok dikkatli olun, çünkü bu davranışa ışık tutmaya yardımcı olacaktır. Daha sonra bu paketi, dönüşümünüzün etkinliğini ölçmek için kullanabilirsiniz.

Bunun ötesinde, metodik olun , acele etmeyin ve işlevselliği izlemek için çok fazla kağıt kullanın.


1

İşte aslında kodu C # tercüme hakkında gitti. .NET goto ifadelerini desteklediğinden, ilk önce tüm Fortran kodunu aldım ve Fortran rutinleri ve alt rutinleri gibi birçok yönteme yeni bir yönteme yapıştırdım.

Derleyici, çoğunlukla tek tek temizlediğim, çoğunlukla bildirilmemiş değişkenler ve yanlış blok deyimi biçimlendirmesi hakkında bir milyon hata ile geldi. Ayrıca G / Ç ifadeleri ve bunun gibi şeyler gibi, Fortran'a özgü bazı kodları yeniden yazmak zorunda kaldım. Bu yapıldığında orijinal kodun tam bir kopyası vardı.

Visual Studio'nun güzel biçimlendirmesi sayesinde, mantıksal blokları tanımlamak orijinal koddan çok daha kolaydı. Ve goto ifadelerini tek tek çözmeye başlayabilirim.

Bu deneyimden, goto ifadelerinin aynı kodu tekrar tekrar yazmaktan kaçınmak için gerçekten ÇOK yararlı olduğu bazı durumlar olduğunu söylemeliyim, ancak birçok durumda aynı yöntemler kullanılarak ve bunları tekrar tekrar çağırarak elde edilebilir .

Ayrıca, yeniden biçimlendirmenin hata üretmediğinden emin olmak için orijinal kodu derlemek ve yeniden biçimlendirilmiş kodumu düzenli olarak kontrol etmek için Silverfrost'un ücretsiz sürümünü kullandım.


0

Böyle bir kodun "ayrıştırılması" için genel bir yaklaşım aşağıdaki gibi olacaktır:

  • önce daha düşük seviyeli bir formda derleyin (ör. LLVM)
  • üzerinde bir SSA dönüşümü gerçekleştirin (yerel değişkenlerinizi temizlemeye yardımcı olacaktır)
  • indirgenemez kontrol akışını bölme (varsa)
  • döngüleri ve ifs'ları tespit edin ve uygun yüksek seviyeli yapılarla değiştirin

LLVM'nin kendi C arka ucu size ilk taslak sağlayabilir.


0

Şüphesiz en iyi yol, ilk önce FORTRAN kodunu daha iyi yapılandırılmış ve mantıklı bir şekilde yeniden yazmak / yeniden düzenlemektir. Bu sizi C # 'a taşımaya çalışmadan önce orijinal mantığı anlamaya zorlayacaktır.

İşte nasıl yaklaşacağım:

  • Mevcut kodu ve gerekirse yeniden düzenleyiciyi anlayın ve hatta çalışıp çalışmadığını kolayca test edebilmeniz için FORTRAN'da yeniden yazın.
  • Yeniden düzenlenmiş kodu C # 'a aktarma

C # gibi Goto'ları ve etiketleri desteklediğinden, orijinal FORTRAN ile aynı karmaşa ifadeleriyle sonuçlanacak otomatik kod dönüştürücü ile zamanınızı boşa harcamayın.


0

Başka bir şey başarısız olursa, C # içinde goto deyimlerini kullanabilirsiniz .

Goto deyimi etiketlenmiş açıklamaya doğrudan programın kontrolünü aktarır.

Yaygın bir kullanımı Goto bir belirli switch-case etiket veya varsayılan etiket kontrolü aktarmak üzere olan anahtar deyimi.

Goto deyimi de derinden iç içe döngüler çıkmak yararlıdır ...


-2

Herhangi bir eski FORTRAN kodunu yeni bir dile dönüştürmek için, birinin eski kodunuzdaki bazı temel adımları (1) geçmesi gerekir. eşdeğeri (4) ortak FORTRAN 90 modülüne dönüştürmek

Ardından diğer dillere dönüştürmeyi deneyebilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.