A syntax-based utility for translating Pascal/Delphi code into C++
Don't get me wrong, I don't dislike Borland Delphi - it is a fine solution for rapid application and user interface development.
But some things just never should have been written in that language. Using Delphi in complex, low-level, performance-critical code (such as simulation engines) can just kill your ability to evolve the code base and take advantage of the powerful features of a language like C++.
Even if Delphi probably matches the flexibility of ANSI C90 for low-level code, it will make it cumbersome to adopt new technologies and libraries that are readily available for the mainstream C and C++ languages. Also, Delphi will make it difficult to hire the best engineers for some technical projects, as those will not want to be using what is a niche language in their field of expertise.
So what do you do when you happen to receive, as I did, the responsibility of a large code base that has been written in Delphi, but never should have been?
If you think "Just dump it, and start from scratch", go read about those who tried, and think again.
A perfect translator?
As others, I have been looking for a utility that would allow me to translate Delphi code into C++.
In the early nineties, an excellent p2c tool has been released under the GPL. It would translate large Pascal programs into C code - which is absolutely great when it works. Unfortunately, this utility hasn't evolved much, and does not support advanced Object Pascal constructs and other features that are common in current Delphi code. We didn't have the resources to undertake the development of such extensions.
Of course, Borland C++ Builder allows you to use Delphi units from C++ code, and automatically generates C++ .h headers from pascal .pas files. Works fine, but it is somewhat the reverse of what we needed (replace low-level code with C++, and use that from Delphi). And it wasn't actually going to help translate any code.
At the time (2002), we chose to develop a simple utility for speeding up the translation of some Delphi Pascal modules into C++ when needed.
Note that with the advent of Delphi.NET, which was not available then, it has since become easier to use Delphi in combination with other languages.
A progressive approach
What we first had to do was to refactor and modularize the application into
- a GUI front-end, which can forever remain written in Delphi, as the language and IDE excel at this
- a small number back-end engines, which were to be translated into C++, or replaced altogether.
We think our approach has been successful in that: we were able to sustain the periodic release of software updates; it has resulted in an improved code base, and a more flexible architecture; and most importantly, our customers have never been confronted with a regression in the features of our product. This is to be compared with what typically happens when a rewrite is undertaken
This code translation solution
This program was initially developed in a week or so, in C++, using the GNU flex tool to generate a low-level parser (available for Windows here). flex is a bit archaic, but still a robust and efficient solution for text parsing; alternative solutions include the ANTLR code generator, or the spririt C++ template library.
Since its first publication, this translator has also been updated based on requests and contributions of a number of users who downloaded it (Thank you!).
The purpose of this translator is to automate a lot of the grunt work required translate Delphi/Pascal files to C++. It reads a .pas file and outputs a .h header and a .cpp implementation file. The program is written in about 1000 lines of C++ code.
The translator usually does a good job translating algorithms and various utilities. It also seeks to preserve the original formatting of the code in the generated files. However, the generated code will often not compile as is, and further editing and refactoring is usually needed.
This syntax-based translator is not a compiler; it does not understand the type of the variables being used, and has therefore limited capabilities. But it does a decent job saving time during a translation process. Some features of Delphi that are known to be incorrectly or partially translated; in the generated code, they are highlighted with a special comment ( /*?*/ ).
I hope this utility program will be useful to anyone who wants to convert existing Delphi code to C++.
This archive contains the source code of the application, as well as an executable compiled for the Win32 Windows API. These files are distributed under the terms of the GPL licence version 3.0 or later – with my thanks to the Free Software Foundation for reminding me to do so.
Source files compatible with Delphi or Pascal can be translated by drag'n'dropping them onto the application's icon, or by passing them to the application using a command line invocation (error messages are sent to console output).
The source code includes the flex source (delphi_yy.l) and generated code (delphi_yy.cpp), as well as a Perl script (flex_MSVC.pl) that wraps the flex generator and modifies its output to address non-compliances with the C++ standard. The main application is in delphi2cpp.cpp, and uses some string-manipulation utilities found in string_utils.cpp.
Please let me know if you found this tool useful, would like to see a bug fixed, or have a feature request. I do not personally have a need for delphi2cpp anymore, but I welcome any contributions or enhancement.
- 20080615 - published some fixes implemented last year (see change history); explicitly placed this program under a GPL license (as has been requested).
- 20060917 - minor improvements to the output, minor additions, support for a couple of new Delphi.NET features.
- 20060701 - extended the support for translating exception handlers, property members, misc.
- 20050624 - bug fix and improved compatibility with Borland C++.
- 20040410 - fixed newly reported bugs: comment handling, empty derived classes, and support for main program files.
- 20040410 - fixed newly reported bugs: ASM functions, 'forward' in interface, ... + minor output improvements
- 20031013 - fixed handling of #dd character constants, added identifier conversions (PChar, etc)
- 20031011 - first posted this utility for public use.