Ankündigung

Einklappen
Keine Ankündigung bisher.

Parserbau

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Parserbau

    Sagt mal, ich müssts eigentlich selbst wissen. Aber wie kann ich einen Lexer & Parser für eine simple Sprache bauen?
    Weiß schon garnicht mehr wie ich anfangen kann.

    Worums eigentlich geht:
    Ich möchte über eine XML eine Website-Konfiguration ermöglichen, beispielsweise:
    Code:
    ..
    <error_reporting>E_ALL | E_STRICT</error_reporting>
    ..
    Wie parse ich den Schlonz jetzt? Denn ohne das zu parsen, müsste ich wohl oder übel eval() verwenden, die Tür stände offen für Code-Injection. Ein unbeabsichtigt erzeugter Parse-Error wäre auch denkbar.
    Ich könnte zwar mit get_defined_constants() und array_filter alle E_* Konstanten ermitteln, prüfen ob in dem Tag diese Konstanten plus erlaubte Zeichen | ^ & + vorkommen, aber einen Syntax-Error könnte man so trotzdem noch erzeugen.

    Ideen? Eigentlich ist da ein Parser schon wieder oversized, aber vielleicht gibts ja eine schlanke Bibliothek, der man nur das Alphabet und ein paar bekannte Regeln übergeben muss und dann wird getestet. RegExp sind hier glaube ich nicht mächtig genug - oder?

  • #2
    obwohl


    explode nach | oder & oder +
    erlaubte Elemente nun optional ^ mit nachfolgender E_* Konstante

    aber das würde das konkrete Problem lösen, das abstrakte nicht, nämlich dass über XML bestimmte PHP-Flags gesetzt werden können. Bzw nicht nur Flags, das wäre ja einfach, sondern auch Werte.

    Kommentar


    • #3
      Hallo Zergling,

      wenn du schon xml-konforme Konfigurations-Files verwendest, kannst du das doch sehr einfach über bereits implementierte XML-Handler/-Parser erledigen.

      Dazu einfach die XML-Datei einlesen und für definierte Knoten einen Handler oder eine Handler-Methode implementieren.

      Was das XML angeht würde ich etwas anderes rangehen:

      Code:
      <root>
        <configuration>
          ..
          <configitem name="error_reporting">E_ALL | E_STRICT</configitem>
          <configitem name="session.save_path">/tmp</configitem>
          ..
        </configuration> 
      </root>
      Das ist IMHO generischer und vor allem leichter zu implementieren.

      Sollte keine XML-Bibliothek zur Verfügung stellen, würde ich einen generischen HTML/XML-Tag-Parser implementieren, der dir aus bekannten Tags einen Objektbaum baut, den du dann anschließend abfragen kannst. Anregungen dazu gibts im Code meines Page-Controllers genügend...

      Kommentar


      • #4
        Und da tauchts wieder auf .. "generisch"

        Kannst du mir ein kleines Beispiel geben? Kann das wirklich schon der XML-Parser erledigen? Über DTD dann?

        Kommentar


        • #5
          was spricht eigentlich gegen config.php
          wo einfach
          error_reporting(E_ALL | E_STRICT); steht?
          oder ist das für dich zu einfach?
          ich sehe kein grund PHP-einstellungen in xml abzuspeichern, da diese einstellungen so wieso nur PHP-Seitig interresant sind und haben für die andere Anwendungen keine bedeutung.

          Kommentar


          • #6
            Ja, aber ich komme langsam davon weg, meine Website über den PHP-Code zu konfigurieren. Ich möchte sie über ein Webinterface konfigurieren, und seien es so elementare Einstellungen wie das error_reporting. Und da bietet sich XML nun mal an.

            Kommentar


            • #7
              nicht unbedingt.
              über Webinterface kann man wunderbar die config.php Datei erzeigen als auch überschreiben und auslesen.
              dabei reicht bei auslesen einfach file, trimm und explode funktionen.
              Auch bei einstellung von configuration, die nicht so offt vorkommt brauchst du dir keine grosse sorgen um die Geschwindigkeit von eval() zu machen (wenn eval überhaupt benötigt wird).
              du findest bestimmt ein paar Bibliotheken oder kannst auch eigener XML Parser entwickeln, aber du muss bedenken, dass dieser configurationsparser bei jedem Aufruf von deiner Hauptanwendung seine Arbeit erledigen muss, was in vergleich zu der einfacher include von config.php mit ein paar variablen, langsamer läuft.

              Configdatei:
              $errorlevel=E_ALL | E_STRICT;//const
              $einevariable="wert";//string
              $nocheine=3;//int
              $etwas=4.6;//double
              $was=FALSE;//bool
              $ding=;//string blja blja blja
              ---------------
              $pattern = '/\$([^\=]+)\=(.*);(\/\/(int|bool|const|string|double).*)?/';
              preg_match_all($pattern, file_get_contents("config.php"), $array);
              echo '<pre>', print_r($array, true), '</pre>';
              gibt dir alle nötige informationen um die Variablen über ein formular behandeln zu können und danach auf grund von den Typen, die als kommentar stehen, richtig veränder und wieder in config.php abzuspeichern.

              sorry, dass ich mit meinem Vorschlag kein direkter Antwort auf deine Frage gebe, aber ich meine, das erzeugen von phpscripten, die nur aus den variablen und den Werten besteht, ziemlich simpel ist und passt für die PHP anwendung viel besser, da die überflüssige Parsen von configurationen mit einer extra bibliothek nicht mehr gebraucht wird.

              Kommentar


              • #8
                Das wäre schon möglich, aber das gefällt mir nicht so wirklich. Ich denke 20 KB sollten für ein Config-XML nicht zuviel sein. Aber notfalls werde ich es so cachen wie du vorgeschlagen hast. Vom Speed ist das zweifelsohne unschlagbar.

                Kommentar


                • #9
                  Zitat von Zergling
                  Und da tauchts wieder auf .. "generisch"

                  Kannst du mir ein kleines Beispiel geben? Kann das wirklich schon der XML-Parser erledigen? Über DTD dann?
                  Tja, generisch ist eines meiner Lieblingswörter...

                  Ein Beispiel wäre meiner Ansicht nach folgendes (ungetestet):

                  PHP-Code:
                  <?php
                  $xmlDocument 
                  domxml_open_mem(file_get_contents('/path/to/my/config/file.ext'));
                  $configurationsNode =  &$xmlDocument->first_child();
                  $ChildNodes = &$configurationsNode->child_nodes();

                  foreach (
                  $ChildNodes as $Key => $Value){

                       if(
                  $ChildNodes[$Key]->node_name() == 'configuration){

                         $ChildNodes[$Key]->node_value()

                       }     

                  }
                  ?>

                  Kommentar


                  • #10
                    Ah verstehe, da ist was dran. Ich baue meinen Projektdummy allerdings grad doch noch etwas weitreichender um. Vorbild Ruby on Rails. Eine Development-, Test- und Production-Umgebung. Da muss die config.xml erstmal hintenanstehen, bis ich die Code-Generierung hab. Ziel ist hier auch in Test-Umgebungen alle assert()s drinzulassen, in der Entwicklung kommen sie natürlich raus, genauso wie Kommentare und Whitespaces. Herrje wenn ich dann noch die Konstanten selbst reinparsen könnte. Wow. Naja alles der Reihe nach.

                    Kommentar


                    • #11
                      Herrje wenn ich dann noch die Konstanten selbst reinparsen könnte
                      Das ist ganz einfach. Definiere einfach neue Tags wie "constant" und behandle die anders.

                      Kommentar


                      • #12
                        @Slava

                        PHP-Code:
                        Configdatei
                        $errorlevel=E_ALL E_STRICT;//const 
                        $einevariable="wert";//string 
                        $nocheine=3;//int 
                        $etwas=4.6;//double 
                        $was=FALSE;//bool 
                        $ding=;//string blja blja blja 
                        --------------- 
                        $pattern '/\$([^\=]+)\=(.*);(\/\/(int|bool|const|string|double).*)?/'
                        preg_match_all($patternfile_get_contents("config.php"), $array); 
                        echo 
                        '<pre>'print_r($arraytrue), '</pre>'
                        halt moment! was hält dich hier davon ab, die config datei einfach ber require einzubinden?
                        zuerst dachte ich mir: klar, wenn nun einer die config.php verändert könnte er alle mögliche dareinschreiben.
                        dann hab ich den satz allerdings zuende gedacht: was allerdings würde denjenigen daran hindern andere dateien zu bearbeiten, wo er doch gerade dabei ist?
                        isn bischn sinnfrei so wie ich mir das denke, aber vllt. kannst dus mir ja erklären.

                        Kommentar


                        • #13
                          Direkter wäre es, statt den Konstanten einfach ihre Werte zu verwenden, allerdings haben Konstanten den Sinn, jederzeit ihren Wert ändern zu können. Hm. DIE Löung habe ich jetzt aber immernoch nicht ..

                          Kommentar


                          • #14
                            [quote]allerdings haben Konstanten den Sinn, jederzeit ihren Wert ändern zu können[/qoute]
                            Ist nicht dein Ernst ... ? :wink:

                            Warum bist du denn so gegen eine saubere Implementierung via XML?

                            Kommentar


                            • #15
                              Bin ich nicht, nur ist mir nicht klar wie ich über ein Schema festlegen kann, welche Werte in einem Tag erlaubt sind, vor allem sind das ja keine Werte, sondern komplexe Wertkombinationen. Zumindest so komplex, dass es mehrere Trennzeichen, ein begrenztes Alphabet und Negierung-Zeichen gibt.

                              Kommentar

                              Lädt...
                              X