Modul zum Kompilieren von Perl-Code

Modul zum Kompilieren von Perl-Code

am 24.02.2007 22:43:29 von Hendrik Schnepel

Hallo,

ich suche ein Modul, mit dem ich innerhalb eines Perl-Programms anderen
Perl-Code (in einem string) kompilieren oder in irgendeiner Form
syntaktisch pruefen kann, ohne den Code auszufuehren.

Unter den B::* Modulen habe ich nicht das richtige gefunden, oder nicht
gesehen, wie man es innerhalb eines Programms (also nicht ueber einen
Kommandozeilenaufruf) verwenden kann. Einen Aufruf von perl -c moechte ich
vermeiden, da ich dann entweder eine temporaere Datei benoetige oder mich
mit den pipe-Eigenheiten verschiedener Systeme rumschlagen muss (schon
probiert).

Gibt's da was?

Viele Gruesse,
Hendrik

Re: Modul zum Kompilieren von Perl-Code

am 26.02.2007 12:41:04 von Ingo Menger

On Feb 24, 10:43 pm, Hendrik Schnepel
wrote:
> Hallo,
>
> ich suche ein Modul, mit dem ich innerhalb eines Perl-Programms anderen
> Perl-Code (in einem string) kompilieren oder in irgendeiner Form
> syntaktisch pruefen kann, ohne den Code auszufuehren.
>
> Unter den B::* Modulen habe ich nicht das richtige gefunden, oder nicht
> gesehen, wie man es innerhalb eines Programms (also nicht ueber einen
> Kommandozeilenaufruf) verwenden kann. Einen Aufruf von perl -c moechte ich
> vermeiden, da ich dann entweder eine temporaere Datei benoetige oder mich
> mit den pipe-Eigenheiten verschiedener Systeme rumschlagen muss (schon
> probiert).
>
> Gibt's da was?

Nicht generell.
Eine begrenzte Möglichkeit wäre sowas wie:

my $perlcode =3D <<'EOF';
unlink("dissertation.tex");
this is garbage
EOF

my $ok =3D eval "sub { " . $perlcode . "}";

Die Einfassung in sub { } verhindert, daß der Code ausgeführt wird.
Schwierig wirds, wenn der Code selbst wieder subs oder BEGIN/END-
Blöcke enthält.
Beachte, daß der $perlcode hier Deine package Variablen und lexicals
"sieht". Das Problem mit den package-Variablen könnte man durch ein
entsprechendes package-Statement noch umgehen, das mit den lexicals
aber eher nicht.

Re: Modul zum Kompilieren von Perl-Code

am 26.02.2007 18:10:04 von Ferry Bolhar

Hendrik Schnepel:

> ich suche ein Modul, mit dem ich innerhalb eines Perl-Programms anderen
> Perl-Code (in einem string) kompilieren oder in irgendeiner Form
> syntaktisch pruefen kann, ohne den Code auszufuehren.

Auf die Schnelle fällt mir das ein: wenn "$code" deinen Perlcode enthält,
dann probiere es mal mit:

my $testcode = <<"EOF";
package MyTest;
defined my $MyTest && do {
$code
}
EOF
eval "$testcode";
print "Compilation failed!\n" if $@;

Der Inhalt des do-Blocks wird in einem eigenen Package kompiliert,
sodass es zu keinen Kollisionen mit anderen globalen Variablen, die in
$code aufscheinen, kommt. Ausgeführt wird er aber nicht, da $MyTest
nie definiert ist. Aber Vorsicht: "use"-Direktiven und BEGIN/CHECK
Blöcke in $code laufen natürlich dennoch los, denn sie sind ja Teil
der Kompilierphase.

LG; Ferry

--
Ing Ferry Bolhar
Magistrat der Stadt Wien - MA 14
A-1010 Wien
E-Mail: bol@adv.magwien.gv.at

Re: Modul zum Kompilieren von Perl-Code

am 26.02.2007 21:35:53 von Hendrik Schnepel

> my $testcode = <<"EOF";
> package MyTest;
> defined my $MyTest && do {
> $code
> }
> EOF
> eval "$testcode";

Die Idee ist ganz gut, aber es laesst sich eben doch umgehen. Sei es
zufaellig (wenn auch halbwegs unwahrscheinlich), oder absichtlich, wenn
man weiss, welche Mechanik dahinter steckt. Das wuerde ich gern vermeiden.

Gruss,
Hendrik

Re: Modul zum Kompilieren von Perl-Code

am 26.02.2007 22:11:27 von Frank Seitz

Hendrik Schnepel wrote:
>>my $testcode = <<"EOF";
>>package MyTest;
>>defined my $MyTest && do {
>> $code
>>}
>>EOF
>>eval "$testcode";
>
> Die Idee ist ganz gut, aber es laesst sich eben doch umgehen. Sei es
> zufaellig (wenn auch halbwegs unwahrscheinlich), oder absichtlich, wenn
> man weiss, welche Mechanik dahinter steckt. Das wuerde ich gern vermeiden.

Wie? Was? Umgehen?
Und perl -c kommt nicht infrage, weil Du dann eine
Tempdatei schreiben müsstest?
Du hast seltsame Anforderungen.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: Modul zum Kompilieren von Perl-Code

am 26.02.2007 22:13:27 von Frank Wiegand

Hendrik Schnepel schrieb:
> ich suche ein Modul, mit dem ich innerhalb eines Perl-Programms anderen
> Perl-Code (in einem string) kompilieren

Kompilieren ist nicht nur syntaktische Überprüfung (bei perl).

> oder in irgendeiner Form syntaktisch pruefen kann, ohne den Code
auszufuehren.

PPI?

> Gibt's da was?

Sag doch, wofür du es brauchst, dann stochern wir nicht so im Dunkeln.


Frank

Re: Modul zum Kompilieren von Perl-Code

am 26.02.2007 22:24:28 von Hendrik Schnepel

This message is in MIME format. The first part should be readable text,
while the remaining parts are likely unreadable without MIME-aware tools.

---559023410-851401618-1172525068=:19415
Content-Type: TEXT/PLAIN; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 8BIT

> Wie? Was? Umgehen?

Zum Beispiel kann ich

}; print "foo"; do {

als Code eingeben, und es wird das print ausgefuehrt und 'foo' ausgegeben.

> Und perl -c kommt nicht infrage, weil Du dann eine
> Tempdatei schreiben müsstest?

Wie sonst? perl -c ist das, was ich braeuchte, aber wenn ich das ueber
pipes laufen lasse (open3) bekomme ich das Eingabe-handle unter Windows
nicht geschlossen und erhalte somit auch kein Ergebnis.

> Du hast seltsame Anforderungen.

Naja ;)
---559023410-851401618-1172525068=:19415--

Re: Modul zum Kompilieren von Perl-Code

am 26.02.2007 22:30:25 von Hendrik Schnepel

This message is in MIME format. The first part should be readable text,
while the remaining parts are likely unreadable without MIME-aware tools.

---559023410-851401618-1172525425=:19447
Content-Type: TEXT/PLAIN; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 8BIT

> Kompilieren ist nicht nur syntaktische Überprüfung (bei perl).

Ja, ok.

>> oder in irgendeiner Form syntaktisch pruefen kann, ohne den Code
> auszufuehren.
>
> PPI?

Sieht interessant aus, ich werde mal gucken, wie zuverlaessig das
ist und es mal ausprobieren. Danke.

> Sag doch, wofür du es brauchst, dann stochern wir nicht so im Dunkeln.

Es geht um eine Schnittstelle, ueber die (vertrauenswuerdige) Benutzer
plugin-artige Funktionen einfuegen koennen. Die Syntaxpruefung soll eine
Komfortfunktion sein. Die Eingabe wird dann in einen generierten sub
blabla { ... } eingefuegt.

Gruss,
Hendrik

---559023410-851401618-1172525425=:19447--

Re: Modul zum Kompilieren von Perl-Code

am 26.02.2007 22:58:10 von Frank Seitz

Hendrik Schnepel wrote:
>>Wie? Was? Umgehen?
>
> Zum Beispiel kann ich
>
> }; print "foo"; do {
>
> als Code eingeben, und es wird das print ausgefuehrt und 'foo' ausgegeben.

Ich meinte, von Sicherheitsanforderungen hattest Du nichts gesagt.

>>Und perl -c kommt nicht infrage, weil Du dann eine
>>Tempdatei schreiben müsstest?
>
> Wie sonst? perl -c ist das, was ich braeuchte, aber wenn ich das ueber
> pipes laufen lasse (open3) bekomme ich das Eingabe-handle unter Windows
> nicht geschlossen und erhalte somit auch kein Ergebnis.

Schreib halt eine Tempdatei und lösche sie anschließend weg.
Wo ist das Problem?

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: Modul zum Kompilieren von Perl-Code

am 26.02.2007 23:42:03 von Hendrik Schnepel

This message is in MIME format. The first part should be readable text,
while the remaining parts are likely unreadable without MIME-aware tools.

---559023410-851401618-1172529723=:19848
Content-Type: TEXT/PLAIN; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 8BIT

>> als Code eingeben, und es wird das print ausgefuehrt und 'foo' ausgegeben.
>
> Ich meinte, von Sicherheitsanforderungen hattest Du nichts gesagt.

Das ist keine Sicherheitsanforderung, sondern eine Anforderung an die
prinzipielle Aufgabe. (Syntaxueberpruefung, ohne Ausfuehrung.)

> Schreib halt eine Tempdatei und lösche sie anschließend weg.
> Wo ist das Problem?

Erscheint mir unelegant :) Aber machbar ist es natuerlich, ja.
---559023410-851401618-1172529723=:19848--

Re: Modul zum Kompilieren von Perl-Code

am 27.02.2007 09:16:37 von Ferry Bolhar

Hendrik Schnepel:

>> Ich meinte, von Sicherheitsanforderungen hattest Du nichts gesagt.
>
> Das ist keine Sicherheitsanforderung, sondern eine Anforderung an die
> prinzipielle Aufgabe. (Syntaxueberpruefung, ohne Ausfuehrung.)

Diese Aufgabe ist durch meinen Code ja schon gelöst. Und ganz "ohne
Ausführung" wird in Perl nicht immer möglich sein, weil zur Syntax-
prüfung manchmal vorher Code ausgeführt werden muss, um sie richtig
bewerkstelligen zu können (dafür gibt's ja eben BEGIN Blöcke).

Und irgendetwas mit Sicherheit dürfte deine Anforderung schon
zu tun haben, sonst hättest du nicht geschrieben:

> Die Idee ist ganz gut, aber es laesst sich eben doch umgehen. Sei es
> zufaellig (wenn auch halbwegs unwahrscheinlich), oder absichtlich,
> wenn man weiss, welche Mechanik dahinter steckt.

Wenn du also Bedenken hast, dass irgendjemand etwas "umgehen"
kann (wobei es interessant wäre, zu wissen was du damit meinst),
dürften schon auch Sicherheitsgedanken im Spiel sein, oder?

LG, Ferry

--
Ing Ferry Bolhar
Magistrat der Stadt Wien - MA 14
A-1010 Wien
E-Mail: bol@adv.magwien.gv.at

Re: Modul zum Kompilieren von Perl-Code

am 27.02.2007 12:03:44 von Hendrik Schnepel

This message is in MIME format. The first part should be readable text,
while the remaining parts are likely unreadable without MIME-aware tools.

---559023410-851401618-1172574224=:19482
Content-Type: TEXT/PLAIN; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 8BIT

> Diese Aufgabe ist durch meinen Code ja schon gelöst. Und ganz "ohne
> Ausführung" wird in Perl nicht immer möglich sein, weil zur Syntax-
> prüfung manchmal vorher Code ausgeführt werden muss, um sie richtig
> bewerkstelligen zu können (dafür gibt's ja eben BEGIN Blöcke).

Na gut, das ist wahr, auch perl -c fuehrt diese Bloecke anscheinend aus.
Kann mir jemand zum Abschluss noch ein einfaches Beispiel geben, warum das
fuer die *Syntax*pruefung notwendig ist?

> Wenn du also Bedenken hast, dass irgendjemand etwas "umgehen"
> kann (wobei es interessant wäre, zu wissen was du damit meinst),
> dürften schon auch Sicherheitsgedanken im Spiel sein, oder?

Ich hatte nicht an die BEGIN Bloecke gedacht und meinte daher mit
"umgehen" ein Konstrukt, das den do Block schliesst und danach Code
einfuegt, der ausgefuehrt wird.

Wie auch immer wollte ich gern vermeiden, dass Code ausgefuehrt wird.
Vielleicht moechte ich eine Funktion ueberpruefen, die bei Ausfuehrung
irgendetwas tut, was man nun gar nicht (beim Pruefen) haben wollte, zB
Veraenderung von Dateien oder Datenbank.

Naja Leute, wenns nicht geht, gehts halt nicht... ;) Danke fuer die
Vorschlaege und Hinweise.

Gruesse,
Hendrik

---559023410-851401618-1172574224=:19482--

Re: Modul zum Kompilieren von Perl-Code

am 27.02.2007 12:30:45 von rs

Hendrik Schnepel wrote:

> Na gut, das ist wahr, auch perl -c fuehrt diese Bloecke anscheinend aus.
> Kann mir jemand zum Abschluss noch ein einfaches Beispiel geben, warum
> das fuer die *Syntax*pruefung notwendig ist?

Ganz einfach:

use Carp qw( croak );
croak "Foo";

Woher soll perl wissen, dass es 'croak' gibt, wenn es nicht die use
Zeile ausführt und Carp->import() aufruft das 'croak' überhaupt erst im
lokalen Namensraum installiert?

> Ich hatte nicht an die BEGIN Bloecke gedacht und meinte daher mit
> "umgehen" ein Konstrukt, das den do Block schliesst und danach Code
> einfuegt, der ausgefuehrt wird.
>
> Wie auch immer wollte ich gern vermeiden, dass Code ausgefuehrt wird.
> Vielleicht moechte ich eine Funktion ueberpruefen, die bei Ausfuehrung
> irgendetwas tut, was man nun gar nicht (beim Pruefen) haben wollte, zB
> Veraenderung von Dateien oder Datenbank.

Ob der Syntax korrekt ist oder nicht, kann nunmal eben zur Laufzeit
beeinflusst werden.

Gruß,
Robert

Re: Modul zum Kompilieren von Perl-Code

am 27.02.2007 13:25:03 von Daniel Fischer

Hendrik Schnepel!

> Na gut, das ist wahr, auch perl -c fuehrt diese Bloecke anscheinend aus.
> Kann mir jemand zum Abschluss noch ein einfaches Beispiel geben, warum das
> fuer die *Syntax*pruefung notwendig ist?

use Acme::Pony;
bU
fFybuf
fybuFFYbu
FfyBUFfYbu
FfYBufFYBu
FFybuFfY
BUffybufFyb uFfy
bUffybuFfyBuFfYbuFFybUfFy
BU fFybufFybufFYBuFfyBUFfYB
ufF ybuFfyBUfFYBuffYbUffybu
FfY buffYBUFFyBuFFY
BUf FyBuFfybUf
fYB UffYbufFy
bu Ff YB UFFy
Bu FF YBU
fF yX
XXX XXX


Gruß
Daniel

Re: Modul zum Kompilieren von Perl-Code

am 27.02.2007 13:34:03 von Frank Wiegand

Daniel Fischer schrieb:

>> Na gut, das ist wahr, auch perl -c fuehrt diese Bloecke anscheinend aus.
>> Kann mir jemand zum Abschluss noch ein einfaches Beispiel geben, warum das
>> fuer die *Syntax*pruefung notwendig ist?
>
> use Acme::Pony;
[...]

Wirklich?

fw@doro:~/tmp$ cat test.pl
bU
fFybuf
fybuFFYbu
FfyBUFfYbu
FfYBufFYBu
FFybuFfY
BUffybufFyb uFfy
bUffybuFfyBuFfYbuFFybUfFy
BU fFybufFybufFYBuFfyBUFfYB
ufF ybuFfyBUfFYBuffYbUffybu
FfY buffYBUFFyBuFFY
BUf FyBuFfybUf
fYB UffYbufFy
bu Ff YB UFFy
Bu FF YBU
fF yX
XXX XXX
fw@doro:~/tmp$ perl -c test.pl
test.pl syntax OK


Frank

Re: Modul zum Kompilieren von Perl-Code

am 27.02.2007 13:39:30 von Daniel Fischer

Frank Wiegand!

> fw@doro:~/tmp$ perl -c test.pl
> test.pl syntax OK

das liefert aber auch false positives:

df@pippilotta ~/temp :( perl -c bla.pl
bla.pl syntax OK

df@pippilotta ~/temp :) perl unpony.pl < bla.pl | perl -c
Unmatched right curly bracket at - line 2, at end of line
syntax error at - line 2, near "}"
- had compilation errors.


Gruß
Daniel

Re: Modul zum Kompilieren von Perl-Code

am 27.02.2007 16:00:08 von Hendrik Schnepel

Ich finde die Beispiele bis jetzt nicht ueberzeugend. Nur weil ggf. nicht
definierte Prozeduren aufgerufen werden, ist nicht die Syntax falsch.

> das liefert aber auch false positives:
>
> df@pippilotta ~/temp :( perl -c bla.pl
> bla.pl syntax OK

Warum ist das syntaktisch gesehen ein false positive? Mit den
entsprechenden packages und subs waere bla.pl ausfuehrbar.

Also bis jetzt klang es doch so, als waere eine Syntaxueberpruefung ohne
Ausfuehrung im Allgemeinen nicht fuer alle Programme moeglich. Ein
Beispiel zur Begruendung waere dann ja wohl ein syntaktisch falsches(!)
Programm, das jedoch durch Laufzeiteffekte doch funktioniert.

Gruss,
Hendrik

Re: Modul zum Kompilieren von Perl-Code

am 27.02.2007 16:31:45 von Frank Seitz

Hendrik Schnepel wrote:

>>df@pippilotta ~/temp :( perl -c bla.pl
>>bla.pl syntax OK
>
> Warum ist das syntaktisch gesehen ein false positive? Mit den
> entsprechenden packages und subs waere bla.pl ausfuehrbar.

Was bla.pl sein soll, hat sich mir nicht erschlossen, aber egal.

> Also bis jetzt klang es doch so, als waere eine Syntaxueberpruefung ohne
> Ausfuehrung im Allgemeinen nicht fuer alle Programme moeglich. Ein
> Beispiel zur Begruendung waere dann ja wohl ein syntaktisch falsches(!)
> Programm, das jedoch durch Laufzeiteffekte doch funktioniert.

Das Beispiel mit Carp/craok war so eins. Wenn das "use" nicht
ausgeführt würde, wäre das Programm syntaktisch nicht korrekt.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: Modul zum Kompilieren von Perl-Code

am 27.02.2007 16:50:34 von Hendrik Schnepel

This message is in MIME format. The first part should be readable text,
while the remaining parts are likely unreadable without MIME-aware tools.

---559023410-1804928587-1172591434=:25203
Content-Type: TEXT/PLAIN; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 8BIT

> Das Beispiel mit Carp/craok war so eins. Wenn das "use" nicht
> ausgeführt würde, wäre das Programm syntaktisch nicht korrekt.

Ok.. :)
---559023410-1804928587-1172591434=:25203--

Re: Modul zum Kompilieren von Perl-Code

am 27.02.2007 17:05:36 von hjp-usenet2

On 2007-02-27 15:00, Hendrik Schnepel wrote:
> Ich finde die Beispiele bis jetzt nicht ueberzeugend. Nur weil ggf. nicht
> definierte Prozeduren aufgerufen werden, ist nicht die Syntax falsch.
>
>> das liefert aber auch false positives:
>>
>> df@pippilotta ~/temp :( perl -c bla.pl
>> bla.pl syntax OK
>
> Warum ist das syntaktisch gesehen ein false positive? Mit den
> entsprechenden packages und subs waere bla.pl ausfuehrbar.
>
> Also bis jetzt klang es doch so, als waere eine Syntaxueberpruefung ohne
> Ausfuehrung im Allgemeinen nicht fuer alle Programme moeglich. Ein
> Beispiel zur Begruendung waere dann ja wohl ein syntaktisch falsches(!)
> Programm, das jedoch durch Laufzeiteffekte doch funktioniert.

Das ist ein Widerspruch in sich. Wenn die Syntax nicht korrekt ist, kann
das Programm nicht funktionieren. Es gibt aber gar keine statische
Perl-Syntax - die Syntax kann von vom Programm selbst geändert werden.
Ein einfaches Beispiel hat Robert 'phaylon' Sedlacek schon in
<45e41665$0$20293$9b4e6d93@newsspool3.arcor-online.net> gebracht:

croak "Test";
ist ein Syntax-Fehler:
String found where operator expected at foo line 3, near "croak "Test""
aber
use Carp 'croak';
croak "Test";
funktioniert, weil das "use Carp" Code ausführt, der im aktuellen
Package eine Funktion "croak" mit einem Parameter bekanntgibt, wodurch
der Code syntaktisch richtig wird.

Das sieht auf den ersten Blick nicht anders aus als

#include "foo.h"

int foo (int bar) {
return (gazonk)(bar);
}

was auch, jenachdem was in foo.h steht, unterschiedlich geparst werden
kann (wenn gazonk eine Funktion ist, ist es ein Funktionsaufruf, wenn
gazonk ein Typ ist, ist es ein Typecast, sonst ist es wahrscheinlich ein
Syntaxfehler).

Es ist aber trotzdem was anderes, weil ein C-Compiler eine statische
Analyse des Programmtexts vornimmt, während der Perl-Compiler
prinzipiell Teile davon (alles in BEGIN-Blöcken) ausführt - im Effekt
wird der compilierte Source-Code Teil des Compilers.

hp


--
_ | Peter J. Holzer | Es ist ganz einfach ihn zu verstehen, wenn
|_|_) | Sysadmin WSR | man nur alle wichtigen Worte im Satz durch
| | | hjp@hjp.at | andere ersetzt.
__/ | http://www.hjp.at/ | -- Nils Ketelsen in danr

Re: Modul zum Kompilieren von Perl-Code

am 27.02.2007 17:10:20 von Ferry Bolhar

Hendrik Schnepel:

> Na gut, das ist wahr, auch perl -c fuehrt diese Bloecke anscheinend aus.

Natürlich. Aus perlrun:

-c causes Perl to check the syntax of the program and then exit with-
out executing it. Actually, it will execute "BEGIN", "CHECK", and
"use" blocks, because these are considered as occurring outside
the execution of your program. "INIT" and "END" blocks, however,
will be skipped.

> Kann mir jemand zum Abschluss noch ein einfaches Beispiel geben, warum das
> fuer die *Syntax*pruefung notwendig ist?

Ein Ausdruck wie

hugo;

ist so, wie er hier steht, nicht erlaubt. Wurde er vorher aber - durch
Perl Code! - als Funktion deklariert oder aus einem andern Package
importiert, ist es ein Funktionsaufruf und somit ist er erlaubt. Eine
Deklaration wie

our $var:MyAttrib;

ist nur erlaubt, wenn ein Modul geladen wurde, das einen entsprechenden
Attributhandler bereitstellt, der dieses Attribut verarbeiten kann (was
ebenfalls in einem BEGIN Block passiert).

Wenn du dir einmal die B-Module anschaust (Backend-Compiler),
wirst du dich wundern, was da alles an Code laufen kann, selbst
wenn -c angegeben ist! ;-))

LG, Ferry

--
Ing Ferry Bolhar
Magistrat der Stadt Wien - MA 14
A-1010 Wien
E-Mail: bol@adv.magwien.gv.at