How to express a context free design grammar as an internal DSL in Python?
Question: [Note: Rereading this before submitting, I realized this Q has become a bit of
an epic. Thank you for indulging my long explanation of the reasoning behind
this pursuit. I feel that, were I in a position to help another undertaking a
similar project, I would be more likely to get on board if I knew the
motivation behind the question.]

I have been getting into [Structure
Synth](http://structuresynth.sourceforge.net/) by Mikael Hvidtfeldt
Christensen lately. It is a tool for generating 3D geometry from a (mostly)
context free grammar called Eisenscript. Structure Synth is itself inspired by
Context Free Art. Context free grammars can create some stunning results from
surprisingly simple rulesets.

My current Structure Synth workflow involves exporting an OBJ file from
Structure Synth, importing it into Blender, setting up lights, materials,
etcetera, then rendering with Luxrender. Unfortunately, importing these OBJ
files often brings Blender to a grinding halt as there can be thousands of
objects with fairly complex geometry. I say 'fairly' because Structure Synth
only generates basic shapes, but a sphere represented by triangles still has
many faces.

Thus, generating the structures directly in Blender would be preferable to the
current process (Blender's deep support for Python scripting should make this
possible). An intelligent Python library could use Blender's instancing
abilities to use one mesh to generate myriad objects, thus saving memory. Plus
Blender is a full-featured 3D suite and its ability to interpret a CFDG would
provide creative possibilities far beyond what Structure Synth can offer.

And so my question is how best to translate the Eisenscript grammar into a
Python DSL. Here's what a simple Eisenscript looks like:

    
    
    set maxdepth 2000
    { a 0.9 hue 30 } R1 
    
    rule R1 { 
      { x 1  rz 3 ry 5  } R1
      { s 1 1 0.1 sat 0.9 } box
    }
    
    rule R1 { 
      { x 1  rz -3 ry 5  } R1
      { s 1 1 0.1 } box
    }
    

To explain, the first call to R1 (line 2) will randomly invoke one of the two
definitions of R1. Each definition of R1 recursively calls R1 (randomly
invoking one of the two definitions) and also creates a box. The first line
kills generation after recursion has gone 2000 levels deep.

Jeremy Ashkenas (of CoffeeScript fame) successfully implemented a [context
free DSL in Ruby](http://ashkenas.com/codework/context-free.html) using
blocks. Internally, it works by creating a hash key for each rule 'name', and
stores the blocks for each definition of that rule in an array, to be randomly
chosen when the rule is invoked.

The previous Eisenscript rule definitions would translate to the Ruby DSL like
so:

    
    
    rule :r1 do
      r1 :x => 1, :rz => 3, :ry => 5
      box :s => [1, 1, 0.1], :sat => 0.9
    end
    
    rule :r1 do
      r1 :x => 1, :rz => -3, :ry => 5
      box :s => [1, 1, 0.1]
    end
    

I am a novice Python user and so have been doing some research on Python's
functional programming capabilities. It seems like lambda is too limited to
create something similar to Jeremy's Ruby DSL, and, as far as I can tell,
lambda is the only option for anonymous functions?

How might an experienced Pythonista approach the design?


Answer: Writing a parser for a context free grammar is hard. You're probably better
off using some sort of library to make things easier on yourself.

I would check out the [PyParsing](http://pyparsing.wikispaces.com/) module.
The download comes with a number of examples, one of which is a simple SQL
parser, which might be enlightening to look at, at least as a first step.

