<xsl:transform 
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
   version="1.0">
<xsl:output indent="yes" method="text"/>

<xsl:template match="define">
<xsl:value-of select="@name"/> = {
   <xsl:apply-templates/>
}

</xsl:template>

<xsl:template match="ref">
<xsl:text> </xsl:text>
<xsl:value-of select="@name"/>
</xsl:template>

<xsl:template match="zeroOrMore">
<xsl:apply-templates/>*
</xsl:template>

<xsl:template match="oneOrMore">
<xsl:apply-templates/>+
</xsl:template>

<xsl:template match="choice">
<xsl:apply-templates/>?
</xsl:template>

<xsl:template match="data[@type='class']">
[<xsl:for-each select="./*[not(position()=last())]">
   <xsl:value-of select="."/>,
</xsl:for-each>
   <xsl:value-of select="./*[position()=last()]"/>]
</xsl:template>

<xsl:template match="data[@type='neg-class']">
[^<xsl:for-each select="./*[not(position()=last())]">
   <xsl:value-of select="."/>,
</xsl:for-each>
   <xsl:value-of select="./*[position()=last()]"/>]
</xsl:template>

<xsl:template match="value">
"<xsl:value-of select="."/>"
</xsl:template>

<xsl:template match="not">
!{ <xsl:apply-templates/> }
</xsl:template>

<xsl:template match="choice">
(<xsl:for-each select="./*[not(position()=last())]">
   <xsl:apply-templates select="."/> | 
</xsl:for-each>
   <xsl:apply-templates select="./*[position()=last()]"/>)
</xsl:template>

<xsl:template match="interleave">
(<xsl:for-each select="./*[not(position()=last())]">
   <xsl:apply-templates select="."/> <xsl:text> &amp; </xsl:text> 
</xsl:for-each>
   <xsl:apply-templates select="./*[position()=last()]"/>)
</xsl:template>

<xsl:template match="intersect">
(<xsl:for-each select="./*[not(position()=last())]">
   <xsl:apply-templates select="."/> ~ 
</xsl:for-each>
   <xsl:apply-templates select="./*[position()=last()]"/>)
</xsl:template>

<!-- Good ol' don't-pass-text-through -->
<xsl:template match="text()|@*"/>

</xsl:transform>
