Frage

Als Haustier-Projekt, würde ich versuchen, wie eine grundlegende Sprache meines eigenen Design zu implementieren, die als Web-Skriptsprache verwendet werden können. Es ist trivial, ein C ++ Programm als Apache CGI zu laufen, so dass die eigentliche Arbeit liegt darin, wie eine Eingabedatei, die nicht-Code (HTML / CSS-Markup) und serverseitigen Code zu analysieren.

In meinem under Compiler wir natürlich verwendet Flex und Bison einen Scanner und einen Parser für eine einfache Sprache zu erzeugen. Wir waren eine Kopie der Grammatik gegeben und schrieb einen Parser, der die einfache Sprache auf eine einfache Montage für eine virtuelle Maschine übersetzt. Die Flex-Scanner tokenizes die Eingabe und gibt die Token an den Bison-Parser.

Der Unterschied zwischen diesem und was ich mag ist zu tun, dass wie PHP, diese Sprache wie folgt durchsetzt einfachen HTML-Markup und die Skriptsprache haben könnte:

<p>Hello,
<? echo "World ?>
</p>

Bin ich falsch in der Annahme, dass es effizienter wäre, die Eingabedatei zu analysieren, wie folgt:

  1. Scan-Eingang, bis ein Skript Start-Tag gefunden wird (‘
  2. Zweiter Scanner tokenizes den serverseitige Skriptabschnitt der Eingabedatei (aus dem offenen tag: ‚‘) und gibt das Token an die Parser, der keine Notwendigkeit, über die Markup in der Datei wissen muss.
  3. Die Steuerung wird an den ersten Scanner zurückgegeben, die diese allgemeine Muster setzt sich fort.

Grundsätzlich ist der erste Scanner unterscheidet nur zwischen Markup und Code (die direkt an den Browser zurückgegeben wird unmodifizierten), die mit dem zweiten Scanner geführt wird, was wiederum den Code tokenizes und übergibt die Token an den Parser.

Wenn das nicht ein festes Muster-Design, wie Sprachen wie PHP Griff Scannen Eingabe tun und Analysieren von Code effizient?

War es hilfreich?

Lösung

Sie möchten bei Startbedingungen suchen. Zum Beispiel:

"<?"            { BEGIN (PHP); }
<PHP>[a-zA-Z]*  { return PHP_TOKEN; }
<PHP>">?"       { BEGIN (0); }
[a-zA-Z]*       { return HTML_TOKEN; }

Sie beginnen im Zustand 0, verwenden Sie die BEGIN Makro Zustände zu ändern. Um nur ein RE zu entsprechen, während in einem bestimmten Zustand, der RE mit dem Staatsnamen von Winkel-Klammer voranstellen.

In dem obigen Beispiel „PHP“ ist Zustand. "PHP_TOKEN" und "HTML_TOKEN" ist _% token_s durch Ihre yacc-Datei definiert.

Andere Tipps

PHP unterscheidet nicht zwischen dem Scannen und dem Markup. Es gibt einfach, wenn in Markup-Modus zu puffern, und schaltet dann auf, wenn das Parsen in Codemodus. Sie brauchen keinen zwei Pass-Scanner benötigen, und Sie können dies tun, mit nur einem einzigen Flex Lexer.

Wenn Sie daran interessiert sind, wie PHP selbst funktioniert, laden Sie die Quelle (versuchen Sie die PHP4 Quelle es viel einfacher ist, zu verstehen). Was Sie wollen, zu betrachten ist im Zend Directory zend_language_scanner.l.

Nachdem etwas ähnliches selbst geschrieben, würde ich wirklich Umdenken empfehle die Flex und Bison Weg zu gehen, und gehen Sie mit etwas Modernes wie Antlr . Es ist viel einfacher, leichter zu verstehen (die in einer lex Grammatik verwendet Makros bekommen sehr verwirrend und schwer zu lesen) und es ist ein Debugger ( ANTLRWorks ), so dass Sie müssen nicht Stunden damit verbringen, auf 3 Meg Debug-Dateien. Es unterstützt auch viele Sprachen (Java, C #, C, Python, Actionscript) und verfügt über ein ausgezeichnetes Buch und eine sehr gute Website, die die Lage sein, sollten Sie sich und laufen in kürzester Zeit zu bekommen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top