Estou tentando converter um programa Fortan77 para c #. Eu tenho uma sub-rotina com cerca de 650 linhas de código e declarações GOTO horríveis em todo o lugar. Estou tendo muitos problemas até começando a visualizar o fluxo da sub-rotina para descobrir o que ela faz.
Existe alguém com experiência nesse tipo de coisa que poderia me dar algum conselho sobre como obter uma visão geral desta sub-rotina? Existem algumas ferramentas disponíveis para acelerar ou facilitar esse tipo de conversão?
Respostas:
Na minha experiência, uma boa maneira de fazer isso é criar um fluxograma do código Fortran. Tente separar os destinos das instruções GOTO em blocos separados e use o diagrama para tentar entender o código em um nível alto.
Veja se você pode substituir logicamente os GOTOs por loops ou chamadas de função; se o diagrama resultante estiver na forma de uma estrutura em árvore, é relativamente fácil converter para C # sem recorrer a GOTOs. No final, porém, você precisará entender intimamente o código para poder manter e usar o resultado com confiança.
fonte
goto
é uma coisa extremamente útil se aplicada com sabedoria. Você não implementaria um autômato de estado grande e eficiente sem umgoto
. Você certamente precisará deles também no código gerado.Além do que Daniel B escreveu acima, eu diria o seguinte:
Primeiro, faça com que seu código Fortran funcione com o Fortran for DotNet. Não se você "não conseguir chegar a lugar nenhum com a reprogramação", mas antes de tentar qualquer reprogramação. Será um pequeno passo, mas na direção certa.
Em seguida, escreva um conjunto de testes em C # que alimente o código Fortran com qualquer entrada que foi feita para mastigar e armazene a saída. Execute o conjunto de testes uma vez e salve a saída. Em seguida, estenda o conjunto de testes para testar a saída produzida em relação à saída salva. Supondo que o código Fortran sempre produz a mesma saída quando alimentado com a mesma entrada, é claro que o teste deve ter sucesso.
Então, enquanto você reescreve o código em C #, você estará executando seu código no conjunto de testes e ele informará se seu código está funcionando corretamente ou não, ou seja, se está produzindo exatamente a mesma saída que o Fortran código dado a mesma entrada. Sem ele, você estará perdido.
Não concordo com a @ SK-logic, você NÃO deve usar nenhum gotos no seu código C #.
(Mas, esperançosamente, depois de fazer o código Fortran funcionar no DotNet, você não verá motivos para continuar perdendo seu tempo convertendo um pedaço de código espaguete em C #.)
fonte
goto
statemens também pode dificultar sua compreensão em alguns casos (e uma máquina de estado é o exemplo mais importante desse caso). Eu simplesmente não suporto essa religião estúpida e gótica - as pessoas continuam repetindo a mesma BS sem sentido, sem nunca tentar entender a razão pela qual goto é considerado prejudicial.Sua tarefa é complicada. Você realmente precisa conhecer bem o Fortran. Você deve ter cuidado com o quão semelhante / diferente o Fortran faz os cálculos e quais regras de truncamento e arredondamento se aplicam. Além disso, você precisa ter cuidado com os tipos primitivos que significam em C # e Fortran.
Outra abordagem do que foi sugestão (não necessariamente melhor, é apenas outra):
A - Considere reescrever o código em C # com base no conhecimento e na função do negócio, use o código Fortran apenas como referência
B - Considere usar uma ferramenta comercial que faz o trabalho de conversão - Exemplo: DataTek
Se a rotina representar uma função padrão ou uma função para a qual você pode comprar uma DLL pronta (como integração numérica), use a função padrão ou o produto comercial em vez da tradução manual, e seu problema foi resolvido.
Se o exposto acima não resolver, responda a esta pergunta:
Preciso otimizar o código ou apenas fazê-lo funcionar. Em outras palavras, qual é o valor comercial de gastar 500 horas para melhorar o código?
se não houver valor na otimização, traduza o código linha por linha e pronto.
Se isso ainda não estiver bom, então:
0-Converta o código do Fortran linha por linha em C # (ou use Fortan CLR)
1-Faça um teste rápido e verifique se ele é executado
2-Use uma re-fatoração (ferramentas comerciais estão disponíveis) para ajudá-lo a escrever o código de uma maneira mais otimizada.
Boa sorte.
fonte
Uma maneira simples de recodificar coisas com muitos gotos é desenhar um fluxograma e esticar a corda. Às vezes, os programas F77 são apenas programas F66 antigos ou programas FII ainda piores. F66 não tinha uma construção if-then-else, então gotos eram necessários. Tudo o que você precisa fazer é inverter a condição para obter um if-then.
F66 também não teve um tempo de folga, mas F77 possui. Depende se o codificador foi convertido de F66 para F77 (como muitos hoje são C para C ++ ou C ++ para C #) onde eles estão usando F77 como F66. Se você pode identificar os padrões, na codificação, é muito mais fácil converter.
fonte
Antes de começar, faça um conjunto de testes para testar o código existente. Seja muito cuidadoso, pois isso ajudará a esclarecer o comportamento. Você pode usar esse conjunto para avaliar a eficácia de sua conversão.
Além disso, seja metódico , não se apresse e use muito papel para rastrear a funcionalidade.
fonte
Aqui está a maneira como eu realmente traduzi o código em C #. Como o .NET suporta instruções goto, primeiro peguei o código Fortran inteiro e colei-o como está em um novo método, assim como tantos métodos quanto as rotinas e sub-rotinas Fortran.
O compilador apresentou um milhão de erros, principalmente sobre variáveis não declaradas e formatação incorreta de instruções de bloco, que eu resolvi uma a uma. Também tive que reescrever parte do código específico do Fortran, como instruções de E / S e coisas assim. Quando isso foi feito, eu tinha uma réplica exata do código original.
Graças à boa formatação do Visual Studio, os blocos lógicos eram muito mais fáceis de identificar do que no código original. E eu poderia começar a desvendar as instruções goto uma a uma.
A partir dessa experiência, devo dizer que há alguns casos em que as instruções goto são MUITO úteis para evitar a necessidade de reescrever o mesmo código repetidamente, embora em muitos casos o mesmo possa ser alcançado usando métodos e chamando-os repetidamente .
Também usei a versão gratuita do Silverfrost para compilar o código original e realizar verificações regulares no meu código reformatado para garantir que a reformatação não produzisse erros.
fonte
Uma abordagem genérica para "descompilar" esse código seria a seguinte:
O back-end C do LLVM pode fornecer um primeiro rascunho.
fonte
A melhor maneira, sem dúvida, é primeiro reescrever / refatorar o código FORTRAN para uma maneira melhor estruturada e lógica. Isso forçará você a entender a lógica original antes de tentar portá-la para C #.
Aqui está como eu abordaria isso:
Não perca seu tempo com um conversor de código automático que acaba com a mesma bagunça de instruções goto que o FORTRAN original, pois o C # suporta gotos e etiquetas, assim como o C.
fonte
Na falta de algo, você pode usar as instruções goto em C # .
fonte
Para converter qualquer código FORTRAN antigo em um novo idioma, alguém deve seguir algumas etapas básicas do código legado (1) para verificação de tipo estático, converter o código em "IMPLICIT NONE" (2) converter todos os truncados comuns em comuns completos (3) Remover equivalence (4) converte comum no Módulo de FORTRAN 90
Então você pode tentar converter para outros idiomas.
fonte