Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Has anyone attempted to create a PHP to Perl converter?

by taint (Chaplain)
on Nov 13, 2013 at 05:54 UTC ( [id://1062332]=perlmeditation: print w/replies, xml ) Need Help??

Greetings Monks.

I've been pondering this idea for quite some time. But only now had the time to actually pursue such an endevor. I performed a Super Search here at perlmonks. But the bulk of the results were (strangely) Perl to PHP related -- eeewww.

I also pergormed a search on CPAN. But also no joy. So. Has anyone attempted to create a simple converter to translate PHP scripting to Perl equivalent language? Would something like this be a very involved task? To me. It seems as though it wouldn't be terribly difficult. But given I can find no projects,modules, or other related to this. Maybe I'm wrong.

I'd really appreciate your thoughts, and any other information you feel worthwhile.

Thank you for all your consideration

--Chris

P.S. I hope I chose the correct location for this.
It did occur to me that Meditations would also be a possibility. But wasn't sure.

#!/usr/bin/perl -Tw
use Perl::Always or die;
my $perl_version = (5.12.5);
print $perl_version;
  • Comment on Has anyone attempted to create a PHP to Perl converter?

Replies are listed 'Best First'.
Re: Has anyone attempted to create a PHP to Perl converter?
by davido (Cardinal) on Nov 13, 2013 at 06:05 UTC

    I recently took on a small project where I had to rewrite a PHP program in Perl. While I don't want to say an automatic converter is impossible, my own experience was that human involvement was beneficial to the project.

    Compiling C down to machine code works because nobody ever has to look at the machine code again. But in translating from one high level language to another, this is a source-code transition. I assume that the new source code would need to be maintained over time. Just looking at the mess made by automatic HTML/CSS generators (which is less complex than a high level language like Perl) should be warning enough to realize that an automated translation would produce messy, read-only code.

    But who knows... maybe the next reply in this thread will have a perfect solution. ;)


    Dave

      Thanks for your reply.

      I think given my current (Perl) skillset. It would indeed require the "human interaction" you describe. Much of it seems to be alot of (s)print(f) sort of stuff. And much of the syntax even closely mimics Perl. So it really doesn't seem to me, a, "quantum leap", or anything. But, as I stated above; it'll probably take some accomplished Perl RE skills.

      Thanks again, for taking the time to respond.

      --Chris

      #!/usr/bin/perl -Tw
      use Perl::Always or die;
      my $perl_version = (5.12.5);
      print $perl_version;

        It's a little more than a regexp problem. You can't exactly substitute a PHP array with a Perl array, or even a Perl hash, because the PHP array is actually an ordered map. An ordered map has different performance and semantic characteristics from a Perl array or a Perl hash. And that's just where the differences begin.

        A human can look and say, "That algorithm that uses a PHP array can be expressed with a Perl array." Or "This other algorithm needs a Perl hash." Or "This algorithm is going to require a hash, and an array crossreference to maintain order." A dumb tool would be forced to make compromises in every case; it would have to maintain the hash, and an ordered list to emulate an ordered map. This is not to say that an ordered map is more powerful, but that it's a different container. In specific cases, Perl could mimic enough of its behavior using an array, and in others, enough of its behavior using a hash. But in a general case, both would have to be used together. Programming for the general case, then, would be inefficient for many specific uses. A human can make the distinction, or even rewrite the algorithm to play to Perl's strengths instead of PHP's strengths.

        Once that problem is solved, there will be many more paradigm mismatches, each one that could be gracefully handled by a human, but where a machine would need to understand the underlying purpose of code segments, which is probably beyond the capabilities of any regexp engine.


        Dave

      This makes me think that the PHP CPAN module is a good thing in this regard, and that frameworks for transition may be better than code converters.

      In general rewriting apps in another language means rethinking everything because there are all sorts of things that just don't quite match between apps. Something to ease the transition might be very good. So for example, despite my skepticism I think the following could be helpful

      • Boilerplate converters. Take a PHP object definition and turn it into a basic Moo or Moose definition. Don't port the methods, just the boilerplate.
      • Bridging type classes. The ability to have a PHP Array inside your Perl code may ease the transition quite a bit.
      • Web application frameworks written with conversion in mind.

      These strike me as both easier and less work than a full-blown code converter but also provide all the basic infrastructure to allow a human to conversion relatively quickly and easily...

Re: Has anyone attempted to create a PHP to Perl converter?
by tobyink (Canon) on Nov 13, 2013 at 09:47 UTC

    It's certainly doable. If I had more tuits, it would be something I'd consider doing. I'd start with using token_get_all to build a stream of PHP tokens (in PHP!), build up an abstract syntax tree and then compile that down to Perl.

    In fact, somebody's already done the hard part.

    UPDATE: OK, I've put together a very quick proof of concept. It can successfully translate <?php echo "Hello world"; ?> to print("Hello world"); (here's the relevant test case). Currently the AST only handles a very tiny subset of PHP (just enough to pass that test!) - there's a long list of language constructs that still need to be handled. Once that's been done, implementations are needed for PHP's built-in functions. Contributions welcome.

    use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name
      > a stream of PHP tokens (in PHP!), build up an abstract syntax tree and then compile that down to Perl.

      You can't handle PHP's 'eval($string)' if you parse the syntax in PHP.

      > In fact, somebody's already done the hard part.

      Nope, the hard part of translating dynamic languages (apart eval) is the realization of implicit type coercions in all edge cases.

      This can get so complicated that you might need to treat every single variable / data structure as a tied object.

      After estimating the speed of such programs most similar projects crumble away.

      edit

      You effectively need a nifty JIT compiling magic which notices that weird edge cases aren't touched and resorts to efficient code.

      Cheers Rolf

      ( addicted to the Perl Programming Language)

      But with that approach you could only deal with pure PHP.

      Do you see a way to deal with PHP-extensions written in C?

      I don't know much about either PHP nor XS but I would assume that without at least some database-module etc (probably written in C) such a port would not have much practical value and making a PHP-extension callable from Perl must be difficult or am I wrong?

        Most PHP extensions either dump a bunch of functions into the global namespace, or define a few classes.

        So to implement a PHP extension, you'd simply dump a few Perl or XS functions into the "PHP::GLOBAL" namespace, or define a few Perl classes

        use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name
      Holy crap! Most impressive. Well done tobyink.

      These seem like ripe candidates for CUFP, or would that be Cool uses for PHP?

      Thank you very for taking the time. These are great.

      --Chris

      #!/usr/bin/perl -Tw
      use Perl::Always or die;
      my $perl_version = (5.12.5);
      print $perl_version;
Re: Has anyone attempted to create a PHP to Perl converter?
by boftx (Deacon) on Nov 13, 2013 at 06:01 UTC

    HRRRRUMMMMPPHHHHH! And people thought my idea of a quest to back-port Moose to Perl 4 was masochistic. :)

    It helps to remember that the primary goal is to drain the swamp even when you are hip-deep in alligators.
      LOL

      I see it as sort of regex puzzle. I can almost complete it in my head with sed. But personal evaluation tells me my Perl RE's fall far short of the mark. I'll have to push it off for a day when my Perl RE's can match my current sed skills. But by then. Who knows? :)

      Thanks for taking the time to respond, and thanks for your honesty. :)

      --Chris

      #!/usr/bin/perl -Tw
      use Perl::Always or die;
      my $perl_version = (5.12.5);
      print $perl_version;

        Don't use regexp's for the same reason that you shouldn't use them for parsing HTML.

        Parse::RecDescent would be a better tool, I think. You might be able to handle the basic syntax that way but what about folks using PDO? It looks superficially like DBI, but... So I doubt you can do that much other than handling very simple cases.

Re: Has anyone attempted to create a PHP to Perl converter?
by Anonymous Monk on Nov 13, 2013 at 15:02 UTC

    I think that it would wind up being like that legendary attempt to write an English-to-Russian translator.   The test was to feed an English sentence in, translate it, then translate it back, and see what you get.   At the time, so the legend goes, this is what happened:

    • Input:   The spirit is willing, but the flesh is weak.
    • Output:   The wine is acceptable, but the meat has spoiled.

    (Google Translate has gotten a lot better since then.)

    There is likely to be too much contextual, semantic information surrounding a real-world PHP program, especially an older one whose logic is interspersed within an HTML page, to make the result of “automatic” translation attempt pragmatically useful.   A small piece, say an editor macro to translate the format of, say, a hash from one language to the other, might be slightly helpful to some.

      My version of that legend has the following phrases:
      • Input: Out of sight, out of mind
      • Output: A blind idiot

      CountZero

      A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

      My blog: Imperial Deltronics
      I'm not so sure.

      As I contemplate it. It could be done in phases. Using SED, I would bite off,gulp,slurp chunks of tags (language constructs) I recognize, and separate them into categorized groups -- functions,(s)print(f)'s,...

      Then, I could translate the actual Language bits, ignoring the other stuff as pretty much being equivalent(s) in Perl. Then (somehow) reconstruct it all -- which is another puzzle in, and of itself.

      This is, of course, pretty simplified. But in my mind, seems a reasonable path.

      --Chris

      #!/usr/bin/perl -Tw
      use Perl::Always or die;
      my $perl_version = (5.12.5);
      print $perl_version;

        Why would you want to use sed when the Perl regexes are far far far more powerful?

        If you feel limited in your command of Perl regexes, I really think that the first thing you want to do is to really start mastering the Perl regexes. Perhaps reading Mastering Regular Expressions, by Jeff Friedl. BTW, this book also shows some of the limitations of regexes, and you project will necessarily meet these limitations. I think that most people on this forum agree that you should not use regexes for parsing HTML or XML, using regexes for parsing PHP would be even worse.

        Although regexes might certainly do part of the work, I doubt that you can go anywhere without using a real parser.

        One final note on the English-Russian translation anecdote, I personally tried several translating software packages over the years (I was a translator before I became a CS professional) between 1988 and 1996. The results were really bad. On the first one I tried, i gave the following sentence: "Time flies like an arrow". The French translation I obtained was: "Les mouches du temps aiment une flèche", which can be translated back into English as follows: "The flies (the insect) of time love an arrow". I tried other packages at the time, the results were possibly not as funny, but not much better. A lot of improvements have been made since, but the basic problem of implicit context understanding is still there.

        There’s no doubt, of course, that valid PHP can be parsed, for syntax checking and so-on, and that once the source has been reduced to an abstract-syntax tree (AST) form, some of those AST constructs could be expanded into Perl.   The languages are in many ways very similar.   You might be able to do such a thing, say, in an editor-macro for a very smart editor.

        If you look beyond the superficial, though, you start getting into some much thornier problems.   For example, in the PHP system, “everything is compiled-in,” and is called by means of (hundreds of ...) functions.   Database access, for example, is implemented in that way.   In the Perl system, per contra, we have DBI.   Now you are going to have to develop a way for the translated Perl code to continue doing things “the PHP way.”   Suddenly, your problem has become quite a bit more complicated, and pretty soon “diminishing returns” are going to be a factor.   And then, there are the ideas that simply do not exist at all in Perl, such as the intermingling of HTML and PHP in a file, which was a founding concept of PHP.

      I am not so sure. The thing is that natural languages aren't really that analogous to programming languages here, because they aren't that ambiguous. Natural languages are defined by use, not by specification. Programming languages are defined by specification and not by use. Of course that specification is written in a language defined by use, but since you have only one canonical implementation of PHP and only one of Perl, you might be able to say that the implementation is authoritative. Because in the end, the basic structures are identical, you shouldn't have problems translating programming languages that you do with natural languages.

      But that leads to a big problem in that to be perfect, a perfect converter would have to translate bug for bug but that's not very feasible, but you could still have something which manages those to an extent. You could have wrapper classes for ordered maps and translate PHP arrays to that. However very likely what you would have to end up with is a program that converts from PHP into a Perl framework built for the conversion.

      Now where I think your point holds some real weight is in the management of code comments. What does the program do with those? Just ignore them? Just include them? Both of those seem dangerous, and you can't translate them for the reason you mentioned.

Re: Has anyone attempted to create a PHP to Perl converter?
by Anonymous Monk on Nov 13, 2013 at 08:09 UTC
    Sure, here it is PHP - embedded PHP interpreter
Re: Has anyone attempted to create a PHP to Perl converter?
by Khen1950fx (Canon) on Nov 13, 2013 at 13:56 UTC
    Have you tried PHP::Include?
    #!/usr/bin/perl -l use strict; use warnings; use PHP::Include ( DEBUG => 1 ); include_php_vars( '/path/to/deepstructure.php' ); my $file = '/path/to/deepstructure.php'; print $file;
    Here's the deepstructure.php:
    <?php $structure = array( 'names' => array( 'a' => array( 'alberto', 'antonio'), 'b' => array( 'burro', 'brain')), 'ages' => array( 10, 20, 30, 40), ); $x = 42; ?>
      my $file = '/path/to/deepstructure.php'; print $file;

      Why have you done this? It literally does nothing to help. Did you actually try this with some real PHP code and not just a simple set of variable declarations? I don't think you actually know what the code you've posted does, your simply falling back to the DEBUG option to dump the perl the module generates to STDERR.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://1062332]
Approved by Athanasius
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (6)
As of 2024-04-19 08:21 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found