<?xml version="1.0"?>
<xsl:transform version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output indent="yes"/>

<xsl:template name="identity" match="node()">
  <!--
   ! This is an identity template in XSLT.
   | However, other templates with higer specificity
   | will override this where appropriate.
   +-->
  <xsl:copy>
    <xsl:for-each select="attribute::*">
      <xsl:copy/>
      </xsl:for-each>
    <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>

<xsl:template match="*[symbol[@optional='true']]" name="enumerate-production">
<xsl:param name="ylist"/>
<xsl:param name="nlist"/>

  <!--
   ! Select the first symbol with optional = 'true'
   ! which has not yet been proccessed.
   +-->
  <xsl:variable name="sym"
    select="symbol
            [@optional='true']
            [not(contains(concat($ylist, ' ', $nlist), generate-id()))]
            [1]"/>

  <xsl:choose>
    <xsl:when test="$sym">
      <!-- We found a new symbol this pass. Get it's id. -->
      <xsl:variable name="sid" select="generate-id($sym)"/>

      <!-- Recurse with this symbol active. -->
      <xsl:call-template name="enumerate-production">
        <xsl:with-param name="ylist" select="concat($ylist, ' ', $sid)"/>
        <xsl:with-param name="nlist" select="$nlist"/>
        </xsl:call-template>

      <!-- Recurse with this symbol inactive. -->
      <xsl:call-template name="enumerate-production">
        <xsl:with-param name="ylist" select="$ylist"/>
        <xsl:with-param name="nlist" select="concat($nlist, ' ', $sid)"/>
        </xsl:call-template>
      </xsl:when>

    <xsl:otherwise>
      <!--
       ! No new symbol, thus this is the final pass. 
       !
       ! Since we wish to strip out epsilon productions, and since they
       ! would be produced when there are no symbols which are not optional
       ! AND the $ylist is empty, we test on this here.
       +-->
      <xsl:if test="count(symbol[not(@optional) or @optional!='true']) or $ylist">
      <xsl:copy>
        <xsl:for-each select="symbol[not(contains($nlist, generate-id()))]">
          <symbol>
            <xsl:for-each select="attribute::*[name() != 'optional']">
              <xsl:copy/>
              </xsl:for-each>
              <xsl:copy-of select="node()"/>
            </symbol>
          </xsl:for-each>
        </xsl:copy>
        </xsl:if>
      </xsl:otherwise>
    </xsl:choose>

  </xsl:template>

</xsl:transform>
