// ===========================================================================
// This file has been generated by
// Rats! Parser Generator, version 1.14.2,
// (C) 2004-2008 Robert Grimm,
// on Tuesday, October 14, 2008 at 8:49:20 AM.
// Edit at your own risk.
// ===========================================================================

package xtc.xform;

import java.io.Reader;
import java.io.IOException;

import java.util.HashSet;
import java.util.Set;

import xtc.util.Action;
import xtc.util.Pair;

import xtc.tree.Node;
import xtc.tree.GNode;

import xtc.parser.ParserBase;
import xtc.parser.Column;
import xtc.parser.Result;
import xtc.parser.SemanticValue;
import xtc.parser.ParseError;

/**
 * Packrat parser for grammar <code>xtc.xform.XForm</code>.
 *
 * <p />This class has been generated by the <i>Rats!</i> parser
 * generator, version 1.14.2, (C) 2004-2008 Robert Grimm.
 */
public final class XFormParser extends ParserBase {

  /** The XFORM_KEYWORDS set. */
  public static final Set<String> XFORM_KEYWORDS = new HashSet<String>();

  // =========================================================================

  /** Chunk 1 of memoized results. */
  static final class Chunk1 {
    Result fCompoundExpression;
    Result fCompoundExpression$$Plus1;
    Result fLetBinding;
    Result fIterativeBindingList;
    Result fIterativeBindingList$$Star1;
    Result fIterativeBinding;
    Result fReplacementExpression;
    Result fNewNodeExpression;
    Result fChild;
    Result fIntersectionExpression;
  }

  /** Chunk 2 of memoized results. */
  static final class Chunk2 {
    Result fLogicalExpression;
    Result fPathExpression;
    Result fRelativePathExpression;
    Result fStepExpression;
    Result fVariableReference;
    Result fIdentifier;
    Result fWord;
    Result fWord$$Star1;
    Result fKeyword;
    Result fStringLiteral;
  }

  /** Chunk 3 of memoized results. */
  static final class Chunk3 {
    Result fIntegerLiteral;
    Result fNull;
    Result fSymbol;
  }

  // =========================================================================

  /** Memoization table column. */
  static final class XFormParserColumn extends Column {
    Chunk1 chunk1;
    Chunk2 chunk2;
    Chunk3 chunk3;
  }

  // =========================================================================

  /**
   * Create a new packrat parser.
   *
   * @param reader The reader.
   * @param file The file name.
   */
  public XFormParser(final Reader reader, final String file) {
    super(reader, file);
  }

  /**
   * Create a new packrat parser.
   *
   * @param reader The file reader.
   * @param file The file name.
   * @param size The file size.
   */
  public XFormParser(final Reader reader, final String file, final int size) {
    super(reader, file, size);
  }

  // =========================================================================

  protected Column newColumn() {
    return new XFormParserColumn();
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.XForm.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  public Result pXForm(final int yyStart) throws IOException {
    Result     yyResult;
    int        yyOption1;
    Node       yyOpValue1;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pSpacing(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {

      yyOption1  = yyResult.index;
      yyOpValue1 = null;

      yyResult = pImportStatement(yyOption1);
      yyError  = yyResult.select(yyError, yyOption1);
      if (yyResult.hasValue()) {
        final Node v$el$1 = yyResult.semanticValue();

        yyOption1  = yyResult.index;
        yyOpValue1 = v$el$1;
      }
      { // Start scope for v$g$1.
        final Node v$g$1 = yyOpValue1;

        yyResult = pCompoundExpression(yyOption1);
        yyError  = yyResult.select(yyError);
        if (yyResult.hasValue()) {
          final Node v$g$2 = yyResult.semanticValue();

          yyResult = pEndOfFile(yyResult.index);
          yyError  = yyResult.select(yyError);
          if (yyResult.hasValue()) {

            yyValue = GNode.create("XForm", v$g$1, v$g$2);
            yyValue.setLocation(location(yyStart));

            return yyResult.createValue(yyValue, yyError);
          }
        }
      } // End scope for v$g$1.
    }

    // Done.
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.ImportStatement.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pImportStatement(final int yyStart) throws IOException {
    Result     yyResult;
    int        yyBase;
    int        yyRepetition1;
    Pair<Node> yyRepValue1;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pKeyword(yyStart);
    if (yyResult.hasValue("import")) {

      yyResult = pStringLiteral(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final Node v$g$1 = yyResult.semanticValue();

        yyRepetition1 = yyResult.index;
        yyRepValue1   = Pair.empty();
        while (true) {

          yyBase   = yyRepetition1;
          yyResult = pSymbol(yyBase);
          if (yyResult.hasValue(",")) {

            yyResult = pStringLiteral(yyResult.index);
            yyError  = yyResult.select(yyError, yyRepetition1);
            if (yyResult.hasValue()) {
              final Node v$el$1 = yyResult.semanticValue();

              yyRepetition1 = yyResult.index;
              yyRepValue1   = new Pair<Node>(v$el$1, yyRepValue1);
              continue;
            }
          } else {
            yyError = yyError.select("',' expected", yyBase);
          }
          break;
        }
        { // Start scope for v$g$2.
          final Pair<Node> v$g$2 = yyRepValue1.reverse();

          yyValue = GNode.createFromPair("ImportStatement", v$g$1, v$g$2);
          yyValue.setLocation(location(yyStart));

          return new SemanticValue(yyValue, yyRepetition1, yyError);
        } // End scope for v$g$2.
      }
    }

    // Done.
    yyError = yyError.select("import statement expected", yyStart);
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.CompoundExpression.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pCompoundExpression(final int yyStart) throws IOException {
    XFormParserColumn yyColumn = (XFormParserColumn)column(yyStart);
    if (null == yyColumn.chunk1) yyColumn.chunk1 = new Chunk1();
    if (null == yyColumn.chunk1.fCompoundExpression) 
      yyColumn.chunk1.fCompoundExpression = pCompoundExpression$1(yyStart);
    return yyColumn.chunk1.fCompoundExpression;
  }

  /** Actually parse xtc.xform.XForm.CompoundExpression. */
  private Result pCompoundExpression$1(final int yyStart) throws IOException {
    Result     yyResult;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative <Comma>.

    yyResult = pSingleExpression(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final Node v$g$1 = yyResult.semanticValue();

      yyResult = pCompoundExpression$$Plus1(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final Pair<Node> v$g$2 = yyResult.semanticValue();

        yyValue = GNode.createFromPair("CompoundExpression", v$g$1, v$g$2);
        yyValue.setLocation(location(yyStart));

        return yyResult.createValue(yyValue, yyError);
      }
    }

    // Alternative <Base>.

    yyResult = pSingleExpression(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      yyValue = yyResult.semanticValue();

      return yyResult.createValue(yyValue, yyError);
    }

    // Done.
    return yyError;
  }

  // =========================================================================

  /**
   * Parse synthetic nonterminal xtc.xform.XForm.CompoundExpression$$Plus1.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pCompoundExpression$$Plus1(final int yyStart) 
    throws IOException {

    XFormParserColumn yyColumn = (XFormParserColumn)column(yyStart);
    if (null == yyColumn.chunk1) yyColumn.chunk1 = new Chunk1();
    if (null == yyColumn.chunk1.fCompoundExpression$$Plus1) 
      yyColumn.chunk1.fCompoundExpression$$Plus1 = pCompoundExpression$$Plus1$1(yyStart);
    return yyColumn.chunk1.fCompoundExpression$$Plus1;
  }

  /** Actually parse xtc.xform.XForm.CompoundExpression$$Plus1. */
  private Result pCompoundExpression$$Plus1$1(final int yyStart) 
    throws IOException {

    Result     yyResult;
    Pair<Node> yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pSymbol(yyStart);
    if (yyResult.hasValue(",")) {

      yyResult = pSingleExpression(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final Node v$el$1 = yyResult.semanticValue();

        final int yyChoice1 = yyResult.index;

        // Nested alternative 1.

        yyResult = pCompoundExpression$$Plus1(yyChoice1);
        yyError  = yyResult.select(yyError);
        if (yyResult.hasValue()) {
          final Pair<Node> v$2 = yyResult.semanticValue();

          yyValue = new Pair<Node>(v$el$1, v$2);

          return yyResult.createValue(yyValue, yyError);
        }

        // Nested alternative 2.

        yyValue = new Pair<Node>(v$el$1);

        return new SemanticValue(yyValue, yyChoice1, yyError);
      }
    }

    // Done.
    yyError = yyError.select("compound expression expected", yyStart);
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.SingleExpression.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pSingleExpression(final int yyStart) throws IOException {
    Result     yyResult;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative <Replacement>.

    yyResult = pReplacementExpression(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      yyValue = yyResult.semanticValue();

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative <InsertBefore>.

    yyResult = pInsertBeforeExpression(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      yyValue = yyResult.semanticValue();

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative <InsertAfter>.

    yyResult = pInsertAfterExpression(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      yyValue = yyResult.semanticValue();

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative <Remove>.

    yyResult = pRemoveExpression(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      yyValue = yyResult.semanticValue();

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative <Add>.

    yyResult = pAddExpression(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      yyValue = yyResult.semanticValue();

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative <Let>.

    yyResult = pLetExpression(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      yyValue = yyResult.semanticValue();

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative <For>.

    yyResult = pForExpression(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      yyValue = yyResult.semanticValue();

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative <CFor>.

    yyResult = pCForExpression(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      yyValue = yyResult.semanticValue();

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative <If>.

    yyResult = pIfExpression(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      yyValue = yyResult.semanticValue();

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative <NewItem>.

    yyResult = pNewItemExpression(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      yyValue = yyResult.semanticValue();

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative <Union>.

    yyResult = pUnionExpression(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      yyValue = yyResult.semanticValue();

      return yyResult.createValue(yyValue, yyError);
    }

    // Done.
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.LetExpression.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pLetExpression(final int yyStart) throws IOException {
    Result     yyResult;
    int        yyBase;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pKeyword(yyStart);
    if (yyResult.hasValue("let")) {

      yyResult = pLetBindingList(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final Node v$g$1 = yyResult.semanticValue();

        yyBase   = yyResult.index;
        yyResult = pKeyword(yyBase);
        if (yyResult.hasValue("return")) {

          yyResult = pSingleExpression(yyResult.index);
          yyError  = yyResult.select(yyError);
          if (yyResult.hasValue()) {
            final Node v$g$2 = yyResult.semanticValue();

            yyValue = GNode.create("LetExpression", v$g$1, v$g$2);
            yyValue.setLocation(location(yyStart));

            return yyResult.createValue(yyValue, yyError);
          }
        } else {
          yyError = yyError.select("'return' expected", yyBase);
        }
      }
    }

    // Done.
    yyError = yyError.select("let expression expected", yyStart);
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.LetBindingList.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pLetBindingList(final int yyStart) throws IOException {
    Result     yyResult;
    int        yyBase;
    int        yyRepetition1;
    Pair<Node> yyRepValue1;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pLetBinding(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final Node v$g$1 = yyResult.semanticValue();

      yyRepetition1 = yyResult.index;
      yyRepValue1   = Pair.empty();
      while (true) {

        yyBase   = yyRepetition1;
        yyResult = pSymbol(yyBase);
        if (yyResult.hasValue(",")) {

          yyResult = pLetBinding(yyResult.index);
          yyError  = yyResult.select(yyError, yyRepetition1);
          if (yyResult.hasValue()) {
            final Node v$el$1 = yyResult.semanticValue();

            yyRepetition1 = yyResult.index;
            yyRepValue1   = new Pair<Node>(v$el$1, yyRepValue1);
            continue;
          }
        } else {
          yyError = yyError.select("',' expected", yyBase);
        }
        break;
      }
      { // Start scope for v$g$2.
        final Pair<Node> v$g$2 = yyRepValue1.reverse();

        yyValue = GNode.createFromPair("LetBindingList", v$g$1, v$g$2);
        yyValue.setLocation(location(yyStart));

        return new SemanticValue(yyValue, yyRepetition1, yyError);
      } // End scope for v$g$2.
    }

    // Done.
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.LetBinding.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pLetBinding(final int yyStart) throws IOException {
    XFormParserColumn yyColumn = (XFormParserColumn)column(yyStart);
    if (null == yyColumn.chunk1) yyColumn.chunk1 = new Chunk1();
    if (null == yyColumn.chunk1.fLetBinding) 
      yyColumn.chunk1.fLetBinding = pLetBinding$1(yyStart);
    return yyColumn.chunk1.fLetBinding;
  }

  /** Actually parse xtc.xform.XForm.LetBinding. */
  private Result pLetBinding$1(final int yyStart) throws IOException {
    Result     yyResult;
    int        yyBase;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pVariableReference(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final Node v$g$1 = yyResult.semanticValue();

      yyBase   = yyResult.index;
      yyResult = pKeyword(yyBase);
      if (yyResult.hasValue("be")) {

        yyResult = pSingleExpression(yyResult.index);
        yyError  = yyResult.select(yyError);
        if (yyResult.hasValue()) {
          final Node v$g$2 = yyResult.semanticValue();

          yyValue = GNode.create("LetBinding", v$g$1, v$g$2);
          yyValue.setLocation(location(yyStart));

          return yyResult.createValue(yyValue, yyError);
        }
      } else {
        yyError = yyError.select("'be' expected", yyBase);
      }
    }

    // Done.
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.ForExpression.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pForExpression(final int yyStart) throws IOException {
    Result     yyResult;
    int        yyBase;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pKeyword(yyStart);
    if (yyResult.hasValue("for")) {

      yyResult = pIterativeBindingList(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final Node v$g$1 = yyResult.semanticValue();

        final int yyChoice1 = yyResult.index;

        // Nested alternative 1.

        yyBase   = yyChoice1;
        yyResult = pKeyword(yyBase);
        if (yyResult.hasValue("return")) {

          yyResult = pSingleExpression(yyResult.index);
          yyError  = yyResult.select(yyError);
          if (yyResult.hasValue()) {
            final Node v$g$2 = yyResult.semanticValue();

            yyValue = GNode.create("ForExpression", v$g$1, v$g$2);
            yyValue.setLocation(location(yyStart));

            return yyResult.createValue(yyValue, yyError);
          }
        } else {
          yyError = yyError.select("'return' expected", yyBase);
        }

        // Nested alternative 2.

        yyResult = pReplacementExpression(yyChoice1);
        yyError  = yyResult.select(yyError);
        if (yyResult.hasValue()) {
          final Node v$g$3 = yyResult.semanticValue();

          yyValue = GNode.create("ForExpression", v$g$1, v$g$3);
          yyValue.setLocation(location(yyStart));

          return yyResult.createValue(yyValue, yyError);
        }
      }
    }

    // Done.
    yyError = yyError.select("for expression expected", yyStart);
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.CForExpression.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pCForExpression(final int yyStart) throws IOException {
    Result     yyResult;
    int        yyBase;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pKeyword(yyStart);
    if (yyResult.hasValue("cfor")) {

      yyResult = pIterativeBindingList(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final Node v$g$1 = yyResult.semanticValue();

        final int yyChoice1 = yyResult.index;

        // Nested alternative 1.

        yyBase   = yyChoice1;
        yyResult = pKeyword(yyBase);
        if (yyResult.hasValue("return")) {

          yyResult = pSingleExpression(yyResult.index);
          yyError  = yyResult.select(yyError);
          if (yyResult.hasValue()) {
            final Node v$g$2 = yyResult.semanticValue();

            yyValue = GNode.create("CForExpression", v$g$1, v$g$2);
            yyValue.setLocation(location(yyStart));

            return yyResult.createValue(yyValue, yyError);
          }
        } else {
          yyError = yyError.select("'return' expected", yyBase);
        }

        // Nested alternative 2.

        yyResult = pReplacementExpression(yyChoice1);
        yyError  = yyResult.select(yyError);
        if (yyResult.hasValue()) {
          final Node v$g$3 = yyResult.semanticValue();

          yyValue = GNode.create("CForExpression", v$g$1, v$g$3);
          yyValue.setLocation(location(yyStart));

          return yyResult.createValue(yyValue, yyError);
        }
      }
    }

    // Done.
    yyError = yyError.select("c for expression expected", yyStart);
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.IterativeBindingList.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pIterativeBindingList(final int yyStart) throws IOException {
    XFormParserColumn yyColumn = (XFormParserColumn)column(yyStart);
    if (null == yyColumn.chunk1) yyColumn.chunk1 = new Chunk1();
    if (null == yyColumn.chunk1.fIterativeBindingList) 
      yyColumn.chunk1.fIterativeBindingList = pIterativeBindingList$1(yyStart);
    return yyColumn.chunk1.fIterativeBindingList;
  }

  /** Actually parse xtc.xform.XForm.IterativeBindingList. */
  private Result pIterativeBindingList$1(final int yyStart) 
    throws IOException {

    Result     yyResult;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pIterativeBinding(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final Node v$g$1 = yyResult.semanticValue();

      yyResult = pIterativeBindingList$$Star1(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final Pair<Node> v$g$2 = yyResult.semanticValue();

        yyValue = GNode.createFromPair("IterativeBindingList", v$g$1, v$g$2);
        yyValue.setLocation(location(yyStart));

        return yyResult.createValue(yyValue, yyError);
      }
    }

    // Done.
    return yyError;
  }

  // =========================================================================

  /**
   * Parse synthetic nonterminal xtc.xform.XForm.IterativeBindingList$$Star1.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pIterativeBindingList$$Star1(final int yyStart) 
    throws IOException {

    XFormParserColumn yyColumn = (XFormParserColumn)column(yyStart);
    if (null == yyColumn.chunk1) yyColumn.chunk1 = new Chunk1();
    if (null == yyColumn.chunk1.fIterativeBindingList$$Star1) 
      yyColumn.chunk1.fIterativeBindingList$$Star1 = pIterativeBindingList$$Star1$1(yyStart);
    return yyColumn.chunk1.fIterativeBindingList$$Star1;
  }

  /** Actually parse xtc.xform.XForm.IterativeBindingList$$Star1. */
  private Result pIterativeBindingList$$Star1$1(final int yyStart) 
    throws IOException {

    Result     yyResult;
    Pair<Node> yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pSymbol(yyStart);
    if (yyResult.hasValue(",")) {

      yyResult = pIterativeBinding(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final Node v$el$1 = yyResult.semanticValue();

        yyResult = pIterativeBindingList$$Star1(yyResult.index);
        yyError  = yyResult.select(yyError);
        if (yyResult.hasValue()) {
          final Pair<Node> v$2 = yyResult.semanticValue();

          yyValue = new Pair<Node>(v$el$1, v$2);

          return yyResult.createValue(yyValue, yyError);
        }
      }
    }

    // Alternative 2.

    yyValue = Pair.empty();

    return new SemanticValue(yyValue, yyStart, yyError);
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.IterativeBinding.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pIterativeBinding(final int yyStart) throws IOException {
    XFormParserColumn yyColumn = (XFormParserColumn)column(yyStart);
    if (null == yyColumn.chunk1) yyColumn.chunk1 = new Chunk1();
    if (null == yyColumn.chunk1.fIterativeBinding) 
      yyColumn.chunk1.fIterativeBinding = pIterativeBinding$1(yyStart);
    return yyColumn.chunk1.fIterativeBinding;
  }

  /** Actually parse xtc.xform.XForm.IterativeBinding. */
  private Result pIterativeBinding$1(final int yyStart) throws IOException {
    Result     yyResult;
    int        yyBase;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pVariableReference(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final Node v$g$1 = yyResult.semanticValue();

      yyBase   = yyResult.index;
      yyResult = pKeyword(yyBase);
      if (yyResult.hasValue("in")) {

        yyResult = pSingleExpression(yyResult.index);
        yyError  = yyResult.select(yyError);
        if (yyResult.hasValue()) {
          final Node v$g$2 = yyResult.semanticValue();

          yyValue = GNode.create("IterativeBinding", v$g$1, v$g$2);
          yyValue.setLocation(location(yyStart));

          return yyResult.createValue(yyValue, yyError);
        }
      } else {
        yyError = yyError.select("'in' expected", yyBase);
      }
    }

    // Done.
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.IfExpression.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pIfExpression(final int yyStart) throws IOException {
    Result     yyResult;
    int        yyBase;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pKeyword(yyStart);
    if (yyResult.hasValue("if")) {

      yyResult = pSingleExpression(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final Node v$g$1 = yyResult.semanticValue();

        yyBase   = yyResult.index;
        yyResult = pKeyword(yyBase);
        if (yyResult.hasValue("then")) {

          yyResult = pSingleExpression(yyResult.index);
          yyError  = yyResult.select(yyError);
          if (yyResult.hasValue()) {
            final Node v$g$2 = yyResult.semanticValue();

            yyBase   = yyResult.index;
            yyResult = pKeyword(yyBase);
            if (yyResult.hasValue("else")) {

              yyResult = pSingleExpression(yyResult.index);
              yyError  = yyResult.select(yyError);
              if (yyResult.hasValue()) {
                final Node v$g$3 = yyResult.semanticValue();

                yyValue = GNode.create("IfExpression", v$g$1, v$g$2, v$g$3);
                yyValue.setLocation(location(yyStart));

                return yyResult.createValue(yyValue, yyError);
              }
            } else {
              yyError = yyError.select("'else' expected", yyBase);
            }
          }
        } else {
          yyError = yyError.select("'then' expected", yyBase);
        }
      }
    }

    // Done.
    yyError = yyError.select("if expression expected", yyStart);
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.ReplacementExpression.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pReplacementExpression(final int yyStart) 
    throws IOException {

    XFormParserColumn yyColumn = (XFormParserColumn)column(yyStart);
    if (null == yyColumn.chunk1) yyColumn.chunk1 = new Chunk1();
    if (null == yyColumn.chunk1.fReplacementExpression) 
      yyColumn.chunk1.fReplacementExpression = pReplacementExpression$1(yyStart);
    return yyColumn.chunk1.fReplacementExpression;
  }

  /** Actually parse xtc.xform.XForm.ReplacementExpression. */
  private Result pReplacementExpression$1(final int yyStart) 
    throws IOException {

    Result     yyResult;
    int        yyBase;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pKeyword(yyStart);
    if (yyResult.hasValue("replace")) {

      yyResult = pSingleExpression(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final Node v$g$1 = yyResult.semanticValue();

        yyBase   = yyResult.index;
        yyResult = pKeyword(yyBase);
        if (yyResult.hasValue("with")) {

          yyResult = pSingleExpression(yyResult.index);
          yyError  = yyResult.select(yyError);
          if (yyResult.hasValue()) {
            final Node v$g$2 = yyResult.semanticValue();

            yyValue = GNode.create("ReplacementExpression", v$g$1, v$g$2);
            yyValue.setLocation(location(yyStart));

            return yyResult.createValue(yyValue, yyError);
          }
        } else {
          yyError = yyError.select("'with' expected", yyBase);
        }
      }
    }

    // Done.
    yyError = yyError.select("replacement expression expected", yyStart);
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.InsertAfterExpression.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pInsertAfterExpression(final int yyStart) 
    throws IOException {

    Result     yyResult;
    int        yyBase;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pKeyword(yyStart);
    if (yyResult.hasValue("insert")) {

      yyResult = pSingleExpression(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final Node v$g$1 = yyResult.semanticValue();

        yyBase   = yyResult.index;
        yyResult = pKeyword(yyBase);
        if (yyResult.hasValue("after")) {

          yyResult = pSingleExpression(yyResult.index);
          yyError  = yyResult.select(yyError);
          if (yyResult.hasValue()) {
            final Node v$g$2 = yyResult.semanticValue();

            yyValue = GNode.create("InsertAfterExpression", v$g$1, v$g$2);
            yyValue.setLocation(location(yyStart));

            return yyResult.createValue(yyValue, yyError);
          }
        } else {
          yyError = yyError.select("'after' expected", yyBase);
        }
      }
    }

    // Done.
    yyError = yyError.select("insert after expression expected", yyStart);
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.InsertBeforeExpression.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pInsertBeforeExpression(final int yyStart) 
    throws IOException {

    Result     yyResult;
    int        yyBase;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pKeyword(yyStart);
    if (yyResult.hasValue("insert")) {

      yyResult = pSingleExpression(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final Node v$g$1 = yyResult.semanticValue();

        yyBase   = yyResult.index;
        yyResult = pKeyword(yyBase);
        if (yyResult.hasValue("before")) {

          yyResult = pSingleExpression(yyResult.index);
          yyError  = yyResult.select(yyError);
          if (yyResult.hasValue()) {
            final Node v$g$2 = yyResult.semanticValue();

            yyValue = GNode.create("InsertBeforeExpression", v$g$1, v$g$2);
            yyValue.setLocation(location(yyStart));

            return yyResult.createValue(yyValue, yyError);
          }
        } else {
          yyError = yyError.select("'before' expected", yyBase);
        }
      }
    }

    // Done.
    yyError = yyError.select("insert before expression expected", yyStart);
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.RemoveExpression.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pRemoveExpression(final int yyStart) throws IOException {
    Result     yyResult;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pKeyword(yyStart);
    if (yyResult.hasValue("remove")) {

      yyResult = pSingleExpression(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final Node v$g$1 = yyResult.semanticValue();

        yyValue = GNode.create("RemoveExpression", v$g$1);
        yyValue.setLocation(location(yyStart));

        return yyResult.createValue(yyValue, yyError);
      }
    }

    // Done.
    yyError = yyError.select("remove expression expected", yyStart);
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.AddExpression.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pAddExpression(final int yyStart) throws IOException {
    Result     yyResult;
    int        yyBase;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pKeyword(yyStart);
    if (yyResult.hasValue("add")) {

      yyResult = pSingleExpression(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final Node v$g$1 = yyResult.semanticValue();

        yyBase   = yyResult.index;
        yyResult = pKeyword(yyBase);
        if (yyResult.hasValue("to")) {

          yyResult = pSingleExpression(yyResult.index);
          yyError  = yyResult.select(yyError);
          if (yyResult.hasValue()) {
            final Node v$g$2 = yyResult.semanticValue();

            yyValue = GNode.create("AddExpression", v$g$1, v$g$2);
            yyValue.setLocation(location(yyStart));

            return yyResult.createValue(yyValue, yyError);
          }
        } else {
          yyError = yyError.select("'to' expected", yyBase);
        }
      }
    }

    // Done.
    yyError = yyError.select("add expression expected", yyStart);
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.NewItemExpression.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pNewItemExpression(final int yyStart) throws IOException {
    Result     yyResult;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative <Null>.

    yyResult = pNull(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final Node v$g$1 = yyResult.semanticValue();

      yyValue = GNode.create("NewItemExpression", v$g$1);
      yyValue.setLocation(location(yyStart));

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative <StringLiteral>.

    yyResult = pStringLiteral(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final Node v$g$2 = yyResult.semanticValue();

      yyValue = GNode.create("NewItemExpression", v$g$2);
      yyValue.setLocation(location(yyStart));

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative <NewNode>.

    yyResult = pNewNodeExpression(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final Node v$g$3 = yyResult.semanticValue();

      yyValue = GNode.create("NewItemExpression", v$g$3);
      yyValue.setLocation(location(yyStart));

      return yyResult.createValue(yyValue, yyError);
    }

    // Done.
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.NewNodeExpression.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pNewNodeExpression(final int yyStart) throws IOException {
    XFormParserColumn yyColumn = (XFormParserColumn)column(yyStart);
    if (null == yyColumn.chunk1) yyColumn.chunk1 = new Chunk1();
    if (null == yyColumn.chunk1.fNewNodeExpression) 
      yyColumn.chunk1.fNewNodeExpression = pNewNodeExpression$1(yyStart);
    return yyColumn.chunk1.fNewNodeExpression;
  }

  /** Actually parse xtc.xform.XForm.NewNodeExpression. */
  private Result pNewNodeExpression$1(final int yyStart) throws IOException {
    Result     yyResult;
    int        yyBase;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pIdentifier(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final Node v$g$1 = yyResult.semanticValue();

      yyBase   = yyResult.index;
      yyResult = pSymbol(yyBase);
      if (yyResult.hasValue("<")) {

        yyResult = pChildren(yyResult.index);
        yyError  = yyResult.select(yyError);
        if (yyResult.hasValue()) {
          final Node v$g$2 = yyResult.semanticValue();

          yyBase   = yyResult.index;
          yyResult = pSymbol(yyBase);
          if (yyResult.hasValue(">")) {

            yyValue = GNode.create("NewNodeExpression", v$g$1, v$g$2);
            yyValue.setLocation(location(yyStart));

            return yyResult.createValue(yyValue, yyError);
          } else {
            yyError = yyError.select("'>' expected", yyBase);
          }
        }
      } else {
        yyError = yyError.select("'<' expected", yyBase);
      }
    }

    // Done.
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.Children.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pChildren(final int yyStart) throws IOException {
    Result     yyResult;
    int        yyBase;
    int        yyRepetition1;
    Pair<Node> yyRepValue1;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pChild(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final Node v$g$1 = yyResult.semanticValue();

      yyRepetition1 = yyResult.index;
      yyRepValue1   = Pair.empty();
      while (true) {

        yyBase   = yyRepetition1;
        yyResult = pSymbol(yyBase);
        if (yyResult.hasValue(",")) {

          yyResult = pChild(yyResult.index);
          yyError  = yyResult.select(yyError, yyRepetition1);
          if (yyResult.hasValue()) {
            final Node v$el$1 = yyResult.semanticValue();

            yyRepetition1 = yyResult.index;
            yyRepValue1   = new Pair<Node>(v$el$1, yyRepValue1);
            continue;
          }
        } else {
          yyError = yyError.select("',' expected", yyBase);
        }
        break;
      }
      { // Start scope for v$g$2.
        final Pair<Node> v$g$2 = yyRepValue1.reverse();

        yyValue = GNode.createFromPair("Children", v$g$1, v$g$2);
        yyValue.setLocation(location(yyStart));

        return new SemanticValue(yyValue, yyRepetition1, yyError);
      } // End scope for v$g$2.
    }

    // Done.
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.Child.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pChild(final int yyStart) throws IOException {
    XFormParserColumn yyColumn = (XFormParserColumn)column(yyStart);
    if (null == yyColumn.chunk1) yyColumn.chunk1 = new Chunk1();
    if (null == yyColumn.chunk1.fChild) 
      yyColumn.chunk1.fChild = pChild$1(yyStart);
    return yyColumn.chunk1.fChild;
  }

  /** Actually parse xtc.xform.XForm.Child. */
  private Result pChild$1(final int yyStart) throws IOException {
    Result     yyResult;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative <Null>.

    yyResult = pNull(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final Node v$g$1 = yyResult.semanticValue();

      yyValue = GNode.create("Child", v$g$1);
      yyValue.setLocation(location(yyStart));

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative <NewNode>.

    yyResult = pNewNodeExpression(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final Node v$g$2 = yyResult.semanticValue();

      yyValue = GNode.create("Child", v$g$2);
      yyValue.setLocation(location(yyStart));

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative <Sequence>.

    yyResult = pSingleExpression(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final Node v$g$3 = yyResult.semanticValue();

      yyValue = GNode.create("Child", v$g$3);
      yyValue.setLocation(location(yyStart));

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative <NoChild>.

    yyValue = GNode.create("Child", false);
    yyValue.setLocation(location(yyStart));

    return new SemanticValue(yyValue, yyStart, yyError);
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.UnionExpression.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pUnionExpression(final int yyStart) throws IOException {
    Result             yyResult;
    int                yyRepetition1;
    Pair<Action<Node>> yyRepValue1;
    Node               yyValue;
    ParseError         yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pDifferExpression(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final Node v$g$3 = yyResult.semanticValue();

      yyRepetition1 = yyResult.index;
      yyRepValue1   = Pair.empty();
      while (true) {

        yyResult = pUnionExpression$$Tail1(yyRepetition1);
        yyError  = yyResult.select(yyError, yyRepetition1);
        if (yyResult.hasValue()) {
          final Action<Node> v$4 = yyResult.semanticValue();

          yyRepetition1 = yyResult.index;
          yyRepValue1   = new Pair<Action<Node>>(v$4, yyRepValue1);
          continue;
        }
        break;
      }
      { // Start scope for v$5.
        final Pair<Action<Node>> v$5 = yyRepValue1.reverse();

        yyValue = apply(v$5, v$g$3, yyStart);

        return new SemanticValue(yyValue, yyRepetition1, yyError);
      } // End scope for v$5.
    }

    // Alternative <Base>.

    yyResult = pIntersectionExpression(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      yyValue = yyResult.semanticValue();

      yyRepetition1 = yyResult.index;
      yyRepValue1   = Pair.empty();
      while (true) {

        yyResult = pUnionExpression$$Tail1(yyRepetition1);
        yyError  = yyResult.select(yyError, yyRepetition1);
        if (yyResult.hasValue()) {
          final Action<Node> v$6 = yyResult.semanticValue();

          yyRepetition1 = yyResult.index;
          yyRepValue1   = new Pair<Action<Node>>(v$6, yyRepValue1);
          continue;
        }
        break;
      }
      { // Start scope for v$7.
        final Pair<Action<Node>> v$7 = yyRepValue1.reverse();

        yyValue = apply(v$7, yyValue, yyStart);

        return new SemanticValue(yyValue, yyRepetition1, yyError);
      } // End scope for v$7.
    }

    // Done.
    return yyError;
  }

  // =========================================================================

  /**
   * Parse synthetic nonterminal xtc.xform.XForm.UnionExpression$$Tail1.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pUnionExpression$$Tail1(final int yyStart) 
    throws IOException {

    Result       yyResult;
    Action<Node> yyValue;
    ParseError   yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pKeyword(yyStart);
    if (yyResult.hasValue("union")) {

      yyResult = pIntersectionExpression(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final Node v$g$2 = yyResult.semanticValue();

        yyValue = new Action<Node>() {
          public Node run(Node v$1) {
            return GNode.create("UnionExpression", v$1, v$g$2);
          }};

        return yyResult.createValue(yyValue, yyError);
      }
    }

    // Done.
    yyError = yyError.select("union expression expected", yyStart);
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.DifferExpression.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pDifferExpression(final int yyStart) throws IOException {
    Result     yyResult;
    int        yyBase;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative <Differ>.

    yyResult = pLogicalExpression(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final Node v$g$1 = yyResult.semanticValue();

      yyBase   = yyResult.index;
      yyResult = pKeyword(yyBase);
      if (yyResult.hasValue("differ")) {

        yyResult = pLogicalExpression(yyResult.index);
        yyError  = yyResult.select(yyError);
        if (yyResult.hasValue()) {
          final Node v$g$2 = yyResult.semanticValue();

          yyValue = GNode.create("DifferExpression", v$g$1, v$g$2);
          yyValue.setLocation(location(yyStart));

          return yyResult.createValue(yyValue, yyError);
        }
      } else {
        yyError = yyError.select("'differ' expected", yyBase);
      }
    }

    // Done.
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.IntersectionExpression.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pIntersectionExpression(final int yyStart) 
    throws IOException {

    XFormParserColumn yyColumn = (XFormParserColumn)column(yyStart);
    if (null == yyColumn.chunk1) yyColumn.chunk1 = new Chunk1();
    if (null == yyColumn.chunk1.fIntersectionExpression) 
      yyColumn.chunk1.fIntersectionExpression = pIntersectionExpression$1(yyStart);
    return yyColumn.chunk1.fIntersectionExpression;
  }

  /** Actually parse xtc.xform.XForm.IntersectionExpression. */
  private Result pIntersectionExpression$1(final int yyStart) 
    throws IOException {

    Result             yyResult;
    int                yyRepetition1;
    Pair<Action<Node>> yyRepValue1;
    Node               yyValue;
    ParseError         yyError = ParseError.DUMMY;

    // Alternative <Base>.

    yyResult = pLogicalExpression(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final Node v$g$3 = yyResult.semanticValue();

      yyRepetition1 = yyResult.index;
      yyRepValue1   = Pair.empty();
      while (true) {

        yyResult = pIntersectionExpression$$Tail1(yyRepetition1);
        yyError  = yyResult.select(yyError, yyRepetition1);
        if (yyResult.hasValue()) {
          final Action<Node> v$4 = yyResult.semanticValue();

          yyRepetition1 = yyResult.index;
          yyRepValue1   = new Pair<Action<Node>>(v$4, yyRepValue1);
          continue;
        }
        break;
      }
      { // Start scope for v$5.
        final Pair<Action<Node>> v$5 = yyRepValue1.reverse();

        yyValue = apply(v$5, v$g$3, yyStart);

        return new SemanticValue(yyValue, yyRepetition1, yyError);
      } // End scope for v$5.
    }

    // Done.
    return yyError;
  }

  // =========================================================================

  /**
   * Parse synthetic nonterminal 
   * xtc.xform.XForm.IntersectionExpression$$Tail1.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pIntersectionExpression$$Tail1(final int yyStart) 
    throws IOException {

    Result       yyResult;
    Action<Node> yyValue;
    ParseError   yyError = ParseError.DUMMY;

    // Alternative <Intersect>.

    yyResult = pKeyword(yyStart);
    if (yyResult.hasValue("intersect")) {

      yyResult = pLogicalExpression(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final Node v$g$2 = yyResult.semanticValue();

        yyValue = new Action<Node>() {
          public Node run(Node v$1) {
            return GNode.create("IntersectionExpression", v$1, v$g$2);
          }};

        return yyResult.createValue(yyValue, yyError);
      }
    }

    // Done.
    yyError = yyError.select("intersection expression expected", yyStart);
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.LogicalExpression.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pLogicalExpression(final int yyStart) throws IOException {
    XFormParserColumn yyColumn = (XFormParserColumn)column(yyStart);
    if (null == yyColumn.chunk2) yyColumn.chunk2 = new Chunk2();
    if (null == yyColumn.chunk2.fLogicalExpression) 
      yyColumn.chunk2.fLogicalExpression = pLogicalExpression$1(yyStart);
    return yyColumn.chunk2.fLogicalExpression;
  }

  /** Actually parse xtc.xform.XForm.LogicalExpression. */
  private Result pLogicalExpression$1(final int yyStart) throws IOException {
    Result     yyResult;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative <OrExpr>.

    yyResult = pOrExpression(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      yyValue = yyResult.semanticValue();

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative <AndExpr>.

    yyResult = pAndExpression(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      yyValue = yyResult.semanticValue();

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative <Base>.

    yyResult = pPathExpression(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      yyValue = yyResult.semanticValue();

      return yyResult.createValue(yyValue, yyError);
    }

    // Done.
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.OrExpression.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pOrExpression(final int yyStart) throws IOException {
    Result     yyResult;
    int        yyBase;
    int        yyRepetition1;
    boolean    yyRepeated1;
    Pair<Node> yyRepValue1;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pPathExpression(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final Node v$g$1 = yyResult.semanticValue();

      yyRepetition1 = yyResult.index;
      yyRepeated1   = false;
      yyRepValue1   = Pair.empty();
      while (true) {

        yyBase   = yyRepetition1;
        yyResult = pKeyword(yyBase);
        if (yyResult.hasValue("or")) {

          yyResult = pPathExpression(yyResult.index);
          yyError  = yyResult.select(yyError);
          if (yyResult.hasValue()) {
            final Node v$el$1 = yyResult.semanticValue();

            yyRepetition1 = yyResult.index;
            yyRepeated1   = true;
            yyRepValue1   = new Pair<Node>(v$el$1, yyRepValue1);
            continue;
          }
        } else {
          yyError = yyError.select("'or' expected", yyBase);
        }
        break;
      }

      if (yyRepeated1) {
        final Pair<Node> v$g$2 = yyRepValue1.reverse();

        yyValue = GNode.createFromPair("OrExpression", v$g$1, v$g$2);
        yyValue.setLocation(location(yyStart));

        return new SemanticValue(yyValue, yyRepetition1, yyError);
      }
    }

    // Done.
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.AndExpression.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pAndExpression(final int yyStart) throws IOException {
    Result     yyResult;
    int        yyBase;
    int        yyRepetition1;
    boolean    yyRepeated1;
    Pair<Node> yyRepValue1;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pPathExpression(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final Node v$g$1 = yyResult.semanticValue();

      yyRepetition1 = yyResult.index;
      yyRepeated1   = false;
      yyRepValue1   = Pair.empty();
      while (true) {

        yyBase   = yyRepetition1;
        yyResult = pKeyword(yyBase);
        if (yyResult.hasValue("and")) {

          yyResult = pPathExpression(yyResult.index);
          yyError  = yyResult.select(yyError);
          if (yyResult.hasValue()) {
            final Node v$el$1 = yyResult.semanticValue();

            yyRepetition1 = yyResult.index;
            yyRepeated1   = true;
            yyRepValue1   = new Pair<Node>(v$el$1, yyRepValue1);
            continue;
          }
        } else {
          yyError = yyError.select("'and' expected", yyBase);
        }
        break;
      }

      if (yyRepeated1) {
        final Pair<Node> v$g$2 = yyRepValue1.reverse();

        yyValue = GNode.createFromPair("AndExpression", v$g$1, v$g$2);
        yyValue.setLocation(location(yyStart));

        return new SemanticValue(yyValue, yyRepetition1, yyError);
      }
    }

    // Done.
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.PathExpression.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pPathExpression(final int yyStart) throws IOException {
    XFormParserColumn yyColumn = (XFormParserColumn)column(yyStart);
    if (null == yyColumn.chunk2) yyColumn.chunk2 = new Chunk2();
    if (null == yyColumn.chunk2.fPathExpression) 
      yyColumn.chunk2.fPathExpression = pPathExpression$1(yyStart);
    return yyColumn.chunk2.fPathExpression;
  }

  /** Actually parse xtc.xform.XForm.PathExpression. */
  private Result pPathExpression$1(final int yyStart) throws IOException {
    Result     yyResult;
    int        yyBase;
    int        yyOption1;
    Object     yyOpValue1;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative <AbsolutePath>.

    yyResult = pSymbol(yyStart);
    if (yyResult.hasValue("/")) {
      final String v$g$1 = "/";

      yyOption1  = yyResult.index;
      yyOpValue1 = null;

      yyResult = pRelativePathExpression(yyOption1);
      yyError  = yyResult.select(yyError, yyOption1);
      if (yyResult.hasValue()) {
        final Node v$el$1 = yyResult.semanticValue();

        yyOption1  = yyResult.index;
        yyOpValue1 = v$el$1;
      }
      { // Start scope for v$g$2.
        final Node v$g$2 = cast(yyOpValue1);

        yyValue = GNode.create("PathExpression", v$g$1, v$g$2);
        yyValue.setLocation(location(yyStart));

        return new SemanticValue(yyValue, yyOption1, yyError);
      } // End scope for v$g$2.
    }

    // Alternative <AllPaths>.

    yyOption1  = yyStart;
    yyOpValue1 = null;

    yyBase   = yyOption1;
    yyResult = pKeyword(yyBase);
    if (yyResult.hasValue("inside_out")) {
      final String v$el$2 = "inside_out";

      yyOption1  = yyResult.index;
      yyOpValue1 = v$el$2;
    } else {
      yyError = yyError.select("'inside_out' expected", yyBase);
    }
    { // Start scope for v$g$3.
      final String v$g$3 = cast(yyOpValue1);

      yyBase   = yyOption1;
      yyResult = pSymbol(yyBase);
      if (yyResult.hasValue("//")) {
        final String v$g$4 = "//";

        yyResult = pRelativePathExpression(yyResult.index);
        yyError  = yyResult.select(yyError);
        if (yyResult.hasValue()) {
          final Node v$g$5 = yyResult.semanticValue();

          yyValue = GNode.create("PathExpression", v$g$3, v$g$4, v$g$5);
          yyValue.setLocation(location(yyStart));

          return yyResult.createValue(yyValue, yyError);
        }
      } else {
        yyError = yyError.select("'//' expected", yyBase);
      }
    } // End scope for v$g$3.

    // Alternative <Base>.

    yyResult = pRelativePathExpression(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final Node v$g$6 = yyResult.semanticValue();

      yyValue = GNode.create("PathExpression", v$g$6);
      yyValue.setLocation(location(yyStart));

      return yyResult.createValue(yyValue, yyError);
    }

    // Done.
    yyError = yyError.select("path expression expected", yyStart);
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.RelativePathExpression.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pRelativePathExpression(final int yyStart) 
    throws IOException {

    XFormParserColumn yyColumn = (XFormParserColumn)column(yyStart);
    if (null == yyColumn.chunk2) yyColumn.chunk2 = new Chunk2();
    if (null == yyColumn.chunk2.fRelativePathExpression) 
      yyColumn.chunk2.fRelativePathExpression = pRelativePathExpression$1(yyStart);
    return yyColumn.chunk2.fRelativePathExpression;
  }

  /** Actually parse xtc.xform.XForm.RelativePathExpression. */
  private Result pRelativePathExpression$1(final int yyStart) 
    throws IOException {

    Result             yyResult;
    int                yyRepetition1;
    Pair<Action<Node>> yyRepValue1;
    Node               yyValue;
    ParseError         yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pStepExpression(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final Node v$g$4 = yyResult.semanticValue();

      yyRepetition1 = yyResult.index;
      yyRepValue1   = Pair.empty();
      while (true) {

        yyResult = pRelativePathExpression$$Tail1(yyRepetition1);
        yyError  = yyResult.select(yyError, yyRepetition1);
        if (yyResult.hasValue()) {
          final Action<Node> v$5 = yyResult.semanticValue();

          yyRepetition1 = yyResult.index;
          yyRepValue1   = new Pair<Action<Node>>(v$5, yyRepValue1);
          continue;
        }
        break;
      }
      { // Start scope for v$6.
        final Pair<Action<Node>> v$6 = yyRepValue1.reverse();

        yyValue = apply(v$6, v$g$4, yyStart);

        return new SemanticValue(yyValue, yyRepetition1, yyError);
      } // End scope for v$6.
    }

    // Done.
    return yyError;
  }

  // =========================================================================

  /**
   * Parse synthetic nonterminal 
   * xtc.xform.XForm.RelativePathExpression$$Tail1.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pRelativePathExpression$$Tail1(final int yyStart) 
    throws IOException {

    Result       yyResult;
    Action<Node> yyValue;
    ParseError   yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pRelativePathExpression$$Choice1(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final String v$g$2 = yyResult.semanticValue();

      yyResult = pStepExpression(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final Node v$g$3 = yyResult.semanticValue();

        yyValue = new Action<Node>() {
          public Node run(Node v$1) {
            return GNode.create("RelativePathExpression", v$1, v$g$2, v$g$3);
          }};

        return yyResult.createValue(yyValue, yyError);
      }
    }

    // Done.
    return yyError;
  }

  // =========================================================================

  /**
   * Parse synthetic nonterminal 
   * xtc.xform.XForm.RelativePathExpression$$Choice1.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pRelativePathExpression$$Choice1(final int yyStart) 
    throws IOException {

    Result     yyResult;
    String     yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pSymbol(yyStart);
    if (yyResult.hasValue("/")) {
      yyValue = "/";

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative 2.

    yyResult = pSymbol(yyStart);
    if (yyResult.hasValue("//")) {
      yyValue = "//";

      return yyResult.createValue(yyValue, yyError);
    }

    // Done.
    yyError = yyError.select("relative path expression expected", yyStart);
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.StepExpression.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pStepExpression(final int yyStart) throws IOException {
    XFormParserColumn yyColumn = (XFormParserColumn)column(yyStart);
    if (null == yyColumn.chunk2) yyColumn.chunk2 = new Chunk2();
    if (null == yyColumn.chunk2.fStepExpression) 
      yyColumn.chunk2.fStepExpression = pStepExpression$1(yyStart);
    return yyColumn.chunk2.fStepExpression;
  }

  /** Actually parse xtc.xform.XForm.StepExpression. */
  private Result pStepExpression$1(final int yyStart) throws IOException {
    Result     yyResult;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative <Selection>.

    yyResult = pItemTest(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final Node v$g$1 = yyResult.semanticValue();

      yyResult = pPredicateList(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final Node v$g$2 = yyResult.semanticValue();

        yyValue = GNode.create("StepExpression", v$g$1, v$g$2);
        yyValue.setLocation(location(yyStart));

        return yyResult.createValue(yyValue, yyError);
      }
    }

    // Alternative <Reverse>.

    yyResult = pReverseStep(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final Node v$g$3 = yyResult.semanticValue();

      yyValue = GNode.create("StepExpression", v$g$3);
      yyValue.setLocation(location(yyStart));

      return yyResult.createValue(yyValue, yyError);
    }

    // Done.
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.ItemTest.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pItemTest(final int yyStart) throws IOException {
    Result     yyResult;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative <PrimaryExpression>.

    yyResult = pPrimaryExpression(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      yyValue = yyResult.semanticValue();

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative <Identifier>.

    yyResult = pIdentifier(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      yyValue = yyResult.semanticValue();

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative <Wildcard>.

    yyResult = pWildcard(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      yyValue = yyResult.semanticValue();

      return yyResult.createValue(yyValue, yyError);
    }

    // Done.
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.PredicateList.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pPredicateList(final int yyStart) throws IOException {
    Result     yyResult;
    int        yyRepetition1;
    Pair<Node> yyRepValue1;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyRepetition1 = yyStart;
    yyRepValue1   = Pair.empty();
    while (true) {

      yyResult = pPredicate(yyRepetition1);
      yyError  = yyResult.select(yyError, yyRepetition1);
      if (yyResult.hasValue()) {
        final Node v$el$1 = yyResult.semanticValue();

        yyRepetition1 = yyResult.index;
        yyRepValue1   = new Pair<Node>(v$el$1, yyRepValue1);
        continue;
      }
      break;
    }
    { // Start scope for v$g$1.
      final Pair<Node> v$g$1 = yyRepValue1.reverse();

      yyValue = GNode.createFromPair("PredicateList", v$g$1);
      yyValue.setLocation(location(yyStart));

      return new SemanticValue(yyValue, yyRepetition1, yyError);
    } // End scope for v$g$1.
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.Predicate.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pPredicate(final int yyStart) throws IOException {
    Result     yyResult;
    int        yyBase;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pSymbol(yyStart);
    if (yyResult.hasValue("[")) {

      yyResult = pPredicate$$Choice1(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final Node v$g$1 = yyResult.semanticValue();

        yyBase   = yyResult.index;
        yyResult = pSymbol(yyBase);
        if (yyResult.hasValue("]")) {

          yyValue = GNode.create("Predicate", v$g$1);
          yyValue.setLocation(location(yyStart));

          return yyResult.createValue(yyValue, yyError);
        } else {
          yyError = yyError.select("']' expected", yyBase);
        }
      }
    }

    // Done.
    yyError = yyError.select("predicate expected", yyStart);
    return yyError;
  }

  // =========================================================================

  /**
   * Parse synthetic nonterminal xtc.xform.XForm.Predicate$$Choice1.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pPredicate$$Choice1(final int yyStart) throws IOException {
    Result     yyResult;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pIntegerLiteral(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      yyValue = yyResult.semanticValue();

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative 2.

    yyResult = pCompoundExpression(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      yyValue = yyResult.semanticValue();

      return yyResult.createValue(yyValue, yyError);
    }

    // Done.
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.PrimaryExpression.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pPrimaryExpression(final int yyStart) throws IOException {
    Result     yyResult;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative <ContextItem>.

    yyResult = pContextItem(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      yyValue = yyResult.semanticValue();

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative <StringLiteral>.

    yyResult = pStringLiteral(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      yyValue = yyResult.semanticValue();

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative <VarRef>.

    yyResult = pVariableReference(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      yyValue = yyResult.semanticValue();

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative <FunctionCall>.

    yyResult = pFunctionCall(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      yyValue = yyResult.semanticValue();

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative <ParenthesizedExpr>.

    yyResult = pParenthesizedExpression(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      yyValue = yyResult.semanticValue();

      return yyResult.createValue(yyValue, yyError);
    }

    // Done.
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.FunctionCall.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pFunctionCall(final int yyStart) throws IOException {
    Result     yyResult;
    int        yyBase;
    int        yyOption1;
    Node       yyOpValue1;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pIdentifier(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final Node v$g$1 = yyResult.semanticValue();

      yyBase   = yyResult.index;
      yyResult = pSymbol(yyBase);
      if (yyResult.hasValue("(")) {

        yyOption1  = yyResult.index;
        yyOpValue1 = null;

        yyResult = pArgumentList(yyOption1);
        yyError  = yyResult.select(yyError, yyOption1);
        if (yyResult.hasValue()) {
          final Node v$el$1 = yyResult.semanticValue();

          yyOption1  = yyResult.index;
          yyOpValue1 = v$el$1;
        }
        { // Start scope for v$g$2.
          final Node v$g$2 = yyOpValue1;

          yyBase   = yyOption1;
          yyResult = pSymbol(yyBase);
          if (yyResult.hasValue(")")) {

            yyValue = GNode.create("FunctionCall", v$g$1, v$g$2);
            yyValue.setLocation(location(yyStart));

            return yyResult.createValue(yyValue, yyError);
          } else {
            yyError = yyError.select("')' expected", yyBase);
          }
        } // End scope for v$g$2.
      } else {
        yyError = yyError.select("'(' expected", yyBase);
      }
    }

    // Done.
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.ArgumentList.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pArgumentList(final int yyStart) throws IOException {
    Result     yyResult;
    int        yyRepetition1;
    Pair<Node> yyRepValue1;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pArgumentList$$Choice1(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final Node v$g$1 = yyResult.semanticValue();

      yyRepetition1 = yyResult.index;
      yyRepValue1   = Pair.empty();
      while (true) {

        yyResult = pArgumentList$$Choice2(yyRepetition1);
        yyError  = yyResult.select(yyError, yyRepetition1);
        if (yyResult.hasValue()) {
          final Node v$el$4 = yyResult.semanticValue();

          yyRepetition1 = yyResult.index;
          yyRepValue1   = new Pair<Node>(v$el$4, yyRepValue1);
          continue;
        }
        break;
      }
      { // Start scope for v$g$2.
        final Pair<Node> v$g$2 = yyRepValue1.reverse();

        yyValue = GNode.createFromPair("ArgumentList", v$g$1, v$g$2);
        yyValue.setLocation(location(yyStart));

        return new SemanticValue(yyValue, yyRepetition1, yyError);
      } // End scope for v$g$2.
    }

    // Done.
    return yyError;
  }

  // =========================================================================

  /**
   * Parse synthetic nonterminal xtc.xform.XForm.ArgumentList$$Choice1.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pArgumentList$$Choice1(final int yyStart) 
    throws IOException {

    Result     yyResult;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pSingleExpression(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      yyValue = yyResult.semanticValue();

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative 2.

    yyResult = pIntegerLiteral(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      yyValue = yyResult.semanticValue();

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative 3.

    yyResult = pStringLiteral(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      yyValue = yyResult.semanticValue();

      return yyResult.createValue(yyValue, yyError);
    }

    // Done.
    return yyError;
  }

  // =========================================================================

  /**
   * Parse synthetic nonterminal xtc.xform.XForm.ArgumentList$$Choice2.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pArgumentList$$Choice2(final int yyStart) 
    throws IOException {

    Result     yyResult;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pSymbol(yyStart);
    if (yyResult.hasValue(",")) {

      final int yyChoice1 = yyResult.index;

      // Nested alternative 1.

      yyResult = pSingleExpression(yyChoice1);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        yyValue = yyResult.semanticValue();

        return yyResult.createValue(yyValue, yyError);
      }

      // Nested alternative 2.

      yyResult = pIntegerLiteral(yyChoice1);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        yyValue = yyResult.semanticValue();

        return yyResult.createValue(yyValue, yyError);
      }

      // Nested alternative 3.

      yyResult = pStringLiteral(yyChoice1);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        yyValue = yyResult.semanticValue();

        return yyResult.createValue(yyValue, yyError);
      }
    }

    // Done.
    yyError = yyError.select("argument list expected", yyStart);
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.ParenthesizedExpression.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pParenthesizedExpression(final int yyStart) 
    throws IOException {

    Result     yyResult;
    int        yyBase;
    int        yyOption1;
    Node       yyOpValue1;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pSymbol(yyStart);
    if (yyResult.hasValue("(")) {

      yyOption1  = yyResult.index;
      yyOpValue1 = null;

      yyResult = pCompoundExpression(yyOption1);
      yyError  = yyResult.select(yyError, yyOption1);
      if (yyResult.hasValue()) {
        final Node v$el$1 = yyResult.semanticValue();

        yyOption1  = yyResult.index;
        yyOpValue1 = v$el$1;
      }
      { // Start scope for v$g$1.
        final Node v$g$1 = yyOpValue1;

        yyBase   = yyOption1;
        yyResult = pSymbol(yyBase);
        if (yyResult.hasValue(")")) {

          yyValue = GNode.create("ParenthesizedExpression", v$g$1);
          yyValue.setLocation(location(yyStart));

          return yyResult.createValue(yyValue, yyError);
        } else {
          yyError = yyError.select("')' expected", yyBase);
        }
      } // End scope for v$g$1.
    }

    // Done.
    yyError = yyError.select("parenthesized expression expected", yyStart);
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.VariableReference.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pVariableReference(final int yyStart) throws IOException {
    XFormParserColumn yyColumn = (XFormParserColumn)column(yyStart);
    if (null == yyColumn.chunk2) yyColumn.chunk2 = new Chunk2();
    if (null == yyColumn.chunk2.fVariableReference) 
      yyColumn.chunk2.fVariableReference = pVariableReference$1(yyStart);
    return yyColumn.chunk2.fVariableReference;
  }

  /** Actually parse xtc.xform.XForm.VariableReference. */
  private Result pVariableReference$1(final int yyStart) throws IOException {
    Result     yyResult;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pSymbol(yyStart);
    if (yyResult.hasValue("$")) {

      yyResult = pWord(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final String w = yyResult.semanticValue();

        if (! contains(XFORM_KEYWORDS, w)) {

          yyResult = pSpacing(yyResult.index);
          yyError  = yyResult.select(yyError);
          if (yyResult.hasValue()) {

            yyValue = GNode.create("VariableReference", w);
            yyValue.setLocation(location(yyStart));

            return yyResult.createValue(yyValue, yyError);
          }
        }
      }
    }

    // Done.
    yyError = yyError.select("variable reference expected", yyStart);
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.Identifier.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pIdentifier(final int yyStart) throws IOException {
    XFormParserColumn yyColumn = (XFormParserColumn)column(yyStart);
    if (null == yyColumn.chunk2) yyColumn.chunk2 = new Chunk2();
    if (null == yyColumn.chunk2.fIdentifier) 
      yyColumn.chunk2.fIdentifier = pIdentifier$1(yyStart);
    return yyColumn.chunk2.fIdentifier;
  }

  /** Actually parse xtc.xform.XForm.Identifier. */
  private Result pIdentifier$1(final int yyStart) throws IOException {
    Result     yyResult;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pWord(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final String v$g$1 = yyResult.semanticValue();

      yyResult = pSpacing(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {

        yyValue = GNode.create("Identifier", v$g$1);
        yyValue.setLocation(location(yyStart));

        return yyResult.createValue(yyValue, yyError);
      }
    }

    // Done.
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.Word.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pWord(final int yyStart) throws IOException {
    XFormParserColumn yyColumn = (XFormParserColumn)column(yyStart);
    if (null == yyColumn.chunk2) yyColumn.chunk2 = new Chunk2();
    if (null == yyColumn.chunk2.fWord) 
      yyColumn.chunk2.fWord = pWord$1(yyStart);
    return yyColumn.chunk2.fWord;
  }

  /** Actually parse xtc.xform.XForm.Word. */
  private Result pWord$1(final int yyStart) throws IOException {
    int        yyC;
    int        yyIndex;
    Result     yyResult;
    String     yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyC = character(yyStart);
    if (-1 != yyC) {
      yyIndex = yyStart + 1;
      if ((('A' <= yyC) && (yyC <= 'Z')) ||
          ('_' == yyC) ||
          (('a' <= yyC) && (yyC <= 'z'))) {

        yyResult = pWord$$Star1(yyIndex);
        yyError  = yyResult.select(yyError);
        if (yyResult.hasValue()) {

          yyValue = difference(yyStart, yyResult.index);

          return yyResult.createValue(yyValue, yyError);
        }
      }
    }

    // Done.
    yyError = yyError.select("word expected", yyStart);
    return yyError;
  }

  // =========================================================================

  /**
   * Parse synthetic nonterminal xtc.xform.XForm.Word$$Star1.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pWord$$Star1(final int yyStart) throws IOException {
    XFormParserColumn yyColumn = (XFormParserColumn)column(yyStart);
    if (null == yyColumn.chunk2) yyColumn.chunk2 = new Chunk2();
    if (null == yyColumn.chunk2.fWord$$Star1) 
      yyColumn.chunk2.fWord$$Star1 = pWord$$Star1$1(yyStart);
    return yyColumn.chunk2.fWord$$Star1;
  }

  /** Actually parse xtc.xform.XForm.Word$$Star1. */
  private Result pWord$$Star1$1(final int yyStart) throws IOException {
    int        yyC;
    int        yyIndex;
    Result     yyResult;
    Void       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyC = character(yyStart);
    if (-1 != yyC) {
      yyIndex = yyStart + 1;
      if ((('0' <= yyC) && (yyC <= '9')) ||
          (('A' <= yyC) && (yyC <= 'Z')) ||
          ('_' == yyC) ||
          (('a' <= yyC) && (yyC <= 'z'))) {

        yyResult = pWord$$Star1(yyIndex);
        yyError  = yyResult.select(yyError);
        if (yyResult.hasValue()) {

          yyValue = null;

          return yyResult.createValue(yyValue, yyError);
        }
      }
    }

    // Alternative 2.

    yyValue = null;

    return new SemanticValue(yyValue, yyStart, yyError);
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.Keyword.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pKeyword(final int yyStart) throws IOException {
    XFormParserColumn yyColumn = (XFormParserColumn)column(yyStart);
    if (null == yyColumn.chunk2) yyColumn.chunk2 = new Chunk2();
    if (null == yyColumn.chunk2.fKeyword) 
      yyColumn.chunk2.fKeyword = pKeyword$1(yyStart);
    return yyColumn.chunk2.fKeyword;
  }

  /** Actually parse xtc.xform.XForm.Keyword. */
  private Result pKeyword$1(final int yyStart) throws IOException {
    Result     yyResult;
    String     yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pWord(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      yyValue = yyResult.semanticValue();

      if (contains(XFORM_KEYWORDS, yyValue)) {

        yyResult = pSpacing(yyResult.index);
        yyError  = yyResult.select(yyError);
        if (yyResult.hasValue()) {

          return yyResult.createValue(yyValue, yyError);
        }
      }
    }

    // Done.
    yyError = yyError.select("keyword expected", yyStart);
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.StringLiteral.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pStringLiteral(final int yyStart) throws IOException {
    XFormParserColumn yyColumn = (XFormParserColumn)column(yyStart);
    if (null == yyColumn.chunk2) yyColumn.chunk2 = new Chunk2();
    if (null == yyColumn.chunk2.fStringLiteral) 
      yyColumn.chunk2.fStringLiteral = pStringLiteral$1(yyStart);
    return yyColumn.chunk2.fStringLiteral;
  }

  /** Actually parse xtc.xform.XForm.StringLiteral. */
  private Result pStringLiteral$1(final int yyStart) throws IOException {
    Result     yyResult;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pQuotedString(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final String v$g$1 = yyResult.semanticValue();

      yyResult = pSpacing(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {

        yyValue = GNode.create("StringLiteral", v$g$1);
        yyValue.setLocation(location(yyStart));

        return yyResult.createValue(yyValue, yyError);
      }
    }

    // Done.
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.IntegerLiteral.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pIntegerLiteral(final int yyStart) throws IOException {
    XFormParserColumn yyColumn = (XFormParserColumn)column(yyStart);
    if (null == yyColumn.chunk3) yyColumn.chunk3 = new Chunk3();
    if (null == yyColumn.chunk3.fIntegerLiteral) 
      yyColumn.chunk3.fIntegerLiteral = pIntegerLiteral$1(yyStart);
    return yyColumn.chunk3.fIntegerLiteral;
  }

  /** Actually parse xtc.xform.XForm.IntegerLiteral. */
  private Result pIntegerLiteral$1(final int yyStart) throws IOException {
    Result     yyResult;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pDecimalLiteral(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final String v$g$1 = yyResult.semanticValue();

      yyResult = pSpacing(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {

        yyValue = GNode.create("IntegerLiteral", v$g$1);
        yyValue.setLocation(location(yyStart));

        return yyResult.createValue(yyValue, yyError);
      }
    }

    // Done.
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.QuotedString.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pQuotedString(final int yyStart) throws IOException {
    int        yyC;
    int        yyIndex;
    int        yyRepetition1;
    String     yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyC = character(yyStart);
    if ('\"' == yyC) {
      yyIndex = yyStart + 1;

      yyRepetition1 = yyIndex;
      while (true) {

        yyC = character(yyRepetition1);
        if (-1 != yyC) {
          yyIndex = yyRepetition1 + 1;

          switch (yyC) {
          case '\n':
          case '\r':
          case '\"':
          case '\\':
            /* No match. */
            break;

          default:
            {
              yyRepetition1 = yyIndex;
              continue;
            }
          }
        }
        break;
      }

      yyC = character(yyRepetition1);
      if ('\"' == yyC) {
        yyIndex = yyRepetition1 + 1;

        yyValue = difference(yyStart, yyIndex);

        return new SemanticValue(yyValue, yyIndex, yyError);
      }
    }

    // Done.
    yyError = yyError.select("quoted string expected", yyStart);
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.DecimalLiteral.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pDecimalLiteral(final int yyStart) throws IOException {
    int        yyC;
    int        yyIndex;
    int        yyRepetition1;
    String     yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyC = character(yyStart);
    if (-1 != yyC) {
      yyIndex = yyStart + 1;

      switch (yyC) {
      case '0':
      case '1':
      case '2':
      case '3':
      case '4':
      case '5':
      case '6':
      case '7':
      case '8':
      case '9':
        {
          yyRepetition1 = yyIndex;
          while (true) {

            yyC = character(yyRepetition1);
            if (-1 != yyC) {
              yyIndex = yyRepetition1 + 1;

              switch (yyC) {
              case '0':
              case '1':
              case '2':
              case '3':
              case '4':
              case '5':
              case '6':
              case '7':
              case '8':
              case '9':
                {
                  yyRepetition1 = yyIndex;
                  continue;
                }

              default:
                /* No match. */
              }
            }
            break;
          }

          yyValue = difference(yyStart, yyRepetition1);

          return new SemanticValue(yyValue, yyRepetition1, yyError);
        }

      default:
        /* No match. */
      }
    }

    // Done.
    yyError = yyError.select("decimal literal expected", yyStart);
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.ContextItem.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pContextItem(final int yyStart) throws IOException {
    Result     yyResult;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pSymbol(yyStart);
    if (yyResult.hasValue(".")) {

      yyValue = GNode.create("ContextItem", false);
      yyValue.setLocation(location(yyStart));

      return yyResult.createValue(yyValue, yyError);
    }

    // Done.
    yyError = yyError.select("context item expected", yyStart);
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.ReverseStep.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pReverseStep(final int yyStart) throws IOException {
    Result     yyResult;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pSymbol(yyStart);
    if (yyResult.hasValue("..")) {

      yyValue = GNode.create("ReverseStep", false);
      yyValue.setLocation(location(yyStart));

      return yyResult.createValue(yyValue, yyError);
    }

    // Done.
    yyError = yyError.select("reverse step expected", yyStart);
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.Null.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pNull(final int yyStart) throws IOException {
    XFormParserColumn yyColumn = (XFormParserColumn)column(yyStart);
    if (null == yyColumn.chunk3) yyColumn.chunk3 = new Chunk3();
    if (null == yyColumn.chunk3.fNull) 
      yyColumn.chunk3.fNull = pNull$1(yyStart);
    return yyColumn.chunk3.fNull;
  }

  /** Actually parse xtc.xform.XForm.Null. */
  private Result pNull$1(final int yyStart) throws IOException {
    Result     yyResult;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pKeyword(yyStart);
    if (yyResult.hasValue("null")) {

      yyValue = GNode.create("Null", false);
      yyValue.setLocation(location(yyStart));

      return yyResult.createValue(yyValue, yyError);
    }

    // Done.
    yyError = yyError.select("null expected", yyStart);
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.Wildcard.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pWildcard(final int yyStart) throws IOException {
    Result     yyResult;
    Node       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pSymbol(yyStart);
    if (yyResult.hasValue("*")) {

      yyValue = GNode.create("Wildcard", false);
      yyValue.setLocation(location(yyStart));

      return yyResult.createValue(yyValue, yyError);
    }

    // Done.
    yyError = yyError.select("wildcard expected", yyStart);
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.Symbol.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pSymbol(final int yyStart) throws IOException {
    XFormParserColumn yyColumn = (XFormParserColumn)column(yyStart);
    if (null == yyColumn.chunk3) yyColumn.chunk3 = new Chunk3();
    if (null == yyColumn.chunk3.fSymbol) 
      yyColumn.chunk3.fSymbol = pSymbol$1(yyStart);
    return yyColumn.chunk3.fSymbol;
  }

  /** Actually parse xtc.xform.XForm.Symbol. */
  private Result pSymbol$1(final int yyStart) throws IOException {
    Result     yyResult;
    String     yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pSymbolCharacters(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      yyValue = yyResult.semanticValue();

      yyResult = pSpacing(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {

        return yyResult.createValue(yyValue, yyError);
      }
    }

    // Done.
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.SymbolCharacters.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pSymbolCharacters(final int yyStart) throws IOException {
    int        yyC;
    int        yyIndex;
    String     yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyC = character(yyStart);
    if (-1 != yyC) {
      yyIndex = yyStart + 1;

      switch (yyC) {
      case '/':
        {
          final int yyChoice1 = yyIndex;

          // Nested alternative 1.

          yyC = character(yyChoice1);
          if (-1 != yyC) {
            yyIndex = yyChoice1 + 1;
            if ('/' == yyC) {

              yyValue = "//";

              return new SemanticValue(yyValue, yyIndex, yyError);
            }
          }

          // Nested alternative 2.

          yyValue = "/";

          return new SemanticValue(yyValue, yyChoice1, yyError);
        }

      case '.':
        {
          final int yyChoice1 = yyIndex;

          // Nested alternative 1.

          yyC = character(yyChoice1);
          if (-1 != yyC) {
            yyIndex = yyChoice1 + 1;
            if ('.' == yyC) {

              yyValue = "..";

              return new SemanticValue(yyValue, yyIndex, yyError);
            }
          }

          // Nested alternative 2.

          yyValue = ".";

          return new SemanticValue(yyValue, yyChoice1, yyError);
        }

      case '(':
        {
          yyValue = "(";

          return new SemanticValue(yyValue, yyIndex, yyError);
        }

      case ')':
        {
          yyValue = ")";

          return new SemanticValue(yyValue, yyIndex, yyError);
        }

      case '[':
        {
          yyValue = "[";

          return new SemanticValue(yyValue, yyIndex, yyError);
        }

      case ']':
        {
          yyValue = "]";

          return new SemanticValue(yyValue, yyIndex, yyError);
        }

      case '#':
        {
          yyValue = "#";

          return new SemanticValue(yyValue, yyIndex, yyError);
        }

      case '<':
        {
          yyValue = "<";

          return new SemanticValue(yyValue, yyIndex, yyError);
        }

      case '>':
        {
          yyValue = ">";

          return new SemanticValue(yyValue, yyIndex, yyError);
        }

      case '!':
        {
          yyValue = "!";

          return new SemanticValue(yyValue, yyIndex, yyError);
        }

      case '$':
        {
          yyValue = "$";

          return new SemanticValue(yyValue, yyIndex, yyError);
        }

      case ',':
        {
          yyValue = ",";

          return new SemanticValue(yyValue, yyIndex, yyError);
        }

      case '*':
        {
          yyValue = "*";

          return new SemanticValue(yyValue, yyIndex, yyError);
        }

      case '+':
        {
          yyValue = "+";

          return new SemanticValue(yyValue, yyIndex, yyError);
        }

      case '=':
        {
          yyValue = "=";

          return new SemanticValue(yyValue, yyIndex, yyError);
        }

      default:
        /* No match. */
      }
    }

    // Done.
    yyError = yyError.select("symbol characters expected", yyStart);
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.Spacing.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pSpacing(final int yyStart) throws IOException {
    int        yyC;
    int        yyIndex;
    Result     yyPredResult;
    int        yyRepetition1;
    int        yyRepetition2;
    Void       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyRepetition1 = yyStart;
    while (true) {

      final int yyChoice1 = yyRepetition1;

      // Nested alternative 1.

      yyC = character(yyChoice1);
      if (-1 != yyC) {
        yyIndex = yyChoice1 + 1;

        switch (yyC) {
        case ' ':
          {
            yyRepetition1 = yyIndex;
            continue;
          }

        case '\t':
          {
            yyRepetition1 = yyIndex;
            continue;
          }

        case '\f':
          {
            yyRepetition1 = yyIndex;
            continue;
          }

        case '#':
          {
            yyRepetition2 = yyIndex;
            while (true) {

              yyC = character(yyRepetition2);
              if (-1 != yyC) {
                yyIndex = yyRepetition2 + 1;

                switch (yyC) {
                case '\n':
                case '\r':
                  /* No match. */
                  break;

                default:
                  {
                    yyRepetition2 = yyIndex;
                    continue;
                  }
                }
              }
              break;
            }

            yyPredResult = pComment$$Choice1(yyRepetition2);
            yyError      = yyPredResult.select(yyError);
            if (yyPredResult.hasValue()) {

              yyRepetition1 = yyRepetition2;
              continue;
            }
          }
          break;

        case '\r':
          {
            final int yyChoice2 = yyIndex;

            // Nested alternative 1.

            yyC = character(yyChoice2);
            if ('\n' == yyC) {
              yyIndex = yyChoice2 + 1;

              yyRepetition1 = yyIndex;
              continue;
            }

            // Nested alternative 2.

            yyRepetition1 = yyChoice2;
            continue;
          }

        case '\n':
          {
            yyRepetition1 = yyIndex;
            continue;
          }

        default:
          /* No match. */
        }
      }
      break;
    }

    yyValue = null;

    return new SemanticValue(yyValue, yyRepetition1, yyError);
  }

  // =========================================================================

  /**
   * Parse synthetic nonterminal xtc.xform.XForm.Comment$$Choice1.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pComment$$Choice1(final int yyStart) throws IOException {
    int        yyC;
    int        yyIndex;
    boolean    yyPredMatched;
    Void       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyC = character(yyStart);
    if (-1 != yyC) {
      yyIndex = yyStart + 1;

      switch (yyC) {
      case '\r':
        {
          final int yyChoice1 = yyIndex;

          // Nested alternative 1.

          yyC = character(yyChoice1);
          if ('\n' == yyC) {
            yyIndex = yyChoice1 + 1;

            yyValue = null;

            return new SemanticValue(yyValue, yyIndex, yyError);
          }

          // Nested alternative 2.

          yyValue = null;

          return new SemanticValue(yyValue, yyChoice1, yyError);
        }

      case '\n':
        {
          yyValue = null;

          return new SemanticValue(yyValue, yyIndex, yyError);
        }

      default:
        /* No match. */
      }
    }

    // Alternative 2.

    yyPredMatched = false;

    yyC = character(yyStart);
    if (-1 != yyC) {

      yyPredMatched = true;
    }

    if (! yyPredMatched) {

      yyValue = null;

      return new SemanticValue(yyValue, yyStart, yyError);
    } else {
      yyError = yyError.select("comment expected", yyStart);
    }

    // Done.
    yyError = yyError.select("comment expected", yyStart);
    return yyError;
  }

  // =========================================================================

  /**
   * Parse nonterminal xtc.xform.XForm.EndOfFile.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pEndOfFile(final int yyStart) throws IOException {
    int        yyC;
    boolean    yyPredMatched;
    Void       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyPredMatched = false;

    yyC = character(yyStart);
    if (-1 != yyC) {

      yyPredMatched = true;
    }

    if (! yyPredMatched) {

      yyValue = null;

      return new SemanticValue(yyValue, yyStart, yyError);
    } else {
      yyError = yyError.select("end of file expected", yyStart);
    }

    // Done.
    return yyError;
  }

  // =========================================================================

  static {
    add(XFORM_KEYWORDS, new String[] {
      "add", "after", "and", "be", "before", "cfor", "differ",
      "else", "for", "if", "import", "in", "insert",
      "inside_out", "intersect", "let", "null", "or",
      "remove", "replace", "return", "then", "to", "union",
      "with" });
  }

  // =========================================================================

  /**
   * Get the specified text.
   *
   * @param s The text.
   * @return The text.
   */
  protected static final String toText(String s) {
    return s;
  }

  // =========================================================================

  /**
   * Add the specified values to the specified set.
   *
   * @param set The set.
   * @param values The new values.
   */
  protected static final <T> void add(Set<T> set, T[] values) {
    for (T v : values) set.add(v);
  }

  /**
   * Check whether the specified set contains the specified value.
   *
   * @param set The set.
   * @param value The value.
   * @return <code>true</code> if the set contains the value.
   */
  protected static final <T> boolean contains(Set<T> set, T value) {
    return set.contains(value);
  }

}
