Frage zu PHP-Interpreter



  • Hey,

    ich habe mal eine Frage zum PHP-Interpreter (oder vergleichbare): Wie hat man es geschafft, dass man den Code in verschiedene Stücke aufteilen kann?

    <?php
    if (...) {
    ?>
    
    Hier steht HTML.
    
    <?
    } // Hier geht PHP weiter.
    ?>
    

    Ich hab schon mal eine kleine Sprache programmiert, aber ich bin ratlos, wie man es realisiert, dass der Code unterbrochen werden kann und trotzdem das was dazwischen steht (HTML) nicht verloren geht.



  • Das, was zwischen <? und ?> steht, wird ausgeführt und der Rest wird vom Interpreter eben ignoriert 😕



  • Ja, das ist mir klar. Es geht um die Programmierung eines solchen Interpreters. Ich weiß nicht, wie ich das in Quellcode am besten umsetze, dass die in <?php und ?> eingeschlossene Codestelle beim Parsen gefunden wird. Liest der Interpreter dannn solange weiter bis wieder eine Codestelle kommt? Was macht er mit den Daten, die zwischen der Codestelle stehen, etc.

    Findet eventuells chon im Voraus eine Analyse statt, wo sich Codeteile befinden?

    Und ignoriert kann es eben nicht werden, da der HTML-Code ganz normal ausgegeben wird (Sofern eine If-Abfrage dies nicht ausschließt).



  • Dieser Thread wurde von Moderator/in pumuckl aus dem Forum C++ in das Forum Rund um die Programmierung verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • alles, was nicht innerhalb der Tags steht, wird einfach als normale Ausgabe gewertet. So hat der Parser am Ende eine reine PHP-Datei

    Dein Beispiel sieht dann wahrscheinlich so aus:

    <?php
    if (...) {
    echo ''."\n";
    echo ''."\n";
    echo 'Hier steht HTML.'."\n";
    echo ''."\n";
    } // Hier geht PHP weiter.
    ?>
    


  • Wo ist der Unterschied zwischen einem Compiler, der alles ignoriert, was nicht zwischen <?php ?> steht, und einem, der alles ignoriert, was zwischen /* und */ steht? Denk mal drueber nach, du wirst sehn, da gibts keinen Unterschied 😉



  • Blue-Tiger schrieb:

    Wo ist der Unterschied zwischen einem Compiler, der alles ignoriert, was nicht zwischen <?php ?> steht, und einem, der alles ignoriert, was zwischen /* und */ steht? Denk mal drueber nach, du wirst sehn, da gibts keinen Unterschied 😉

    Der Interpreter ignoriert es aber nicht in dem Sinne. Du kannst das nicht mit einem Kommentar gleichsetzen (Kommentare werden tatsächlich ignoriert). Das was zwutz meint scheint mir aber der richtige Weg zu sein. Mir ist eine ähnliche Idee auch noch eingefallen. Ich werd das jetzt so probieren, danke.



  • Dieser Thread wurde von Moderator/in rüdiger aus dem Forum Rund um die Programmierung in das Forum Webzeugs verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • PHP benutzt keinen Compiler, und er generiert afaik auch keinen Zwischencode. Das einfachte wäre es, alles zwischen <?php und ?> einfach direkt auszugeben.



  • ........ schrieb:

    Der Interpreter ignoriert es aber nicht in dem Sinne. Du kannst das nicht mit einem Kommentar gleichsetzen (Kommentare werden tatsächlich ignoriert).

    Natürlich kann man es gleichsetzen. Die Erkennung ist dieselbe, und ob nun der Code verworfen oder ausgegeben wird, ist eine einfache if-Abfrage : o )



  • So wie du es schilderst ist es aber nicht. Ich hab mir das inzwischen ganz genau angesehen.

    Beispiel:

    Blub <?php /* Wird ignoriert */ ?> Bla <?php ?>
    

    T_INLINE_HTML "Blub "
    T_OPEN_TAG
    T_CLOSE_TAG
    T_INLINE_HTML " Bla "
    T_OPEN_TAG
    T_CLOSE_TAG

    Kommentare und Codetags erfahren eine unterschiedliche Behandlung (=lassen sich eben nicht gleichsetzen).

    Das Problem konnte ich übrigens lösen. Ich hab den Scanner so umgesetzt, wie es in PHP auch realisiert wurde: Alles was außerhalb der Codetags steht wird in einem speziellen Token zusammengefasst.

    The-Kenny schrieb:

    PHP benutzt keinen Compiler, und er generiert afaik auch keinen Zwischencode. Das einfachte wäre es, alles zwischen <?php und ?> einfach direkt auszugeben.

    Das ist korrekt. PHP wird interpretiert. Außer man nutzt die Zend-Engine. In dem Fall wird es tatsächlich zu einem Zwischencode kompiliert, um die Ausführungsgeschwindigkeit zu verbessern.

    Ich frage mich warum ihr das immer ausgeben wollt? Schlussendlich muss der eigentliche Code doch noch ausgeführt werden. Eventuell ist das hier das Missverständnis.

    Aber wie gesagt, ich konnte das Problem lösen. Danke für die Hilfe 🙂


  • Mod

    ........ schrieb:

    Außer man nutzt die Zend-Engine. In dem Fall wird es tatsächlich zu einem Zwischencode kompiliert, um die Ausführungsgeschwindigkeit zu verbessern.

    Die Zend Engine ist bestandteil von PHP.
    Was du meinst sind Opcode Caches. Die Zend Engine erstellt naemlich immer PHP-Opcode, also kompiliert den PHP Code. Ein Opcode Cache wird nun verwendet um diesen generierten Code zu speichern um beim naechsten Seitenaufruf nicht mehr neu kompilieren zu muessen.



  • Natürlich ist die Behandlung letztlich unterschiedlich. Das stört den Interpreter aber herzlich wenig. Für ihn ist die Behandlung von Kommentaren oder HTML relativ gleichwertig. Der Tokenizer verpackt beides in ein eindeutiges Token (bzw. ein Token von eindeutigem Typ) und jedes erfährt dann eine bestimmte Behandlung (Verwerfen, Ausgeben ...).

    Das Verfahren wird aber nahezu identisch ablaufen: Startmarke erkennen, Endmarke erkennen. Das hat wohl Blue-Tiger gemeint, und darauf bezog ich mich ...



  • Ich kann Dir sagen, wie tntnet es macht. Tntnet hat ja eine Templatesprache, wo ich C++-Code in Html einbetten kann.

    Da gibt es einen Präcompiler, der alle statischen Teile einer Seite im C++ einfach ausgibt. Also vereinfacht wird folgendes Template:

    <%cpp>
    if (printHeader)
    {
    <%cpp>
    <h1>Das ist statischer Inhalt</h1>
    <%cpp>
    }  // der beendet das if aus dem vorigen %cpp-Block
    </%cpp>
    

    zu diesen C++-Code:

    if (printHeader)
    {
      reply.sout() << "<h1>Das ist statischer Inhalt</h1>";
    }  // der beendet das if aus dem vorigen %cpp-Block
    

    Das reply.sout() liefert einen std::ostream, auf den das Ergebnis geschrieben wird.



  • Die Theorie interessiert?

    Man kann hier fast genau so ansetzen, wie wenn man einen DOM Baum parsen würde.
    Nur ein bisschen anders.

    Am besten sucht man das erste Vorkommnis von "<?php" ab der Stelle 0. Dann sucht man das Vorkommnis von "?>" ab der Stelle 0 (Voraussetzung für diesen einfachen Weg ist natürlich dass ?> nicht in Kommentaren existieren darf). Jetzt den ganzen Text dazwischen an den internen eigenen Interpreter geben und dann entsprechend dessen Ausgabe mit dem gesamten Code ersetzen.

    Dann wiederholt sich das ganze Spiel, bis man am Ende ist. Am besten immer ab Position 0 suchen, denn dann kann mann, wenn der eigene Interpreter noch einmal Interpreter Code raushaut, diesen ohne weitere "rekursionen" (falsch gewähltes Wort mir fällt aber kein besseres ein) auch wieder durch den Interpreter jagen, bis halt am Ende alles schön geparsed ist und kein PHP spezifischer Code mehr existiert.

    Dies kann man nun auch für seine eigene Sprache relativ simpel implementieren, wie gesagt es gibt bei dieser Methodik auch einige Nachteile, jedoch ist sie am einfachsten 🙂


  • Mod

    Blackskyliner schrieb:

    Man kann hier fast genau so ansetzen, wie wenn man einen DOM Baum parsen würde.
    Nur ein bisschen anders.

    Ne, das ist keine gute Idee.
    Man laesst das einfach den Tokenizer machen.

    Es ist ja nicht so als ob das was zwischen ?> und <? steht geparst werden muesste. Es ist einfach ein String der automatisch ausgegeben wird. Man braucht da nichtmal einen Parser der das irgendwie verstehen muss.

    Der PHP Tokenizer macht zB ein T_INLINE_HTML
    Siehe auch: http://de.php.net/manual/en/tokens.php

    Fuer uns Menschen sieht ?> <? anders aus als /* */ aber das ist fuer den Computer komplett gleichwertig...


Anmelden zum Antworten