การแปลงรหัส Fortran 77 เป็น C #


14

ฉันพยายามแปลงโปรแกรม Fortan77 เป็น C # ฉันมีรูทีนย่อยที่มีโค้ดประมาณ 650 บรรทัดและคำสั่ง GOTO ที่น่ากลัวทั่วทุกที่ ฉันมีปัญหามากมายแม้กระทั่งเริ่มเห็นภาพการไหลของรูทีนย่อยเพื่อหาว่ามันทำอะไร

มีใครบ้างไหมที่มีประสบการณ์ในสิ่งนี้ที่สามารถให้คำแนะนำกับฉันเกี่ยวกับวิธีรับภาพรวมของรูทีนย่อยนี้ มีเครื่องมือบางอย่างที่สามารถเพิ่มความเร็วหรืออำนวยความสะดวกในการแปลงประเภทนี้หรือไม่?


1
เนื่องจากคำถามนี้เปิดกว้างมากขึ้นและกำลังมองหาคำแนะนำจึงน่าจะเหมาะสมกับโปรแกรมเมอร์ SE

4
คุณคิดว่าจะคอมไพล์มันลงใน. NET โดยใช้silverfrost.com/11/ftn95/ftn95_fortran_95_for_windows.aspxแล้วเพียงแค่อ้างอิงแอสเซมบลีหรือไม่

@ Shaun นั่นเป็นความคิดที่ดี Shaun ฉันจะดูว่าถ้าฉันไม่สามารถไปที่ใดก็ได้กับการเขียนโปรแกรมใหม่
user643192

2
ฉันรู้สึกเสียใจกับคุณ ...
marko

1
ฉันอยู่ในที่ของคุณแล้ว มันเป็นวันที่เลวร้ายที่สุดในอาชีพของฉัน
ผู้ใช้

คำตอบ:


10

จากประสบการณ์ของผมวิธีที่ดีในการทำสิ่งนี้คือการสร้างผังของรหัส Fortran พยายามแยกเป้าหมายของคำแถลง GOTO ออกเป็นบล็อกแยกและใช้แผนภาพเพื่อพยายามเข้าใจโค้ดในระดับสูง

ดูว่าคุณสามารถแทนที่ GOTO แบบโลจิคัลด้วยการวนซ้ำหรือการเรียกฟังก์ชัน ถ้าแผนภาพผลลัพธ์อยู่ในรูปแบบของโครงสร้างต้นไม้มันค่อนข้างง่ายที่จะแปลงเป็น C # โดยไม่ต้องใช้ GOTO ในท้ายที่สุดแม้ว่าคุณจะต้องเข้าใจรหัสอย่างใกล้ชิดเพื่อให้สามารถรักษาและใช้ผลลัพธ์ได้อย่างมั่นใจ


คำแนะนำที่ดีขอบคุณ! คำสั่ง GOTO ควรถูกแบน
user643192

6
@ user643192 gotoเป็นสิ่งที่มีประโยชน์มากหากใช้อย่างชาญฉลาด คุณจะไม่ไปดำเนินการที่มีประสิทธิภาพ, gotoหุ่นยนต์ขนาดใหญ่ของรัฐโดยไม่ต้อง คุณจะต้องใช้รหัสที่สร้างขึ้นของคุณเช่นกัน
SK-logic

3
มีเครื่องมือที่สามารถวาดผังงานจากรหัส Fortran ตัวอย่าง: home.comcast.net/~lchen223621
NoChance

OP: คุณไม่สามารถแบนย้อนหลังได้อย่างมีประสิทธิภาพ @EmmadKareem: ข้อเสนอแนะที่มีประโยชน์มาก
กริช

ฉันลงเอยด้วยการทำตามสิ่งที่ Daniel B แนะนำที่นี่และสร้างรหัส Fortran ให้เป็นเวอร์ชั่นบล็อก มันช่วยได้มากขอบคุณสำหรับสิ่งนั้น สำหรับ SK-logic คุณอาจพูดถูกเกี่ยวกับ GOTO ความคิดเห็นของฉันถูกสร้างขึ้นหลังจากบ่ายแรกของฉันดูรหัส ... และมี GOTO จำนวนมากอยู่ในนั้น: o (
user643192

12

นอกจากสิ่งที่ Daniel B เขียนไว้ข้างต้นฉันจะพูดสิ่งต่อไปนี้:

ก่อนอื่นรับรหัส Fortran ของคุณเพื่อทำงานกับ Fortran สำหรับ DotNet ไม่ใช่ถ้าคุณ "ไม่สามารถไปที่ใดก็ได้ด้วยการเขียนโปรแกรมใหม่" แต่ก่อนที่คุณจะลองโปรแกรมใหม่ มันจะเป็นขั้นตอนเล็ก ๆ แต่ในทิศทางที่ถูกต้อง

จากนั้นเขียนชุดทดสอบใน C # ซึ่งป้อนรหัส Fortran ด้วยการป้อนข้อมูลอะไรก็ตามที่ทำเพื่อแทะเล็มและเก็บเอาท์พุท เรียกใช้ชุดทดสอบหนึ่งครั้งและบันทึกผลลัพธ์ จากนั้นขยายชุดทดสอบเพื่อทดสอบเอาต์พุตที่ได้จากเอาต์พุตที่บันทึกไว้ สมมติว่ารหัส Fortran สร้างผลลัพธ์เดียวกันเสมอเมื่อป้อนอินพุตเดียวกันการทดสอบควรจะสำเร็จ

จากนั้นในขณะที่คุณเขียนรหัสใหม่ใน C # คุณจะเรียกใช้รหัสของคุณภายใต้ชุดทดสอบและมันจะบอกคุณว่ารหัสของคุณทำงานอย่างถูกต้องหรือไม่ความหมายไม่ว่ามันจะสร้างผลลัพธ์เดียวกันกับ Fortran รหัสที่ได้รับการป้อนข้อมูลเดียวกัน หากปราศจากมันคุณจะหลงทาง

ฉันไม่เห็นด้วยกับ @ SK-logic คุณไม่ควรใช้ gotos ใด ๆ เลยในรหัส C # ของคุณ

(แต่หวังว่าเมื่อคุณทำให้รหัส Fortran ทำงานภายใต้ DotNet คุณจะไม่เห็นเหตุผลที่จะเสียเวลาของคุณในการแปลงรหัสสปาเก็ตตี้เป็น C #)


1
ใจอธิบายทำไม "คุณไม่ควร"? เหตุผลใด ๆนอกจาก "ทุกคนเชื่อว่ามันเป็นความชั่วร้าย"? ฉันตั้งชื่อสองกรณีที่สำคัญอย่างยิ่งที่คุณต้อง ใช้ goto มิฉะนั้นคุณจะต้องเขียนโค้ดที่อ่านไม่ได้หรือไม่มีประสิทธิภาพ (หรือทั้งสองอย่าง)
SK-logic

@ SK- ตรรกะฉันไม่ได้เขียน "คุณไม่ควร" ฉันเขียน "คุณไม่ควรต้อง" ไม่ว่าในกรณีใดก็ตามที่นี่ไป: คำสั่งของ goto ทำให้โค้ดยากที่จะเข้าใจและตรวจสอบความถูกต้องของมันภายใต้สถานการณ์เกือบทั้งหมด แน่นอนว่าสิ่งเหล่านี้สามารถชี้แจงเพิ่มเติมได้ แต่โปรดงดเว้นการทำเช่นนี้ไม่ใช่สถานที่สำหรับการอภิปรายนี้ ให้เราเห็นด้วยที่จะไม่เห็นด้วย
Mike Nakis

2
การขาดgotostatemens ยังทำให้คุณรหัสยากที่จะเข้าใจในบางกรณี (และเครื่องรัฐเป็นตัวอย่างที่สำคัญที่สุดของกรณีดังกล่าว) ฉันไม่สามารถทนต่อศาสนาที่ได้รับการตีกลับอย่างโง่เขลานี้ได้ - ผู้คนต่างพูดซ้ำ BS ที่ไร้ความหมายเดิมโดยไม่พยายามทำความเข้าใจเหตุผลที่ว่าทำไม goto ถือว่าเป็นอันตราย
SK-logic

คุณเป็นหนึ่งในคนเหล่านั้นที่ไม่สามารถยืนหยัดได้หากพวกเขาไม่มีคำพูดสุดท้ายใช่มั้ย C -: =
Mike Nakis

1
@ ridecar2 ฉันเขียนเครื่องจักรสถานะที่ดีตลอดเวลา ฉันใช้คำสั่ง enums และ switch และให้ผู้แปลเขียน GOTO ในภาษาเครื่องที่สร้างขึ้น ฉันไม่เคยเห็นตัวอย่างของเครื่องรัฐที่เขียนด้วย GOTO สนใจโพสต์ตัวชี้ไปยังตัวอย่างหรือไม่
John R. Strohm

3

งานของคุณเป็นเรื่องยุ่งยาก คุณต้องรู้จัก Fortran เป็นอย่างดี คุณต้องระวังว่าฟอร์แทรนที่เหมือนกัน / แตกต่างกันอย่างไรในการคำนวณและใช้กฎการตัดและปัดเศษแบบใด นอกจากนี้คุณต้องระวังเกี่ยวกับความหมายของชนิดดั้งเดิมใน C # และ Fortran

แนวทางอื่นจากสิ่งที่ได้รับการแนะนำ (ไม่จำเป็นต้องดีกว่ามันเป็นอีกวิธีหนึ่ง):

เอ - พิจารณาเขียนรหัสใหม่ใน C # ตามความรู้ทางธุรกิจและฟังก์ชั่นใช้รหัส Fortran เช่นเดียวกับการอ้างอิง

B -Consider โดยใช้เครื่องมือเชิงพาณิชย์ที่ทำหน้าที่แปลงตัวอย่าง - DataTek

หากชุดคำสั่งแสดงถึงฟังก์ชันมาตรฐานหรือฟังก์ชั่นที่คุณสามารถซื้อ dll สำเร็จรูปสำหรับ (เช่นการรวมตัวเลข) ให้ใช้ฟังก์ชันมาตรฐานหรือผลิตภัณฑ์เชิงพาณิชย์แทนการแปลด้วยตนเองและปัญหาของคุณจะได้รับการแก้ไข

หากข้างต้นไม่ได้ตัดตอบคำถามนี้:

ฉันจำเป็นต้องปรับรหัสให้เหมาะสมหรือไม่ กล่าวอีกนัยหนึ่งมูลค่าทางธุรกิจของการใช้จ่าย 500 ชั่วโมงเพื่อทำให้โค้ดดีขึ้นคืออะไร

หากไม่มีค่าในการปรับให้เหมาะสมแปลบรรทัดรหัสโดยบรรทัดและคุณเสร็จแล้ว

หากยังไม่ดีให้ทำดังนี้

0- แปลงรหัสบรรทัด Fortran ทีละบรรทัดเป็น C # (หรือใช้ Fortan CLR)

1 - ทำการทดสอบอย่างรวดเร็วเพื่อให้แน่ใจว่ามันทำงาน

2- ใช้การกู้คืนแฟคตอริ่ง (มีเครื่องมือเชิงพาณิชย์) เพื่อช่วยคุณเขียนโค้ดในแบบที่เหมาะสมที่สุด

โชคดี.


2

วิธีง่ายๆในการบันทึกสิ่งต่าง ๆ ที่มี gotos มากมายคือการวาดผังงานและดึงสตริงตรง บางครั้งโปรแกรม F77 เป็นเพียงโปรแกรม F66 รุ่นเก่าหรือแม้แต่โปรแกรม FII ที่แย่ลง F66 ไม่มีโครงสร้าง if-then-else จึงจำเป็นต้องมี gotos สิ่งที่คุณต้องทำคือพลิกกลับเงื่อนไขเพื่อรับ if-then

F66 ไม่ได้ทำในขณะที่อย่างใดอย่างหนึ่ง แต่ F77 ทำ ขึ้นอยู่กับว่าตัวแปลงสัญญาณเป็นตัวแปลงจาก F66 เป็น F77 หรือไม่ (เช่นหลาย ๆ วันนี้คือ C ถึง C ++ หรือ C ++ ถึง C #) ที่พวกเขาใช้ F77 เช่น F66 หากคุณสามารถมองเห็นลวดลายในการเขียนโปรแกรมการแปลงนั้นทำได้ง่ายกว่ามาก


1

ก่อนที่คุณจะเริ่มต้นให้สร้างชุดทดสอบเพื่อทดสอบรหัสที่มีอยู่ ระมัดระวังให้มากเพราะจะช่วยให้เห็นพฤติกรรมที่ชัดเจน จากนั้นคุณสามารถใช้ชุดนี้เพื่อวัดประสิทธิภาพการแปลงของคุณ

นอกเหนือจากนั้นจงมีระเบียบอย่าเร่งรีบและใช้กระดาษจำนวนมากเพื่อติดตามการทำงาน


1

นี่คือวิธีที่ฉันไปเกี่ยวกับการแปลรหัสเป็น C # ตั้งแต่. NET รองรับคำสั่ง goto ฉันใช้รหัส Fortran ทั้งหมดและวางมันตามที่เป็นวิธีการใหม่เช่นเดียวกับวิธีการอื่น ๆ เนื่องจากมีรูทีนและรูทีนย่อยของ Fortran

คอมไพเลอร์เกิดข้อผิดพลาดเป็นล้านส่วนใหญ่เกี่ยวกับตัวแปรที่ไม่ได้ประกาศและการจัดรูปแบบคำสั่งบล็อกที่ไม่ถูกต้องซึ่งฉันได้ทำการล้างข้อมูลทีละรายการ ฉันยังต้องเขียนรหัสเฉพาะ Fortran บางอย่างเช่นคำสั่ง I / O และบางอย่างเช่นนั้น เมื่อทำเสร็จแล้วฉันมีแบบจำลองที่แน่นอนของรหัสต้นฉบับ

ด้วยการจัดรูปแบบที่ดีของ Visual Studio บล็อกแบบลอจิคัลนั้นง่ายต่อการระบุมากกว่าในรหัสต้นฉบับ และฉันสามารถเริ่มต้นการแถลงงบ goto ทีละคน

จากประสบการณ์นี้ฉันต้องบอกว่ามีบางกรณีที่คำสั่ง goto เป็นประโยชน์อย่างมากในการหลีกเลี่ยงการเขียนรหัสเดียวกันซ้ำแล้วซ้ำอีกแม้ว่าในหลายกรณีสามารถทำได้โดยใช้วิธีการและเรียกสิ่งเหล่านั้นซ้ำ ๆ .

ฉันยังใช้ Silverfrost รุ่นฟรีเพื่อรวบรวมรหัสต้นฉบับและตรวจสอบอย่างสม่ำเสมอเกี่ยวกับรหัสที่จัดรูปแบบใหม่ของฉันเพื่อให้แน่ใจว่าการจัดรูปแบบไม่ได้ทำให้เกิดข้อผิดพลาด


0

วิธีการทั่วไปในการ "decompiling" เช่นรหัสจะเป็นดังต่อไปนี้:

  • ก่อนอื่นให้รวบรวมเป็นแบบฟอร์มระดับล่าง (เช่น LLVM)
  • ทำการแปลง SSA (จะช่วยล้างตัวแปรในเครื่องของคุณ)
  • แบ่งการควบคุมการไหลลดลง (ถ้ามี)
  • ตรวจสอบลูปและ ifs และแทนที่ด้วยโครงสร้างระดับสูงที่เหมาะสม

แบ็กเอนด์ C ของ LLVM นั้นสามารถให้ร่างแรกได้


0

วิธีที่ดีที่สุดอย่างไม่ต้องสงสัยคือการเขียนใหม่ / refactor หรือรหัส FORTRAN เป็นวิธีที่มีโครงสร้างและตรรกะที่ดีกว่า สิ่งนี้จะบังคับให้คุณเข้าใจตรรกะดั้งเดิมก่อนที่จะพยายามพอร์ตกับ C #

นี่คือวิธีที่ฉันจะเข้าใกล้:

  • ทำความเข้าใจกับรหัสที่มีอยู่และหากจำเป็นต้องมี refactor และแม้แต่เขียนใหม่ใน FORTRAN เพื่อให้คุณสามารถทดสอบได้อย่างง่ายดาย
  • พอร์ตรหัส refactored ไปยัง C #

อย่าเสียเวลากับโปรแกรมแปลงรหัสอัตโนมัติซึ่งจะจบลงด้วยข้อความที่เหมือนกันของคำสั่ง goto เหมือนกับ FORTRAN ดั้งเดิมเนื่องจาก C # รองรับ gotos และป้ายกำกับเช่นเดียวกับที่ C ทำ


0

คุณสามารถใช้คำสั่ง goto ใน C #ได้

ข้ามคำสั่งโอนการควบคุมโปรแกรมโดยตรงกับคำสั่งที่มีป้ายกำกับ

การใช้งานทั่วไปของgotoคือการถ่ายโอนการควบคุมไปยังเลเบลตัวเรือนสวิตช์เฉพาะหรือเลเบลเริ่มต้นในคำสั่งสวิตช์

ข้ามไปสั่งนี้ยังเป็นประโยชน์ที่จะได้รับออกจากลูปซ้อนกันอย่างลึกซึ้ง ...


-2

ในการแปลงรหัส FORTRAN เก่าให้เป็นภาษาใหม่บางคนควรทำตามขั้นตอนพื้นฐานในรหัสดั้งเดิมของคุณ (1) สำหรับการตรวจสอบประเภทคงที่แปลงรหัสเป็น "IMPLICIT NONE" (2) แปลงทั้งหมดที่ถูกตัดทอนเป็นสามัญทั่วไป (3) สมมูล (4) แปลงสามัญให้เป็นโมดูลของ FORTRAN 90

จากนั้นคุณสามารถลองแปลงเป็นภาษาอื่นได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.