Jedes Mal, wenn Sie eine Zwischenrepräsentation benötigen, die zum Generieren von Code verwendet wird, ist das offensichtlichste, was mir in den Sinn kommt, ein abstrakter Syntaxbaum (AST). Ihre Beispieldarstellung sind Listen, die meiner Erfahrung nach nicht so flexibel sind. Für etwas mehr als triviale Code-Generierung würde ich nicht um den heißen Brei herumreden, und nur mit einer vollständigen AST-Darstellung gehen. Indem Sie Listen verwenden, schieben Sie mehr Arbeit auf die Generierungsseite, um die Informationen wie Typen und was der erste Gegenstand bedeutet, auszuwerten. Wenn Sie zu einer AST-Repräsentation wechseln, erhalten Sie mehr Flexibilität und entkoppeln mehr von dem System auf Kosten von mehr Arbeit von der Parsing-Seite (oder mehr Arbeit von den Funktionen, die die Formulare generieren). Die Erzeugungsseite wird ebenfalls mehr Arbeit leisten, aber die vielen dieser Komponenten können entkoppelt werden, da ihre Eingaben strukturierter sind.
Im Hinblick darauf, was sollte der AST aussehen, ich kopiere entweder enlive Christophe Groß würde, wo er {:tag <tag name> :attrs <map of attrs> :content <some collection>}
oder welche clojure Skript verwendet verwendet, {:op <some operator> :children <some collection>}
.
Das macht es ziemlich allgemein, da Sie willkürliche Wanderer definieren können, die in :children
spähen und jede Struktur durchqueren können, ohne genau zu wissen, was die :op
's oder :tag
' s sind.
Dann für atomare Komponenten, können Sie es in einer Karte umhüllen und geben Sie einige Informationen (in Bezug auf die Semantik Ihrer DSL), die unabhängig von der tatsächlichen Art des Objekts ist. {:atom <the object> :type :background-image}
.
Auf der Seite der Code-Generierung, wenn Sie auf ein Atom stoßen, kann Ihr Code dann auf die :type
versenden, und dann, wenn Sie möchten, weiter auf den tatsächlichen Typ des Objekts versenden. Die Generierung aus Sammlungsformularen ist ebenfalls einfach, Versand am: op /: tag, und dann wieder mit den Kindern. Für welche Sammlung, die ich für Kinder verwende, habe ich mehr über die Diskussionen in den Google-Gruppen gelesen. Ihre Schlussfolgerungen waren für mich aufschlussreich.
https://groups.google.com/forum/#!topic/clojure-dev/vZLVKmKX0oc/discussion
Um es zusammenzufassen, für Kinder, wenn es semantischen Ordnungs Bedeutung waren wie in einer if-Anweisung, dann {:conditional z :then y :else x}
eine Karte verwenden. Wenn es nur eine Argumentliste wäre, könnten Sie einen Vektor verwenden.
vielen dank - genau die art von einblicken, nach denen ich gesucht habe! – mikera