Chuyển đổi mã Fortran 77 sang C #


14

Tôi đang cố gắng chuyển đổi chương trình Fortan77 sang C #. Tôi có một chương trình con với khoảng 650 dòng mã và các câu lệnh GOTO khủng khiếp ở khắp mọi nơi. Tôi gặp rất nhiều rắc rối thậm chí bắt đầu hình dung dòng chảy của chương trình con để tìm ra nó làm gì.

Có ai có kinh nghiệm về loại điều này có thể cho tôi bất kỳ lời khuyên nào về cách có được cái nhìn tổng quan về chương trình con này không? Có một số công cụ có sẵn để tăng tốc hoặc tạo điều kiện cho loại chuyển đổi này không?


1
Vì câu hỏi này đã kết thúc cởi mở hơn và tìm kiếm lời khuyên, nó sẽ phù hợp hơn với Lập trình viên SE

4
Bạn đã xem xét việc biên dịch nó thành .NET bằng cách sử dụng silverfrost.com/11/ftn95/ftn95_fortran_95_for_windows.aspx và sau đó chỉ tham khảo lắp ráp?

@Shaun, đó là một ý tưởng hay đấy Shaun. Tôi sẽ xem xét điều đó nếu tôi không thể đến bất cứ nơi nào với việc lập trình lại.
dùng643192

2
Tôi cảm thấy tiếc cho bạn ...
marko

1
Tôi đã ở vị trí của bạn. Đó là những ngày tồi tệ nhất trong sự nghiệp của tôi.
người dùng

Câu trả lời:


10

Theo kinh nghiệm của tôi, một cách hay để làm điều này là tạo ra một biểu đồ dòng mã Fortran. Cố gắng tách các mục tiêu của các câu lệnh GOTO thành các khối riêng biệt và sử dụng sơ đồ để cố gắng hiểu mã ở mức cao.

Xem nếu bạn có thể thay thế một cách hợp lý các GOTO bằng các vòng lặp hoặc các lệnh gọi hàm; nếu sơ đồ kết quả ở dạng cấu trúc cây, việc chuyển đổi sang C # tương đối dễ dàng mà không cần dùng đến GOTO. Cuối cùng, bạn sẽ cần phải hiểu mã một cách mật thiết để có thể duy trì và sử dụng kết quả một cách tự tin.


Đề nghị tốt, cảm ơn! Tuyên bố GOTO nên bị cấm.
dùng643192

6
@ user643192, gotolà một điều cực kỳ hữu ích nếu được áp dụng một cách khôn ngoan. Bạn sẽ không thực hiện một máy tự động nhà nước hiệu quả, lớn mà không có goto. Bạn chắc chắn sẽ cần chúng trong mã được tạo của bạn là tốt.
SK-logic

3
Có những công cụ có thể vẽ sơ đồ từ mã Fortran. Ví dụ: home.comcast.net/~lchen223621
NoChance 30/11/11

OP: Bạn không thể cấm retro-hiệu quả. @EmmadKareem: Gợi ý rất hữu ích.
Kris

Cuối cùng tôi đã làm những gì Daniel B ở đây gợi ý và tạo ra một phiên bản khối của mã Fortran. Nó đã giúp rất nhiều, vì vậy cảm ơn vì điều đó. Đối với SK-logic, có lẽ bạn đúng về GOTO. Nhận xét của tôi đã được đưa ra sau buổi chiều đầu tiên của tôi khi xem mã ... và có RẤT NHIỀU GOTO trong đó: o (
user643192

12

Ngoài những gì Daniel B đã viết ở trên, tôi sẽ nói như sau:

Trước tiên, hãy lấy mã Fortran của bạn để làm việc với Fortran cho DotNet. Không phải nếu bạn "không thể đến bất cứ nơi nào với việc lập trình lại", nhưng trước khi bạn thử lập trình lại. Đó sẽ là một bước nhỏ, nhưng đi đúng hướng.

Sau đó, viết một bộ kiểm tra bằng C # để cung cấp mã Fortran với bất kỳ đầu vào nào được tạo để nhai và lưu trữ đầu ra. Chạy bộ kiểm tra một lần và lưu kết quả đầu ra. Sau đó, mở rộng bộ kiểm tra để kiểm tra đầu ra được sản xuất so với đầu ra đã lưu. Giả sử rằng mã Fortran luôn tạo ra cùng một đầu ra khi được cung cấp cùng một đầu vào, thử nghiệm tất nhiên sẽ thành công.

Sau đó, trong khi bạn đang viết lại mã trong C #, bạn sẽ chạy mã của mình trong bộ kiểm tra và nó sẽ cho bạn biết mã của bạn có hoạt động đúng hay không, nghĩa là nó có tạo ra đầu ra chính xác như Fortran không mã cho cùng một đầu vào. Không có nó, bạn sẽ lạc lối.

Tôi không đồng ý với @ SK-logic, bạn KHÔNG nên sử dụng bất kỳ gotos nào trong mã C # của mình.

(Nhưng hy vọng rằng một khi bạn đã làm cho mã Fortran hoạt động trong DotNet, bạn sẽ không có lý do gì để tiếp tục lãng phí thời gian của mình để chuyển đổi một đoạn mã spaghetti thành C #.)


1
tâm trí giải thích, tại sao "bạn không nên"? Bất kỳ lẽ hợp lý , ngoài "tất cả mọi người tin rằng đó là xấu xa"? Tôi đã đặt tên cho hai trường hợp cực kỳ quan trọng khi bạn phải sử dụng goto, nếu không bạn sẽ viết mã không thể đọc được hoặc không hiệu quả (hoặc cả hai).
SK-logic

@ SK-logic Tôi không viết "bạn KHÔNG nên", tôi đã viết "bạn KHÔNG nên". Trong mọi trường hợp, đây là: các câu lệnh goto làm cho mã rất khó để hiểu và xác minh tính đúng đắn của nó trong hầu hết mọi trường hợp, và lợi ích hiệu quả được cho là của chúng là một cái gì đó giữa một huyền thoại và một quan niệm sai lầm. Tất nhiên những điều này có thể được làm rõ thêm, nhưng xin vui lòng không làm điều đó, đây không phải là nơi cho cuộc thảo luận này. Hãy để chúng tôi chỉ đồng ý không đồng ý.
Mike Nakis

2
sự vắng mặt của stHRens gotocũng có thể khiến bạn viết mã rất khó hiểu trong một số trường hợp (và một máy trạng thái là ví dụ quan trọng nhất của trường hợp đó). Tôi chỉ không thể chịu được tôn giáo goto-bashing ngu ngốc này - mọi người cứ lặp đi lặp lại cùng một BS vô nghĩa mà không bao giờ cố gắng hiểu lý do tại sao goto bị coi là có hại.
SK-logic

Bạn là một trong những người không thể chịu đựng được nếu họ không có từ cuối cùng, eh? C -: =
Mike Nakis

1
@ Ridecar2, tôi viết máy trạng thái tốt TẤT CẢ THỜI GIAN. Tôi sử dụng enums và chuyển đổi các câu lệnh và tôi để trình biên dịch viết các GOTO bằng ngôn ngữ máy được tạo. Tôi thực sự chưa bao giờ thấy một ví dụ về một máy trạng thái được viết rõ ràng bằng GOTOs. Quan tâm để gửi một con trỏ đến một ví dụ?
John R. Strohm

3

Nhiệm vụ của bạn là khó khăn. Bạn thực sự cần phải biết rõ Fortran. Bạn phải cẩn thận về cách tính toán tương tự / khác nhau của Fortran và áp dụng quy tắc cắt xén và làm tròn nào. Ngoài ra, bạn cần cẩn thận về các loại nguyên thủy có nghĩa trong C # và Fortran.

Một cách tiếp cận khác từ những gì đã được đề xuất (không nhất thiết là một cách tốt hơn, nó chỉ là một cách khác):

A - Cân nhắc viết lại mã bằng C # dựa trên kiến ​​thức kinh doanh và chức năng, sử dụng mã Fortran làm tài liệu tham khảo

B -Consider sử dụng một công cụ thương mại thực hiện công việc chuyển đổi - Ví dụ: DataTek

Nếu thường trình đại diện cho một chức năng tiêu chuẩn hoặc một chức năng mà bạn có thể mua một dll đã sẵn sàng cho (chẳng hạn như tích hợp số), hãy sử dụng chức năng tiêu chuẩn hoặc sản phẩm thương mại thay vì dịch thủ công và vấn đề của bạn đã được giải quyết.

Nếu ở trên không cắt nó, trả lời câu hỏi này:

Tôi có cần tối ưu hóa mã hay chỉ làm cho nó chạy. Nói cách khác, giá trị kinh doanh của việc dành 500 giờ để làm cho mã tốt hơn là gì?

nếu không có giá trị tối ưu hóa, hãy dịch từng dòng mã và bạn đã hoàn thành.

Nếu điều này vẫn không tốt, thì:

0-Chuyển đổi dòng mã Fortran theo dòng thành C # (hoặc sử dụng Fortan CLR)

1-Làm một bài kiểm tra nhanh đảm bảo nó chạy

2-Sử dụng bao thanh toán lại (công cụ thương mại có sẵn) để giúp bạn viết mã theo cách tối ưu hơn.

Chúc may mắn.


2

Một cách đơn giản để mã hóa lại các công cụ có nhiều gotos là vẽ sơ đồ và kéo chuỗi thẳng. Đôi khi, các chương trình F77 chỉ là các chương trình F66 cũ hoặc thậm chí các chương trình FII tồi tệ hơn. F66 không có cấu trúc if-then-other nên gotos là cần thiết. Tất cả những gì bạn cần làm là đảo ngược điều kiện để có được if-then.

F66 cũng không có thời gian thực hiện nhưng F77 thì có. Nó phụ thuộc vào việc bộ mã hóa là một chuyển đổi từ F66 sang F77 (giống như nhiều người ngày nay là C sang C ++ hoặc C ++ sang C #) trong đó họ đang sử dụng F77 như F66. Nếu bạn có thể phát hiện ra các mẫu, trong mã hóa, việc chuyển đổi sẽ dễ dàng hơn nhiều.


1

Trước khi bạn bắt đầu, hãy tạo một bộ kiểm tra để kiểm tra mã hiện có. Hãy thật kỹ lưỡng vì điều này sẽ giúp làm sáng tỏ hành vi. Sau đó, bạn có thể sử dụng bộ công cụ này để đánh giá hiệu quả chuyển đổi của mình.

Ngoài ra, hãy cẩn thận , đừng vội vàng và sử dụng nhiều giấy để tìm ra chức năng.


1

Đây là cách tôi thực sự đã đi về việc dịch mã sang C #. Vì .NET hỗ trợ các câu lệnh goto, trước tiên tôi đã lấy toàn bộ mã Fortran và dán nó vào một phương thức mới, cũng như nhiều phương thức như có các thường trình và chương trình con của Fortran.

Trình biên dịch đã đưa ra một triệu lỗi, chủ yếu là về các biến không được khai báo và định dạng câu lệnh khối không chính xác, tôi đã xóa từng cái một. Tôi cũng đã phải viết lại một số mã dành riêng cho Fortran, như các câu lệnh I / O và những thứ tương tự. Khi điều đó được thực hiện, tôi đã có một bản sao chính xác của mã gốc.

Nhờ định dạng đẹp của Visual Studio, các khối logic dễ xác định hơn rất nhiều so với mã gốc. Và tôi có thể bắt đầu làm sáng tỏ từng câu lệnh goto.

Từ kinh nghiệm này, tôi phải nói rằng có một số trường hợp các câu lệnh goto thực sự RẤT hữu ích để tránh phải viết lại cùng một mã nhiều lần, mặc dù trong rất nhiều trường hợp có thể đạt được điều tương tự bằng cách sử dụng các phương thức và gọi chúng nhiều lần .

Tôi cũng đã sử dụng phiên bản miễn phí của Silverfrost để biên dịch mã gốc và kiểm tra thường xuyên trên mã được định dạng lại của mình để đảm bảo rằng việc định dạng lại không gây ra lỗi.


0

Một cách tiếp cận chung để "dịch ngược" mã như vậy sẽ là như sau:

  • đầu tiên biên dịch nó thành một dạng cấp thấp hơn (ví dụ: LLVM)
  • thực hiện chuyển đổi SSA trên nó (nó sẽ giúp dọn sạch các biến cục bộ của bạn)
  • phân chia luồng điều khiển không thể giảm (nếu có)
  • phát hiện các vòng lặp và if và thay thế chúng bằng các cấu trúc mức cao thích hợp

Phần cuối C của LLVM có thể cung cấp cho bạn bản nháp đầu tiên.


0

Cách tốt nhất mà không nghi ngờ gì là trước tiên hãy viết lại / cấu trúc lại mã FORTRAN thành một cách có cấu trúc và logic tốt hơn. Điều này sẽ buộc bạn phải hiểu logic ban đầu trước khi thử chuyển nó sang C #.

Đây là cách tôi sẽ tiếp cận nó:

  • Hiểu mã hiện có và nếu cần cấu trúc lại và thậm chí viết lại nó trong FORTRAN để bạn có thể kiểm tra dễ dàng rằng nó hoạt động.
  • Chuyển mã được tái cấu trúc sang C #

Đừng lãng phí thời gian của bạn với một trình chuyển đổi mã tự động, nó sẽ kết thúc với cùng một câu lệnh goto giống như FORTRAN ban đầu vì C # hỗ trợ gotos và nhãn, giống như C làm.


0

Không có gì khác, bạn có thể sử dụng câu lệnh goto trong C # .

Câu lệnh goto chuyển điều khiển chương trình trực tiếp sang câu lệnh được gắn nhãn.

Một cách sử dụng phổ biến của goto là chuyển điều khiển sang nhãn trường hợp chuyển đổi cụ thể hoặc nhãn mặc định trong câu lệnh chuyển đổi .

Các goto tuyên bố cũng rất hữu ích để thoát khỏi vòng lặp lồng nhau sâu sắc ...


-2

Để chuyển đổi bất kỳ mã FORTRAN cũ nào sang ngôn ngữ mới, ai đó cần thực hiện một số bước cơ bản trong mã kế thừa của bạn (1) để kiểm tra kiểu tĩnh chuyển đổi mã thành "IMPLICIT NONE" (2) chuyển đổi tất cả phổ biến bị cắt cụt thành phổ biến hoàn toàn (3) Xóa tương đương (4) chuyển đổi phổ biến thành Mô-đun FORTRAN 90

Sau đó, bạn có thể cố gắng chuyển đổi sang các ngôn ngữ khác.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.