// ===========================================================================
// This file has been generated by
// Rats! Parser Generator, version 1.14.3,
// (C) 2004-2008 Robert Grimm,
// on Thursday, November 6, 2008 at 12:39:26 PM.
// Edit at your own risk.
// ===========================================================================

package xtc.parser;

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

import xtc.util.Pair;

import xtc.tree.Locatable;

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

import java.util.ArrayList;
import java.util.List;

import xtc.Constants;

import xtc.tree.Attribute;
import xtc.tree.Comment;

import xtc.util.Utilities;

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

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

  /** Chunk 1 of memoized results. */
  static final class Chunk1 {
    Result fModuleList;
    Result fModuleList$$Star1;
    Result fModuleTarget;
    Result fModuleName;
    Result fProductionAttributes;
    Result fChoice;
    Result fChoice$$Star1;
    Result fSequence;
    Result fSequence$$Star1;
    Result fSequenceName;
  }

  /** Chunk 2 of memoized results. */
  static final class Chunk2 {
    Result fVoided;
    Result fSuffix;
    Result fPrimary;
    Result fUnqualifiedNonTerminal;
    Result fAction;
    Result fAttribute;
    Result fTypeName;
    Result fTypeNameCharacters;
    Result fTypeNameCharacters$$Star1;
    Result fName;
  }

  /** Chunk 3 of memoized results. */
  static final class Chunk3 {
    Result fWord;
    Result fNameCharacters;
    Result fNameCharacters$$Star1;
    Result fWordCharacters;
    Result fWordCharacters$$Plus1;
    Result fWordCharacters$$Star1;
    Result fCharacterLiteral;
    Result fStringLiteral;
    Result fStringLiteral$$Star1;
    Result fClassChar;
  }

  /** Chunk 4 of memoized results. */
  static final class Chunk4 {
    Result fSymbol;
  }

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

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

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

  /** The global state object. */
  protected final PParserState yyState;

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

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

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

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

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

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.Module.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  public Result pModule(final int yyStart) throws IOException {
    Result       yyResult;
    int          yyBase;
    int          yyRepetition1;
    Pair<Object> yyRepValue1;
    int          yyOption1;
    Object       yyOpValue1;
    Module       yyValue;
    ParseError   yyError = ParseError.DUMMY;

    // Reset the global state object.
    yyState.reset(column(yyStart).file);

    // Alternative 1.

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

      yyOption1  = yyResult.index;
      yyOpValue1 = null;

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

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

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

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

            yyResult = pModuleName(yyResult.index);
            yyError  = yyResult.select(yyError);
            if (yyResult.hasValue()) {
              final ModuleName name = yyResult.semanticValue();

              yyOption1  = yyResult.index;
              yyOpValue1 = null;

              yyResult = pModuleList(yyOption1);
              yyError  = yyResult.select(yyError, yyOption1);
              if (yyResult.hasValue()) {
                final ModuleList v$el$2 = yyResult.semanticValue();

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

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

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

                    yyResult = pModuleDependency(yyRepetition1);
                    yyError  = yyResult.select(yyError, yyRepetition1);
                    if (yyResult.hasValue()) {
                      final ModuleDependency v$el$3 = yyResult.semanticValue();

                      yyRepetition1 = yyResult.index;
                      yyRepValue1   = new Pair<Object>(v$el$3, yyRepValue1);
                      continue;
                    }
                    break;
                  }
                  { // Start scope for deps.
                    final Pair<ModuleDependency> deps = cast(yyRepValue1.reverse());

                    yyOption1  = yyRepetition1;
                    yyOpValue1 = null;

                    yyResult = pHeader(yyOption1);
                    yyError  = yyResult.select(yyError, yyOption1);
                    if (yyResult.hasValue()) {
                      final Action v$el$4 = yyResult.semanticValue();

                      yyOption1  = yyResult.index;
                      yyOpValue1 = v$el$4;
                    }
                    { // Start scope for header.
                      final Action header = cast(yyOpValue1);

                      yyOpValue1 = null;

                      yyResult = pBody(yyOption1);
                      yyError  = yyResult.select(yyError, yyOption1);
                      if (yyResult.hasValue()) {
                        final Action v$el$5 = yyResult.semanticValue();

                        yyOption1  = yyResult.index;
                        yyOpValue1 = v$el$5;
                      }
                      { // Start scope for body.
                        final Action body = cast(yyOpValue1);

                        yyOpValue1 = null;

                        yyResult = pFooter(yyOption1);
                        yyError  = yyResult.select(yyError, yyOption1);
                        if (yyResult.hasValue()) {
                          final Action v$el$6 = yyResult.semanticValue();

                          yyOption1  = yyResult.index;
                          yyOpValue1 = v$el$6;
                        }
                        { // Start scope for footer.
                          final Action footer = cast(yyOpValue1);

                          yyOpValue1 = null;

                          yyResult = pOptions(yyOption1);
                          yyError  = yyResult.select(yyError, yyOption1);
                          if (yyResult.hasValue()) {
                            final List<Attribute> v$el$7 = yyResult.semanticValue();

                            yyOption1  = yyResult.index;
                            yyOpValue1 = v$el$7;
                          }
                          { // Start scope for options.
                            final List<Attribute> options = cast(yyOpValue1);

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

                              yyResult = pProduction(yyRepetition1);
                              yyError  = 
                                yyResult.select(yyError, yyRepetition1);
                              if (yyResult.hasValue()) {
                                final Production v$el$8 = yyResult.semanticValue();

                                yyRepetition1 = yyResult.index;
                                yyRepValue1   = 
                                  new Pair<Object>(v$el$8, yyRepValue1);
                                continue;
                              }
                              break;
                            }
                            { // Start scope for productions.
                              final Pair<Production> productions = cast(yyRepValue1.reverse());

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

                                yyValue = new Module(Comment.documentation(documentation), name,
                                params, deps.list(), header, body, footer,
                                options, productions.list());

                                setLocation(yyValue, yyStart);
                                return yyResult.createValue(yyValue, yyError);
                              }
                            } // End scope for productions.
                          } // End scope for options.
                        } // End scope for footer.
                      } // End scope for body.
                    } // End scope for header.
                  } // End scope for deps.
                } else {
                  yyError = yyError.select("';' expected", yyBase);
                }
              } // End scope for params.
            }
          } else {
            yyError = yyError.select("'module' expected", yyBase);
          }
        }
      } // End scope for documentation.
    }

    // Done.
    return yyError;
  }

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.ModuleDependency.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pModuleDependency(final int yyStart) throws IOException {
    Result           yyResult;
    ModuleDependency yyValue;
    ParseError       yyError = ParseError.DUMMY;

    // Alternative <Modification>.

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

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative <Instantiation>.

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

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative <Import>.

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

      return yyResult.createValue(yyValue, yyError);
    }

    // Done.
    return yyError;
  }

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.ModuleModification.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pModuleModification(final int yyStart) throws IOException {
    Result             yyResult;
    int                yyBase;
    int                yyOption1;
    Object             yyOpValue1;
    ModuleModification yyValue;
    ParseError         yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pWord(yyStart);
    if (yyResult.hasValue("modify")) {

      yyResult = pModuleName(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final ModuleName name = yyResult.semanticValue();

        yyOption1  = yyResult.index;
        yyOpValue1 = null;

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

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

          yyOpValue1 = null;

          yyResult = pModuleTarget(yyOption1);
          yyError  = yyResult.select(yyError, yyOption1);
          if (yyResult.hasValue()) {
            final ModuleName v$el$2 = yyResult.semanticValue();

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

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

              yyValue =
              new ModuleModification(name, args, target);

              setLocation(yyValue, yyStart);
              return yyResult.createValue(yyValue, yyError);
            } else {
              yyError = yyError.select("';' expected", yyBase);
            }
          } // End scope for target.
        } // End scope for args.
      }
    }

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

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.ModuleInstantiation.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pModuleInstantiation(final int yyStart) throws IOException {
    Result              yyResult;
    int                 yyBase;
    int                 yyOption1;
    Object              yyOpValue1;
    ModuleInstantiation yyValue;
    ParseError          yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pWord(yyStart);
    if (yyResult.hasValue("instantiate")) {

      yyResult = pModuleName(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final ModuleName name = yyResult.semanticValue();

        yyOption1  = yyResult.index;
        yyOpValue1 = null;

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

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

          yyOpValue1 = null;

          yyResult = pModuleTarget(yyOption1);
          yyError  = yyResult.select(yyError, yyOption1);
          if (yyResult.hasValue()) {
            final ModuleName v$el$2 = yyResult.semanticValue();

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

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

              yyValue =
              new ModuleInstantiation(name, args, target);

              setLocation(yyValue, yyStart);
              return yyResult.createValue(yyValue, yyError);
            } else {
              yyError = yyError.select("';' expected", yyBase);
            }
          } // End scope for target.
        } // End scope for args.
      }
    }

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

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.ModuleImport.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pModuleImport(final int yyStart) throws IOException {
    Result       yyResult;
    int          yyBase;
    int          yyOption1;
    Object       yyOpValue1;
    ModuleImport yyValue;
    ParseError   yyError = ParseError.DUMMY;

    // Alternative 1.

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

      yyResult = pModuleName(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final ModuleName name = yyResult.semanticValue();

        yyOption1  = yyResult.index;
        yyOpValue1 = null;

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

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

          yyOpValue1 = null;

          yyResult = pModuleTarget(yyOption1);
          yyError  = yyResult.select(yyError, yyOption1);
          if (yyResult.hasValue()) {
            final ModuleName v$el$2 = yyResult.semanticValue();

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

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

              yyValue = new ModuleImport(name, args, target);

              setLocation(yyValue, yyStart);
              return yyResult.createValue(yyValue, yyError);
            } else {
              yyError = yyError.select("';' expected", yyBase);
            }
          } // End scope for target.
        } // End scope for args.
      }
    }

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

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.ModuleList.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pModuleList(final int yyStart) throws IOException {
    PParserColumn yyColumn = (PParserColumn)column(yyStart);
    if (null == yyColumn.chunk1) yyColumn.chunk1 = new Chunk1();
    if (null == yyColumn.chunk1.fModuleList) 
      yyColumn.chunk1.fModuleList = pModuleList$1(yyStart);
    return yyColumn.chunk1.fModuleList;
  }

  /** Actually parse xtc.parser.PGrammar.ModuleList. */
  private Result pModuleList$1(final int yyStart) throws IOException {
    Result     yyResult;
    int        yyBase;
    ModuleList yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

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

      final int yyChoice1 = yyResult.index;

      // Nested alternative 1.

      yyResult = pModuleName(yyChoice1);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final ModuleName name = yyResult.semanticValue();

        yyResult = pModuleList$$Star1(yyResult.index);
        yyError  = yyResult.select(yyError);
        if (yyResult.hasValue()) {
          final Pair<ModuleName> names = yyResult.semanticValue();

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

            yyValue = new ModuleList(new Pair<ModuleName>(name, names).list());

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

      // Nested alternative 2.

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

        yyValue = new ModuleList(new ArrayList<ModuleName>(0));

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

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

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

  /**
   * Parse synthetic nonterminal xtc.parser.PGrammar.ModuleList$$Star1.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pModuleList$$Star1(final int yyStart) throws IOException {
    PParserColumn yyColumn = (PParserColumn)column(yyStart);
    if (null == yyColumn.chunk1) yyColumn.chunk1 = new Chunk1();
    if (null == yyColumn.chunk1.fModuleList$$Star1) 
      yyColumn.chunk1.fModuleList$$Star1 = pModuleList$$Star1$1(yyStart);
    return yyColumn.chunk1.fModuleList$$Star1;
  }

  /** Actually parse xtc.parser.PGrammar.ModuleList$$Star1. */
  private Result pModuleList$$Star1$1(final int yyStart) throws IOException {
    Result           yyResult;
    Pair<ModuleName> yyValue;
    ParseError       yyError = ParseError.DUMMY;

    // Alternative 1.

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

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

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

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

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

    // Alternative 2.

    yyValue = Pair.empty();

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

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.ModuleTarget.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pModuleTarget(final int yyStart) throws IOException {
    PParserColumn yyColumn = (PParserColumn)column(yyStart);
    if (null == yyColumn.chunk1) yyColumn.chunk1 = new Chunk1();
    if (null == yyColumn.chunk1.fModuleTarget) 
      yyColumn.chunk1.fModuleTarget = pModuleTarget$1(yyStart);
    return yyColumn.chunk1.fModuleTarget;
  }

  /** Actually parse xtc.parser.PGrammar.ModuleTarget. */
  private Result pModuleTarget$1(final int yyStart) throws IOException {
    Result     yyResult;
    ModuleName yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pWord(yyStart);
    if (yyResult.hasValue("as")) {

      yyResult = pModuleName(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        yyValue = yyResult.semanticValue();

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

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

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.ModuleName.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pModuleName(final int yyStart) throws IOException {
    PParserColumn yyColumn = (PParserColumn)column(yyStart);
    if (null == yyColumn.chunk1) yyColumn.chunk1 = new Chunk1();
    if (null == yyColumn.chunk1.fModuleName) 
      yyColumn.chunk1.fModuleName = pModuleName$1(yyStart);
    return yyColumn.chunk1.fModuleName;
  }

  /** Actually parse xtc.parser.PGrammar.ModuleName. */
  private Result pModuleName$1(final int yyStart) throws IOException {
    Result     yyResult;
    ModuleName yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pName(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final String name = yyResult.semanticValue();

      yyValue = new ModuleName(name);

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

    // Done.
    return yyError;
  }

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.Header.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pHeader(final int yyStart) throws IOException {
    Result     yyResult;
    Action     yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pWord(yyStart);
    if (yyResult.hasValue("header")) {

      yyResult = pAction(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        yyValue = yyResult.semanticValue();

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

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

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.Body.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pBody(final int yyStart) throws IOException {
    Result     yyResult;
    Action     yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pWord(yyStart);
    if (yyResult.hasValue("body")) {

      yyResult = pAction(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        yyValue = yyResult.semanticValue();

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

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

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.Footer.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pFooter(final int yyStart) throws IOException {
    Result     yyResult;
    Action     yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pWord(yyStart);
    if (yyResult.hasValue("footer")) {

      yyResult = pAction(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        yyValue = yyResult.semanticValue();

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

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

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.Options.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pOptions(final int yyStart) throws IOException {
    Result          yyResult;
    int             yyBase;
    int             yyRepetition1;
    Pair<Attribute> yyRepValue1;
    List<Attribute> yyValue;
    ParseError      yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pWord(yyStart);
    if (yyResult.hasValue("option")) {

      yyResult = pAttribute(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final Attribute att = yyResult.semanticValue();

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

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

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

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

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

            yyValue = new ArrayList<Attribute>(atts.size() + 1);
            new Pair<Attribute>(att, atts).addTo(yyValue);

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

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

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.Production.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pProduction(final int yyStart) throws IOException {
    Result     yyResult;
    Production yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative <Full>.

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

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative <Addition>.

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

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative <Removal>.

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

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative <Override>.

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

      return yyResult.createValue(yyValue, yyError);
    }

    // Done.
    return yyError;
  }

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.FullProduction.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pFullProduction(final int yyStart) throws IOException {
    Result         yyResult;
    int            yyBase;
    FullProduction yyValue;
    ParseError     yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pProductionAttributes(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final Pair<Attribute> attributes = yyResult.semanticValue();

      yyResult = pTypeName(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final String type = yyResult.semanticValue();

        yyResult = pUnqualifiedNonTerminal(yyResult.index);
        yyError  = yyResult.select(yyError);
        if (yyResult.hasValue()) {
          final NonTerminal nt = yyResult.semanticValue();

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

            yyResult = pChoice(yyResult.index);
            yyError  = yyResult.select(yyError);
            if (yyResult.hasValue()) {
              final OrderedChoice choice = yyResult.semanticValue();

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

                List<Attribute> list = new ArrayList<Attribute>(attributes.size());
                attributes.addTo(list);
                yyValue = new FullProduction(list, type, nt, choice);

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

    // Done.
    return yyError;
  }

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.AlternativeAddition.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pAlternativeAddition(final int yyStart) throws IOException {
    Result              yyResult;
    int                 yyBase;
    AlternativeAddition yyValue;
    ParseError          yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pTypeName(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final String type = yyResult.semanticValue();

      yyResult = pUnqualifiedNonTerminal(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final NonTerminal nt = yyResult.semanticValue();

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

          final int yyChoice1 = yyResult.index;

          // Nested alternative 1.

          yyResult = pSequenceName(yyChoice1);
          yyError  = yyResult.select(yyError);
          if (yyResult.hasValue()) {
            final SequenceName s = yyResult.semanticValue();

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

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

                yyResult = pChoice(yyResult.index);
                yyError  = yyResult.select(yyError);
                if (yyResult.hasValue()) {
                  final OrderedChoice choice = yyResult.semanticValue();

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

                    yyValue = new AlternativeAddition(type, nt, choice, s, false);

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

          // Nested alternative 2.

          yyResult = pChoice(yyChoice1);
          yyError  = yyResult.select(yyError);
          if (yyResult.hasValue()) {
            final OrderedChoice choice = yyResult.semanticValue();

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

              yyResult = pSequenceName(yyResult.index);
              yyError  = yyResult.select(yyError);
              if (yyResult.hasValue()) {
                final SequenceName s = yyResult.semanticValue();

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

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

                    yyValue = new AlternativeAddition(type, nt, choice, s, true);

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

    // Done.
    return yyError;
  }

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

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

    // Alternative 1.

    yyResult = pTypeName(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final String type = yyResult.semanticValue();

      yyResult = pUnqualifiedNonTerminal(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final NonTerminal nt = yyResult.semanticValue();

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

          yyResult = pSequenceName(yyResult.index);
          yyError  = yyResult.select(yyError);
          if (yyResult.hasValue()) {
            final SequenceName s = yyResult.semanticValue();

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

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

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

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

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

                yyValue = new
                AlternativeRemoval(type, nt, new Pair<SequenceName>(s, ss).list());

                setLocation(yyValue, yyStart);
                return yyResult.createValue(yyValue, yyError);
              } else {
                yyError = yyError.select("';' expected", yyBase);
              }
            } // End scope for ss.
          }
        } else {
          yyError = yyError.select("'-=' expected", yyBase);
        }
      }
    }

    // Done.
    return yyError;
  }

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.ProductionOverride.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pProductionOverride(final int yyStart) throws IOException {
    Result             yyResult;
    int                yyBase;
    ProductionOverride yyValue;
    ParseError         yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pTypeName(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final String type = yyResult.semanticValue();

      yyResult = pUnqualifiedNonTerminal(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final NonTerminal nt = yyResult.semanticValue();

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

          final int yyChoice1 = yyResult.index;

          // Nested alternative 1.

          yyResult = pChoice(yyChoice1);
          yyError  = yyResult.select(yyError);
          if (yyResult.hasValue()) {
            final OrderedChoice choice = yyResult.semanticValue();

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

              yyValue = new ProductionOverride(type, nt, choice, true);

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

          // Nested alternative 2.

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

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

              yyResult = pChoice(yyResult.index);
              yyError  = yyResult.select(yyError);
              if (yyResult.hasValue()) {
                final OrderedChoice choice = yyResult.semanticValue();

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

                  yyValue = new ProductionOverride(type, nt, choice, false);

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

          // Nested alternative 3.

          yyResult = pChoice(yyChoice1);
          yyError  = yyResult.select(yyError);
          if (yyResult.hasValue()) {
            final OrderedChoice choice = yyResult.semanticValue();

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

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

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

                  yyValue = new ProductionOverride(type, nt, choice, false);

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

    // Alternative 2.

    yyResult = pProductionAttributes(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final Pair<Attribute> attributes = yyResult.semanticValue();

      yyResult = pTypeName(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final String type = yyResult.semanticValue();

        yyResult = pUnqualifiedNonTerminal(yyResult.index);
        yyError  = yyResult.select(yyError);
        if (yyResult.hasValue()) {
          final NonTerminal nt = yyResult.semanticValue();

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

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

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

                List<Attribute> list = new ArrayList<Attribute>(attributes.size());
                attributes.addTo(list);
                yyValue = new ProductionOverride(list, type, nt);

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

    // Done.
    return yyError;
  }

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.ProductionAttributes.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pProductionAttributes(final int yyStart) throws IOException {
    PParserColumn yyColumn = (PParserColumn)column(yyStart);
    if (null == yyColumn.chunk1) yyColumn.chunk1 = new Chunk1();
    if (null == yyColumn.chunk1.fProductionAttributes) 
      yyColumn.chunk1.fProductionAttributes = pProductionAttributes$1(yyStart);
    return yyColumn.chunk1.fProductionAttributes;
  }

  /** Actually parse xtc.parser.PGrammar.ProductionAttributes. */
  private Result pProductionAttributes$1(final int yyStart) 
    throws IOException {

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

    // Alternative 1.

    yyPredResult = pTypeName(yyStart);
    yyError      = yyPredResult.select(yyError);
    if (yyPredResult.hasValue()) {

      yyPredResult = pUnqualifiedNonTerminal(yyPredResult.index);
      yyError      = yyPredResult.select(yyError);
      if (yyPredResult.hasValue()) {

        yyPredResult = pSymbol(yyPredResult.index);
        yyError      = yyPredResult.select(yyError);
        if (yyPredResult.hasValue()) {
          final String s = yyPredResult.semanticValue();

          if ("=".equals(s) || ":=".equals(s)) {

            yyValue = Pair.empty();

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

    // Alternative 2.

    yyResult = pAttribute(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final Attribute att = yyResult.semanticValue();

      yyResult = pProductionAttributes(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final Pair<Attribute> atts = yyResult.semanticValue();

        yyValue = new Pair<Attribute>(att, atts);

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

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

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.Choice.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pChoice(final int yyStart) throws IOException {
    PParserColumn yyColumn = (PParserColumn)column(yyStart);
    if (null == yyColumn.chunk1) yyColumn.chunk1 = new Chunk1();
    if (null == yyColumn.chunk1.fChoice) 
      yyColumn.chunk1.fChoice = pChoice$1(yyStart);
    return yyColumn.chunk1.fChoice;
  }

  /** Actually parse xtc.parser.PGrammar.Choice. */
  private Result pChoice$1(final int yyStart) throws IOException {
    Result        yyResult;
    OrderedChoice yyValue;
    ParseError    yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pSequence(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final Sequence s = yyResult.semanticValue();

      yyResult = pChoice$$Star1(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final Pair<Sequence> ss = yyResult.semanticValue();

        yyValue = new OrderedChoice(new Pair<Sequence>(s, ss).list());

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

    // Done.
    return yyError;
  }

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

  /**
   * Parse synthetic nonterminal xtc.parser.PGrammar.Choice$$Star1.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pChoice$$Star1(final int yyStart) throws IOException {
    PParserColumn yyColumn = (PParserColumn)column(yyStart);
    if (null == yyColumn.chunk1) yyColumn.chunk1 = new Chunk1();
    if (null == yyColumn.chunk1.fChoice$$Star1) 
      yyColumn.chunk1.fChoice$$Star1 = pChoice$$Star1$1(yyStart);
    return yyColumn.chunk1.fChoice$$Star1;
  }

  /** Actually parse xtc.parser.PGrammar.Choice$$Star1. */
  private Result pChoice$$Star1$1(final int yyStart) throws IOException {
    Result         yyResult;
    Pair<Sequence> yyValue;
    ParseError     yyError = ParseError.DUMMY;

    // Alternative 1.

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

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

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

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

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

    // Alternative 2.

    yyValue = Pair.empty();

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

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.Sequence.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pSequence(final int yyStart) throws IOException {
    PParserColumn yyColumn = (PParserColumn)column(yyStart);
    if (null == yyColumn.chunk1) yyColumn.chunk1 = new Chunk1();
    if (null == yyColumn.chunk1.fSequence) 
      yyColumn.chunk1.fSequence = pSequence$1(yyStart);
    return yyColumn.chunk1.fSequence;
  }

  /** Actually parse xtc.parser.PGrammar.Sequence. */
  private Result pSequence$1(final int yyStart) throws IOException {
    Result       yyResult;
    Result       yyPredResult;
    boolean      yyPredMatched;
    int          yyOption1;
    SequenceName yyOpValue1;
    Sequence     yyValue;
    ParseError   yyError = ParseError.DUMMY;

    // Alternative 1.

    yyPredMatched = false;

    yyPredResult = pEllipsis(yyStart);
    if (yyPredResult.hasValue()) {

      yyPredMatched = true;
    }

    if (! yyPredMatched) {

      yyOption1  = yyStart;
      yyOpValue1 = null;

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

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

        yyResult = pSequence$$Star1(yyOption1);
        yyError  = yyResult.select(yyError);
        if (yyResult.hasValue()) {
          final Pair<Element> l = yyResult.semanticValue();

          yyValue = new Sequence(n, l.list());

          setLocation(yyValue, yyStart);
          return yyResult.createValue(yyValue, yyError);
        }
      } // End scope for n.
    } else {
      yyError = yyError.select("sequence expected", yyStart);
    }

    // Done.
    return yyError;
  }

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

  /**
   * Parse synthetic nonterminal xtc.parser.PGrammar.Sequence$$Star1.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pSequence$$Star1(final int yyStart) throws IOException {
    PParserColumn yyColumn = (PParserColumn)column(yyStart);
    if (null == yyColumn.chunk1) yyColumn.chunk1 = new Chunk1();
    if (null == yyColumn.chunk1.fSequence$$Star1) 
      yyColumn.chunk1.fSequence$$Star1 = pSequence$$Star1$1(yyStart);
    return yyColumn.chunk1.fSequence$$Star1;
  }

  /** Actually parse xtc.parser.PGrammar.Sequence$$Star1. */
  private Result pSequence$$Star1$1(final int yyStart) throws IOException {
    Result        yyResult;
    Pair<Element> yyValue;
    ParseError    yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pVoided(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final Element v$el$2 = yyResult.semanticValue();

      yyResult = pSequence$$Star1(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final Pair<Element> v$3 = yyResult.semanticValue();

        yyValue = new Pair<Element>(v$el$2, v$3);

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

    // Alternative 2.

    yyValue = Pair.empty();

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

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.SequenceName.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pSequenceName(final int yyStart) throws IOException {
    PParserColumn yyColumn = (PParserColumn)column(yyStart);
    if (null == yyColumn.chunk1) yyColumn.chunk1 = new Chunk1();
    if (null == yyColumn.chunk1.fSequenceName) 
      yyColumn.chunk1.fSequenceName = pSequenceName$1(yyStart);
    return yyColumn.chunk1.fSequenceName;
  }

  /** Actually parse xtc.parser.PGrammar.SequenceName. */
  private Result pSequenceName$1(final int yyStart) throws IOException {
    int          yyC;
    int          yyIndex;
    Result       yyResult;
    int          yyBase;
    SequenceName yyValue;
    ParseError   yyError = ParseError.DUMMY;

    // Alternative 1.

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

      yyResult = pWordCharacters(yyIndex);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final String name = yyResult.semanticValue();

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

          yyValue = new SequenceName(name);

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

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

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.Ellipsis.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pEllipsis(final int yyStart) throws IOException {
    Result     yyResult;
    int        yyBase;
    Void       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

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

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

        yyValue = null;

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

    // Alternative 2.

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

      yyValue = null;

      return yyResult.createValue(yyValue, yyError);
    }

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

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.Voided.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pVoided(final int yyStart) throws IOException {
    PParserColumn yyColumn = (PParserColumn)column(yyStart);
    if (null == yyColumn.chunk2) yyColumn.chunk2 = new Chunk2();
    if (null == yyColumn.chunk2.fVoided) 
      yyColumn.chunk2.fVoided = pVoided$1(yyStart);
    return yyColumn.chunk2.fVoided;
  }

  /** Actually parse xtc.parser.PGrammar.Voided. */
  private Result pVoided$1(final int yyStart) throws IOException {
    Result     yyResult;
    int        yyBase;
    Element    yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pWord(yyStart);
    if (yyResult.hasValue("void")) {

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

        yyResult = pVoided(yyResult.index);
        yyError  = yyResult.select(yyError);
        if (yyResult.hasValue()) {
          final Element p = yyResult.semanticValue();

          yyValue = new VoidedElement(p);

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

    // Alternative 2.

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

      return yyResult.createValue(yyValue, yyError);
    }

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

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.Prefix.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pPrefix(final int yyStart) throws IOException {
    Result     yyResult;
    int        yyBase;
    Element    yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

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

      yyResult = pSuffix(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final Element s = yyResult.semanticValue();

        if (s instanceof Action) {
          yyValue = new SemanticPredicate((Action)s);
        } else {
          yyValue = new FollowedBy(s);
        }

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

    // Alternative 2.

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

      yyResult = pSuffix(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final Element s = yyResult.semanticValue();

        yyValue = new NotFollowedBy(s);

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

    // Alternative 3.

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

      yyResult = pSuffix(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final Element s = yyResult.semanticValue();

        if (s instanceof Action) {

          yyValue = new ParserAction((Action)s);

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

    // Alternative 4.

    yyResult = pWord(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final String id = yyResult.semanticValue();

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

        yyResult = pSuffix(yyResult.index);
        yyError  = yyResult.select(yyError);
        if (yyResult.hasValue()) {
          final Element s = yyResult.semanticValue();

          yyValue = new Binding(id, s);

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

    // Alternative 5.

    yyResult = pStringLiteral(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final String t1 = yyResult.semanticValue();

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

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

          yyResult = pSuffix(yyResult.index);
          yyError  = yyResult.select(yyError);
          if (yyResult.hasValue()) {
            final Element s = yyResult.semanticValue();

            final String t2 = Utilities.unescape(t1.substring(1, t1.length()-1));
            yyValue = new StringMatch(t2, s);

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

    // Alternative 6.

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

      return yyResult.createValue(yyValue, yyError);
    }

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

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.Suffix.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pSuffix(final int yyStart) throws IOException {
    PParserColumn yyColumn = (PParserColumn)column(yyStart);
    if (null == yyColumn.chunk2) yyColumn.chunk2 = new Chunk2();
    if (null == yyColumn.chunk2.fSuffix) 
      yyColumn.chunk2.fSuffix = pSuffix$1(yyStart);
    return yyColumn.chunk2.fSuffix;
  }

  /** Actually parse xtc.parser.PGrammar.Suffix. */
  private Result pSuffix$1(final int yyStart) throws IOException {
    Result     yyResult;
    int        yyBase;
    Element    yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pPrimary(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final Element p = yyResult.semanticValue();

      final int yyChoice1 = yyResult.index;

      // Nested alternative 1.

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

        yyValue = new Option(p);

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

      // Nested alternative 2.

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

        yyValue = new Repetition(false, p);

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

      // Nested alternative 3.

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

        yyValue = new Repetition(true,  p);

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

    // Alternative 2.

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

      return yyResult.createValue(yyValue, yyError);
    }

    // Done.
    return yyError;
  }

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.Primary.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pPrimary(final int yyStart) throws IOException {
    PParserColumn yyColumn = (PParserColumn)column(yyStart);
    if (null == yyColumn.chunk2) yyColumn.chunk2 = new Chunk2();
    if (null == yyColumn.chunk2.fPrimary) 
      yyColumn.chunk2.fPrimary = pPrimary$1(yyStart);
    return yyColumn.chunk2.fPrimary;
  }

  /** Actually parse xtc.parser.PGrammar.Primary. */
  private Result pPrimary$1(final int yyStart) throws IOException {
    Result     yyResult;
    int        yyBase;
    Element    yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

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

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative 2.

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

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative 3.

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

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative 4.

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

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative 5.

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

      return yyResult.createValue(yyValue, yyError);
    }

    // Alternative 6.

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

      yyResult = pChoice(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        yyValue = yyResult.semanticValue();

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

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

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

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.NullLiteral.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pNullLiteral(final int yyStart) throws IOException {
    Result      yyResult;
    NullLiteral yyValue;
    ParseError  yyError = ParseError.DUMMY;

    // Alternative 1.

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

      yyValue = new NullLiteral();

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

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

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.NonTerminal.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pNonTerminal(final int yyStart) throws IOException {
    Result      yyResult;
    NonTerminal yyValue;
    ParseError  yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pName(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final String name = yyResult.semanticValue();

      yyValue = new NonTerminal(name);

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

    // Done.
    return yyError;
  }

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.UnqualifiedNonTerminal.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pUnqualifiedNonTerminal(final int yyStart) 
    throws IOException {

    PParserColumn yyColumn = (PParserColumn)column(yyStart);
    if (null == yyColumn.chunk2) yyColumn.chunk2 = new Chunk2();
    if (null == yyColumn.chunk2.fUnqualifiedNonTerminal) 
      yyColumn.chunk2.fUnqualifiedNonTerminal = pUnqualifiedNonTerminal$1(yyStart);
    return yyColumn.chunk2.fUnqualifiedNonTerminal;
  }

  /** Actually parse xtc.parser.PGrammar.UnqualifiedNonTerminal. */
  private Result pUnqualifiedNonTerminal$1(final int yyStart) 
    throws IOException {

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

    // Alternative 1.

    yyResult = pWord(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final String name = yyResult.semanticValue();

      yyValue = new NonTerminal(name);

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

    // Done.
    return yyError;
  }

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.Terminal.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pTerminal(final int yyStart) throws IOException {
    int             yyC;
    int             yyIndex;
    Result          yyResult;
    int             yyRepetition1;
    Pair<CharRange> yyRepValue1;
    Terminal        yyValue;
    ParseError      yyError = ParseError.DUMMY;

    // Alternative 1.

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

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

        yyValue = new AnyChar();

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

    // Alternative 2.

    yyResult = pCharacterLiteral(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final String c = yyResult.semanticValue();

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

        yyValue = new CharLiteral(Utilities.unescape(c).charAt(1));

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

    // Alternative 3.

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

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

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

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

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

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

            yyValue = new CharClass(l.list());

            setLocation(yyValue, yyStart);
            return yyResult.createValue(yyValue, yyError);
          }
        }
      } // End scope for l.
    }

    // Alternative 4.

    yyResult = pStringLiteral(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final String s1 = yyResult.semanticValue();

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

        final String s2 = Utilities.unescape(s1);
        yyValue = new StringLiteral(s2.substring(1, s2.length()-1));

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

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

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.Range.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pRange(final int yyStart) throws IOException {
    int        yyC;
    int        yyIndex;
    Result     yyResult;
    CharRange  yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pClassChar(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final String c1 = yyResult.semanticValue();

      final int yyChoice1 = yyResult.index;

      // Nested alternative 1.

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

        yyResult = pClassChar(yyIndex);
        yyError  = yyResult.select(yyError);
        if (yyResult.hasValue()) {
          final String c2 = yyResult.semanticValue();

          yyValue = new CharRange(Utilities.unescape(c1).charAt(0),
          Utilities.unescape(c2).charAt(0));

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

      // Nested alternative 2.

      yyValue = new CharRange(Utilities.unescape(c1).charAt(0));

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

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

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.NodeMarker.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pNodeMarker(final int yyStart) throws IOException {
    int        yyC;
    int        yyIndex;
    Result     yyResult;
    NodeMarker yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

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

      yyResult = pWord(yyIndex);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final String name = yyResult.semanticValue();

        yyValue = new NodeMarker(name);

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

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

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.Action.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pAction(final int yyStart) throws IOException {
    PParserColumn yyColumn = (PParserColumn)column(yyStart);
    if (null == yyColumn.chunk2) yyColumn.chunk2 = new Chunk2();
    if (null == yyColumn.chunk2.fAction) 
      yyColumn.chunk2.fAction = pAction$1(yyStart);
    return yyColumn.chunk2.fAction;
  }

  /** Actually parse xtc.parser.PGrammar.Action. */
  private Result pAction$1(final int yyStart) throws IOException {
    int        yyC;
    int        yyIndex;
    Result     yyResult;
    Action     yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

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

      yyResult = pActionBody(yyIndex);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {
        final String s = yyResult.semanticValue();

        yyC = character(yyResult.index);
        if ('}' == yyC) {
          yyIndex = yyResult.index + 1;

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

            yyValue = new Action(s, yyState.indentations());

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

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

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.ActionBody.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pActionBody(final int yyStart) throws IOException {
    Result     yyResult;
    String     yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Start a state modification.
    yyState.start();

    // Alternative 1.

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

      yyValue = difference(yyStart, yyResult.index);

      // Commit the state modification.
      yyState.commit();

      return yyResult.createValue(yyValue, yyError);
    }

    // Abort the state modification.
    yyState.abort();

    // Done.
    return yyError;
  }

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.ActionText.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pActionText(final int yyStart) throws IOException {
    int        yyC;
    int        yyIndex;
    Result     yyResult;
    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 ('{' == yyC) {
        yyIndex = yyChoice1 + 1;

        yyState.open();

        yyResult = pActionText(yyIndex);
        yyError  = yyResult.select(yyError, yyRepetition1);
        if (yyResult.hasValue()) {

          yyC = character(yyResult.index);
          if ('}' == yyC) {
            yyIndex = yyResult.index + 1;

            yyState.close();

            yyRepetition1 = yyIndex;
            continue;
          }
        }
      }

      // Nested alternative 2.

      yyResult = pCharacterLiteral(yyChoice1);
      yyError  = yyResult.select(yyError, yyRepetition1);
      if (yyResult.hasValue()) {

        yyState.content();

        yyRepetition1 = yyResult.index;
        continue;
      }

      // Nested alternative 3.

      yyResult = pStringLiteral(yyChoice1);
      yyError  = yyResult.select(yyError, yyRepetition1);
      if (yyResult.hasValue()) {

        yyState.content();

        yyRepetition1 = yyResult.index;
        continue;
      }

      // Nested alternative 4.

      yyResult = pCodeComment(yyChoice1);
      yyError  = yyResult.select(yyError, yyRepetition1);
      if (yyResult.hasValue()) {

        yyState.content();

        yyRepetition1 = yyResult.index;
        continue;
      }

      // Nested alternative 5.

      yyResult = pTraditionalComment(yyChoice1);
      yyError  = yyResult.select(yyError, yyRepetition1);
      if (yyResult.hasValue()) {

        yyState.content();

        yyRepetition1 = yyResult.index;
        continue;
      }

      // Nested alternative 6.

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

        switch (yyC) {
        case '/':
          {
            yyC = character(yyIndex);
            if (-1 != yyC) {
              yyIndex = yyIndex + 1;
              if ('/' == yyC) {

                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;
                }

                yyResult = pLineTerminator(yyRepetition2);
                yyError  = yyResult.select(yyError, yyRepetition1);
                if (yyResult.hasValue()) {

                  yyRepetition1 = yyResult.index;
                  continue;
                }
              }
            }
          }
          break;

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

            // Nested alternative 1.

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

              yyState.newline();

              yyRepetition1 = yyIndex;
              continue;
            }

            // Nested alternative 2.

            yyState.newline();

            yyRepetition1 = yyChoice2;
            continue;
          }

        case '\n':
          {
            yyState.newline();

            yyRepetition1 = yyIndex;
            continue;
          }

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

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

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

        default:
          /* No match. */
        }
      }

      // Nested alternative 7.

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

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

        default:
          {
            yyState.content();

            yyRepetition1 = yyIndex;
            continue;
          }
        }
      }
      break;
    }

    yyValue = null;

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

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.Attribute.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  public Result pAttribute(final int yyStart) throws IOException {
    PParserColumn yyColumn = (PParserColumn)column(yyStart);
    if (null == yyColumn.chunk2) yyColumn.chunk2 = new Chunk2();
    if (null == yyColumn.chunk2.fAttribute) 
      yyColumn.chunk2.fAttribute = pAttribute$1(yyStart);
    return yyColumn.chunk2.fAttribute;
  }

  /** Actually parse xtc.parser.PGrammar.Attribute. */
  private Result pAttribute$1(final int yyStart) throws IOException {
    Result     yyResult;
    int        yyBase;
    int        yyOption1;
    Object     yyOpValue1;
    Attribute  yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pWord(yyStart);
    if (yyResult.hasValue("public")) {

      yyValue = new Attribute(Constants.NAME_VISIBILITY,
      Constants.VALUE_PUBLIC);

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

    // Alternative 2.

    yyResult = pWord(yyStart);
    if (yyResult.hasValue("protected")) {

      yyValue = new Attribute(Constants.NAME_VISIBILITY,
      Constants.VALUE_PROTECTED);

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

    // Alternative 3.

    yyResult = pWord(yyStart);
    if (yyResult.hasValue("private")) {

      yyValue = new Attribute(Constants.NAME_VISIBILITY,
      Constants.VALUE_PRIVATE);

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

    // Alternative 4.

    yyResult = pWord(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final String name = yyResult.semanticValue();

      yyOption1  = yyResult.index;
      yyOpValue1 = null;

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

        yyResult = pAttributeValue(yyResult.index);
        yyError  = yyResult.select(yyError, yyOption1);
        if (yyResult.hasValue()) {
          final Object v$el$1 = yyResult.semanticValue();

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

            yyOption1  = yyResult.index;
            yyOpValue1 = v$el$1;
          } else {
            yyError = yyError.select("')' expected", yyBase);
          }
        }
      } else {
        yyError = yyError.select("'(' expected", yyBase);
      }
      { // Start scope for value.
        final Object value = yyOpValue1;

        yyValue = new Attribute(name, value);

        setLocation(yyValue, yyStart);
        return new SemanticValue(yyValue, yyOption1, yyError);
      } // End scope for value.
    }

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

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.AttributeValue.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pAttributeValue(final int yyStart) throws IOException {
    Result     yyResult;
    Object     yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pIntegerLiteral(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {
      final String lit = yyResult.semanticValue();

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

        try {
          yyValue = Integer.decode(lit);
        } catch (NumberFormatException x) {
          yyValue = null; // Cannot happen.
        }

        if (yyValue instanceof Locatable) {
          setLocation((Locatable)yyValue, yyStart);
        }
        return yyResult.createValue(yyValue, yyError);
      }
    }

    // Alternative 2.

    yyResult = pName(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();

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

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

    // Done.
    return yyError;
  }

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.TypeName.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pTypeName(final int yyStart) throws IOException {
    PParserColumn yyColumn = (PParserColumn)column(yyStart);
    if (null == yyColumn.chunk2) yyColumn.chunk2 = new Chunk2();
    if (null == yyColumn.chunk2.fTypeName) 
      yyColumn.chunk2.fTypeName = pTypeName$1(yyStart);
    return yyColumn.chunk2.fTypeName;
  }

  /** Actually parse xtc.parser.PGrammar.TypeName. */
  private Result pTypeName$1(final int yyStart) throws IOException {
    Result     yyResult;
    String     yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pTypeNameCharacters(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.parser.PGrammar.TypeNameCharacters.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pTypeNameCharacters(final int yyStart) throws IOException {
    PParserColumn yyColumn = (PParserColumn)column(yyStart);
    if (null == yyColumn.chunk2) yyColumn.chunk2 = new Chunk2();
    if (null == yyColumn.chunk2.fTypeNameCharacters) 
      yyColumn.chunk2.fTypeNameCharacters = pTypeNameCharacters$1(yyStart);
    return yyColumn.chunk2.fTypeNameCharacters;
  }

  /** Actually parse xtc.parser.PGrammar.TypeNameCharacters. */
  private Result pTypeNameCharacters$1(final int yyStart) throws IOException {
    int        yyC;
    int        yyIndex;
    Result     yyResult;
    int        yyOption1;
    String     yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

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

      yyOption1  = yyResult.index;

      yyResult = pSimpleSpacing(yyOption1);
      yyError  = yyResult.select(yyError, yyOption1);
      if (yyResult.hasValue()) {

        yyC = character(yyResult.index);
        if ('<' == yyC) {
          yyIndex = yyResult.index + 1;

          yyResult = pSimpleSpacing(yyIndex);
          yyError  = yyResult.select(yyError, yyOption1);
          if (yyResult.hasValue()) {

            yyResult = pTypeNameCharacters(yyResult.index);
            yyError  = yyResult.select(yyError, yyOption1);
            if (yyResult.hasValue()) {

              yyResult = pSimpleSpacing(yyResult.index);
              yyError  = yyResult.select(yyError, yyOption1);
              if (yyResult.hasValue()) {

                yyResult = pTypeNameCharacters$$Star1(yyResult.index);
                yyError  = yyResult.select(yyError, yyOption1);
                if (yyResult.hasValue()) {

                  yyC = character(yyResult.index);
                  if ('>' == yyC) {
                    yyIndex = yyResult.index + 1;

                    yyOption1  = yyIndex;
                  }
                }
              }
            }
          }
        }
      }

      yyValue = difference(yyStart, yyOption1);

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

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

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

  /**
   * Parse synthetic nonterminal 
   * xtc.parser.PGrammar.TypeNameCharacters$$Star1.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pTypeNameCharacters$$Star1(final int yyStart) 
    throws IOException {

    PParserColumn yyColumn = (PParserColumn)column(yyStart);
    if (null == yyColumn.chunk2) yyColumn.chunk2 = new Chunk2();
    if (null == yyColumn.chunk2.fTypeNameCharacters$$Star1) 
      yyColumn.chunk2.fTypeNameCharacters$$Star1 = pTypeNameCharacters$$Star1$1(yyStart);
    return yyColumn.chunk2.fTypeNameCharacters$$Star1;
  }

  /** Actually parse xtc.parser.PGrammar.TypeNameCharacters$$Star1. */
  private Result pTypeNameCharacters$$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 (',' == yyC) {
      yyIndex = yyStart + 1;

      yyResult = pSimpleSpacing(yyIndex);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {

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

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

            yyResult = pTypeNameCharacters$$Star1(yyResult.index);
            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.parser.PGrammar.Name.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pName(final int yyStart) throws IOException {
    PParserColumn yyColumn = (PParserColumn)column(yyStart);
    if (null == yyColumn.chunk2) yyColumn.chunk2 = new Chunk2();
    if (null == yyColumn.chunk2.fName) 
      yyColumn.chunk2.fName = pName$1(yyStart);
    return yyColumn.chunk2.fName;
  }

  /** Actually parse xtc.parser.PGrammar.Name. */
  private Result pName$1(final int yyStart) throws IOException {
    Result     yyResult;
    String     yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pNameCharacters(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.parser.PGrammar.Word.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pWord(final int yyStart) throws IOException {
    PParserColumn yyColumn = (PParserColumn)column(yyStart);
    if (null == yyColumn.chunk3) yyColumn.chunk3 = new Chunk3();
    if (null == yyColumn.chunk3.fWord) 
      yyColumn.chunk3.fWord = pWord$1(yyStart);
    return yyColumn.chunk3.fWord;
  }

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

    // Alternative 1.

    yyResult = pWordCharacters(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.parser.PGrammar.NameCharacters.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pNameCharacters(final int yyStart) throws IOException {
    PParserColumn yyColumn = (PParserColumn)column(yyStart);
    if (null == yyColumn.chunk3) yyColumn.chunk3 = new Chunk3();
    if (null == yyColumn.chunk3.fNameCharacters) 
      yyColumn.chunk3.fNameCharacters = pNameCharacters$1(yyStart);
    return yyColumn.chunk3.fNameCharacters;
  }

  /** Actually parse xtc.parser.PGrammar.NameCharacters. */
  private Result pNameCharacters$1(final int yyStart) throws IOException {
    Result     yyResult;
    String     yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

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

      yyResult = pNameCharacters$$Star1(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {

        yyValue = difference(yyStart, yyResult.index);

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

    // Done.
    return yyError;
  }

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

  /**
   * Parse synthetic nonterminal xtc.parser.PGrammar.NameCharacters$$Star1.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pNameCharacters$$Star1(final int yyStart) 
    throws IOException {

    PParserColumn yyColumn = (PParserColumn)column(yyStart);
    if (null == yyColumn.chunk3) yyColumn.chunk3 = new Chunk3();
    if (null == yyColumn.chunk3.fNameCharacters$$Star1) 
      yyColumn.chunk3.fNameCharacters$$Star1 = pNameCharacters$$Star1$1(yyStart);
    return yyColumn.chunk3.fNameCharacters$$Star1;
  }

  /** Actually parse xtc.parser.PGrammar.NameCharacters$$Star1. */
  private Result pNameCharacters$$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 ('.' == yyC) {
      yyIndex = yyStart + 1;

      yyResult = pWordCharacters(yyIndex);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {

        yyResult = pNameCharacters$$Star1(yyResult.index);
        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.parser.PGrammar.WordCharacters.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pWordCharacters(final int yyStart) throws IOException {
    PParserColumn yyColumn = (PParserColumn)column(yyStart);
    if (null == yyColumn.chunk3) yyColumn.chunk3 = new Chunk3();
    if (null == yyColumn.chunk3.fWordCharacters) 
      yyColumn.chunk3.fWordCharacters = pWordCharacters$1(yyStart);
    return yyColumn.chunk3.fWordCharacters;
  }

  /** Actually parse xtc.parser.PGrammar.WordCharacters. */
  private Result pWordCharacters$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')) ||
          (('a' <= yyC) && (yyC <= 'z'))) {

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

          yyValue = difference(yyStart, yyResult.index);

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

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

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

  /**
   * Parse synthetic nonterminal xtc.parser.PGrammar.WordCharacters$$Plus1.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pWordCharacters$$Plus1(final int yyStart) 
    throws IOException {

    PParserColumn yyColumn = (PParserColumn)column(yyStart);
    if (null == yyColumn.chunk3) yyColumn.chunk3 = new Chunk3();
    if (null == yyColumn.chunk3.fWordCharacters$$Plus1) 
      yyColumn.chunk3.fWordCharacters$$Plus1 = pWordCharacters$$Plus1$1(yyStart);
    return yyColumn.chunk3.fWordCharacters$$Plus1;
  }

  /** Actually parse xtc.parser.PGrammar.WordCharacters$$Plus1. */
  private Result pWordCharacters$$Plus1$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 ('_' == yyC) {

        final int yyChoice1 = yyIndex;

        // Nested alternative 1.

        yyResult = pWordCharacters$$Plus1(yyChoice1);
        yyError  = yyResult.select(yyError);
        if (yyResult.hasValue()) {

          yyValue = null;

          return yyResult.createValue(yyValue, yyError);
        }

        // Nested alternative 2.

        yyValue = null;

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

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

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

  /**
   * Parse synthetic nonterminal xtc.parser.PGrammar.WordCharacters$$Star1.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pWordCharacters$$Star1(final int yyStart) 
    throws IOException {

    PParserColumn yyColumn = (PParserColumn)column(yyStart);
    if (null == yyColumn.chunk3) yyColumn.chunk3 = new Chunk3();
    if (null == yyColumn.chunk3.fWordCharacters$$Star1) 
      yyColumn.chunk3.fWordCharacters$$Star1 = pWordCharacters$$Star1$1(yyStart);
    return yyColumn.chunk3.fWordCharacters$$Star1;
  }

  /** Actually parse xtc.parser.PGrammar.WordCharacters$$Star1. */
  private Result pWordCharacters$$Star1$1(final int yyStart) 
    throws IOException {

    int        yyC;
    int        yyIndex;
    Result     yyResult;
    Void       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

    yyResult = pWordCharacters$$Plus1(yyStart);
    yyError  = yyResult.select(yyError);
    if (yyResult.hasValue()) {

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

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

            yyValue = null;

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

    // Alternative 2.

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

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

          yyValue = null;

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

    // Alternative 3.

    yyValue = null;

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

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.CharacterLiteral.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pCharacterLiteral(final int yyStart) throws IOException {
    PParserColumn yyColumn = (PParserColumn)column(yyStart);
    if (null == yyColumn.chunk3) yyColumn.chunk3 = new Chunk3();
    if (null == yyColumn.chunk3.fCharacterLiteral) 
      yyColumn.chunk3.fCharacterLiteral = pCharacterLiteral$1(yyStart);
    return yyColumn.chunk3.fCharacterLiteral;
  }

  /** Actually parse xtc.parser.PGrammar.CharacterLiteral. */
  private Result pCharacterLiteral$1(final int yyStart) throws IOException {
    int        yyC;
    int        yyIndex;
    Result     yyResult;
    String     yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

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

      yyResult = pCharacterLiteral$$Choice1(yyIndex);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {

        yyC = character(yyResult.index);
        if ('\'' == yyC) {
          yyIndex = yyResult.index + 1;

          yyValue = difference(yyStart, yyIndex);

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

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

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

  /**
   * Parse synthetic nonterminal 
   * xtc.parser.PGrammar.CharacterLiteral$$Choice1.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pCharacterLiteral$$Choice1(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;

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

          // Nested alternative 1.

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

            switch (yyC) {
            case '\"':
            case '\'':
            case '-':
            case '[':
            case '\\':
            case ']':
            case 'b':
            case 'f':
            case 'n':
            case 'r':
            case 't':
              {
                yyValue = null;

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

            case 'u':
              {
                yyResult = pHexQuad(yyIndex);
                yyError  = yyResult.select(yyError);
                if (yyResult.hasValue()) {

                  yyValue = null;

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

            default:
              /* No match. */
            }
          }

          // Nested alternative 2.
          { // Start scope for nested choice.

            final int yyChoice2 = yyChoice1;

            // Nested alternative 1.

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

              switch (yyC) {
              case '0':
              case '1':
              case '2':
              case '3':
                {
                  yyC = character(yyIndex);
                  if (-1 != yyC) {
                    yyIndex = yyIndex + 1;

                    switch (yyC) {
                    case '0':
                    case '1':
                    case '2':
                    case '3':
                    case '4':
                    case '5':
                    case '6':
                    case '7':
                      {
                        yyC = character(yyIndex);
                        if (-1 != yyC) {
                          yyIndex = yyIndex + 1;

                          switch (yyC) {
                          case '0':
                          case '1':
                          case '2':
                          case '3':
                          case '4':
                          case '5':
                          case '6':
                          case '7':
                            {
                              yyValue = null;

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

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

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

              default:
                /* No match. */
              }
            }

            // Nested alternative 2.

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

              switch (yyC) {
              case '0':
              case '1':
              case '2':
              case '3':
              case '4':
              case '5':
              case '6':
              case '7':
                {
                  final int yyChoice3 = yyIndex;

                  // Nested alternative 1.

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

                    switch (yyC) {
                    case '0':
                    case '1':
                    case '2':
                    case '3':
                    case '4':
                    case '5':
                    case '6':
                    case '7':
                      {
                        yyValue = null;

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

                    default:
                      /* No match. */
                    }
                  }

                  // Nested alternative 2.

                  yyValue = null;

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

              default:
                /* No match. */
              }
            }
          } // End scope for nested choice.
        }
        break;

      default:
        /* No match. */
      }
    }

    // Alternative 2.

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

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

      default:
        {
          yyValue = null;

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

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

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

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

  /** Actually parse xtc.parser.PGrammar.StringLiteral. */
  private Result pStringLiteral$1(final int yyStart) throws IOException {
    int        yyC;
    int        yyIndex;
    Result     yyResult;
    String     yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

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

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

        yyC = character(yyResult.index);
        if ('\"' == yyC) {
          yyIndex = yyResult.index + 1;

          yyValue = difference(yyStart, yyIndex);

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

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

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

  /**
   * Parse synthetic nonterminal xtc.parser.PGrammar.StringLiteral$$Star1.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pStringLiteral$$Star1(final int yyStart) throws IOException {
    PParserColumn yyColumn = (PParserColumn)column(yyStart);
    if (null == yyColumn.chunk3) yyColumn.chunk3 = new Chunk3();
    if (null == yyColumn.chunk3.fStringLiteral$$Star1) 
      yyColumn.chunk3.fStringLiteral$$Star1 = pStringLiteral$$Star1$1(yyStart);
    return yyColumn.chunk3.fStringLiteral$$Star1;
  }

  /** Actually parse xtc.parser.PGrammar.StringLiteral$$Star1. */
  private Result pStringLiteral$$Star1$1(final int yyStart) 
    throws IOException {

    int        yyC;
    int        yyIndex;
    Result     yyResult;
    Void       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

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

      yyResult = pStringLiteral$$Star1(yyResult.index);
      yyError  = yyResult.select(yyError);
      if (yyResult.hasValue()) {

        yyValue = null;

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

    // Alternative 2.

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

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

      default:
        {
          yyResult = pStringLiteral$$Star1(yyIndex);
          yyError  = yyResult.select(yyError);
          if (yyResult.hasValue()) {

            yyValue = null;

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

    // Alternative 3.

    yyValue = null;

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

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.ClassChar.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pClassChar(final int yyStart) throws IOException {
    PParserColumn yyColumn = (PParserColumn)column(yyStart);
    if (null == yyColumn.chunk3) yyColumn.chunk3 = new Chunk3();
    if (null == yyColumn.chunk3.fClassChar) 
      yyColumn.chunk3.fClassChar = pClassChar$1(yyStart);
    return yyColumn.chunk3.fClassChar;
  }

  /** Actually parse xtc.parser.PGrammar.ClassChar. */
  private Result pClassChar$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;

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

          // Nested alternative 1.

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

            switch (yyC) {
            case '\"':
            case '\'':
            case '-':
            case '[':
            case '\\':
            case ']':
            case 'b':
            case 'f':
            case 'n':
            case 'r':
            case 't':
              {
                yyValue = difference(yyStart, yyIndex);

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

            case 'u':
              {
                yyResult = pHexQuad(yyIndex);
                yyError  = yyResult.select(yyError);
                if (yyResult.hasValue()) {

                  yyValue = difference(yyStart, yyResult.index);

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

            default:
              /* No match. */
            }
          }

          // Nested alternative 2.
          { // Start scope for nested choice.

            final int yyChoice2 = yyChoice1;

            // Nested alternative 1.

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

              switch (yyC) {
              case '0':
              case '1':
              case '2':
              case '3':
                {
                  yyC = character(yyIndex);
                  if (-1 != yyC) {
                    yyIndex = yyIndex + 1;

                    switch (yyC) {
                    case '0':
                    case '1':
                    case '2':
                    case '3':
                    case '4':
                    case '5':
                    case '6':
                    case '7':
                      {
                        yyC = character(yyIndex);
                        if (-1 != yyC) {
                          yyIndex = yyIndex + 1;

                          switch (yyC) {
                          case '0':
                          case '1':
                          case '2':
                          case '3':
                          case '4':
                          case '5':
                          case '6':
                          case '7':
                            {
                              yyValue = difference(yyStart, yyIndex);

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

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

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

              default:
                /* No match. */
              }
            }

            // Nested alternative 2.

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

              switch (yyC) {
              case '0':
              case '1':
              case '2':
              case '3':
              case '4':
              case '5':
              case '6':
              case '7':
                {
                  final int yyChoice3 = yyIndex;

                  // Nested alternative 1.

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

                    switch (yyC) {
                    case '0':
                    case '1':
                    case '2':
                    case '3':
                    case '4':
                    case '5':
                    case '6':
                    case '7':
                      {
                        yyValue = difference(yyStart, yyIndex);

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

                    default:
                      /* No match. */
                    }
                  }

                  // Nested alternative 2.

                  yyValue = difference(yyStart, yyChoice3);

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

              default:
                /* No match. */
              }
            }
          } // End scope for nested choice.
        }
        break;

      default:
        /* No match. */
      }
    }

    // Alternative 2.

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

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

      default:
        {
          yyValue = difference(yyStart, yyIndex);

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

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

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.EscapeSequence.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pEscapeSequence(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 ('\\' == yyC) {

        final int yyChoice1 = yyIndex;

        // Nested alternative 1.

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

          switch (yyC) {
          case '\"':
          case '\'':
          case '-':
          case '[':
          case '\\':
          case ']':
          case 'b':
          case 'f':
          case 'n':
          case 'r':
          case 't':
            {
              yyValue = null;

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

          case 'u':
            {
              yyResult = pHexQuad(yyIndex);
              yyError  = yyResult.select(yyError);
              if (yyResult.hasValue()) {

                yyValue = null;

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

          default:
            /* No match. */
          }
        }

        // Nested alternative 2.
        { // Start scope for nested choice.

          final int yyChoice2 = yyChoice1;

          // Nested alternative 1.

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

            switch (yyC) {
            case '0':
            case '1':
            case '2':
            case '3':
              {
                yyC = character(yyIndex);
                if (-1 != yyC) {
                  yyIndex = yyIndex + 1;

                  switch (yyC) {
                  case '0':
                  case '1':
                  case '2':
                  case '3':
                  case '4':
                  case '5':
                  case '6':
                  case '7':
                    {
                      yyC = character(yyIndex);
                      if (-1 != yyC) {
                        yyIndex = yyIndex + 1;

                        switch (yyC) {
                        case '0':
                        case '1':
                        case '2':
                        case '3':
                        case '4':
                        case '5':
                        case '6':
                        case '7':
                          {
                            yyValue = null;

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

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

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

            default:
              /* No match. */
            }
          }

          // Nested alternative 2.

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

            switch (yyC) {
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
              {
                final int yyChoice3 = yyIndex;

                // Nested alternative 1.

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

                  switch (yyC) {
                  case '0':
                  case '1':
                  case '2':
                  case '3':
                  case '4':
                  case '5':
                  case '6':
                  case '7':
                    {
                      yyValue = null;

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

                  default:
                    /* No match. */
                  }
                }

                // Nested alternative 2.

                yyValue = null;

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

            default:
              /* No match. */
            }
          }
        } // End scope for nested choice.
      }
    }

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

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.IntegerLiteral.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pIntegerLiteral(final int yyStart) throws IOException {
    int        yyC;
    int        yyIndex;
    int        yyRepetition1;
    boolean    yyRepeated1;
    String     yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

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

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

          // Nested alternative 1.

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

            switch (yyC) {
            case 'X':
            case 'x':
              {
                yyRepetition1 = yyIndex;
                yyRepeated1   = false;
                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':
                    case 'A':
                    case 'B':
                    case 'C':
                    case 'D':
                    case 'E':
                    case 'F':
                    case 'a':
                    case 'b':
                    case 'c':
                    case 'd':
                    case 'e':
                    case 'f':
                      {
                        yyRepetition1 = yyIndex;
                        yyRepeated1   = true;
                        continue;
                      }

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

                if (yyRepeated1) {

                  yyValue = difference(yyStart, yyRepetition1);

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

            default:
              /* No match. */
            }
          }

          // Nested alternative 2.

          yyRepetition1 = yyChoice1;
          yyRepeated1   = false;
          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':
                {
                  yyRepetition1 = yyIndex;
                  yyRepeated1   = true;
                  continue;
                }

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

          if (yyRepeated1) {

            yyValue = difference(yyStart, yyRepetition1);

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

          // Nested alternative 3.

          yyValue = "0";

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

      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("integer literal expected", yyStart);
    return yyError;
  }

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.HexQuad.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pHexQuad(final int yyStart) throws IOException {
    int        yyC;
    int        yyIndex;
    Void       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':
      case 'A':
      case 'B':
      case 'C':
      case 'D':
      case 'E':
      case 'F':
      case 'a':
      case 'b':
      case 'c':
      case 'd':
      case 'e':
      case 'f':
        {
          yyC = character(yyIndex);
          if (-1 != yyC) {
            yyIndex = yyIndex + 1;

            switch (yyC) {
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
            case 'A':
            case 'B':
            case 'C':
            case 'D':
            case 'E':
            case 'F':
            case 'a':
            case 'b':
            case 'c':
            case 'd':
            case 'e':
            case 'f':
              {
                yyC = character(yyIndex);
                if (-1 != yyC) {
                  yyIndex = yyIndex + 1;

                  switch (yyC) {
                  case '0':
                  case '1':
                  case '2':
                  case '3':
                  case '4':
                  case '5':
                  case '6':
                  case '7':
                  case '8':
                  case '9':
                  case 'A':
                  case 'B':
                  case 'C':
                  case 'D':
                  case 'E':
                  case 'F':
                  case 'a':
                  case 'b':
                  case 'c':
                  case 'd':
                  case 'e':
                  case 'f':
                    {
                      yyC = character(yyIndex);
                      if (-1 != yyC) {
                        yyIndex = yyIndex + 1;

                        switch (yyC) {
                        case '0':
                        case '1':
                        case '2':
                        case '3':
                        case '4':
                        case '5':
                        case '6':
                        case '7':
                        case '8':
                        case '9':
                        case 'A':
                        case 'B':
                        case 'C':
                        case 'D':
                        case 'E':
                        case 'F':
                        case 'a':
                        case 'b':
                        case 'c':
                        case 'd':
                        case 'e':
                        case 'f':
                          {
                            yyValue = null;

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

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

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

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

      default:
        /* No match. */
      }
    }

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

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

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

  /** Actually parse xtc.parser.PGrammar.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.parser.PGrammar.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;
    boolean    yyPredMatched;
    String     yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

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

      switch (yyC) {
      case '.':
        {
          yyC = character(yyIndex);
          if (-1 != yyC) {
            yyIndex = yyIndex + 1;
            if ('.' == yyC) {

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

                  yyValue = "...";

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

      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 '-':
        {
          yyC = character(yyIndex);
          if (-1 != yyC) {
            yyIndex = yyIndex + 1;
            if ('=' == yyC) {

              yyValue = "-=";

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

      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 '/':
        {
          yyPredMatched = false;

          yyC = character(yyIndex);
          if (-1 != yyC) {
            if (('*' == yyC) ||
                ('/' == yyC)) {

              yyPredMatched = true;
            }
          }

          if (! yyPredMatched) {

            yyValue = "/";

            return new SemanticValue(yyValue, yyIndex, yyError);
          } else {
            yyError = yyError.select("symbol characters expected", yyStart);
          }
        }
        break;

      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.parser.PGrammar.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     yyResult;
    boolean    yyPredMatched;
    int        yyBase;
    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 '\r':
          {
            final int yyChoice2 = yyIndex;

            // Nested alternative 1.

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

              yyState.newline();

              yyRepetition1 = yyIndex;
              continue;
            }

            // Nested alternative 2.

            yyState.newline();

            yyRepetition1 = yyChoice2;
            continue;
          }

        case '\n':
          {
            yyState.newline();

            yyRepetition1 = yyIndex;
            continue;
          }

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

              switch (yyC) {
              case '*':
                {
                  yyPredMatched = false;

                  yyC = character(yyIndex);
                  if ('*' == yyC) {

                    yyPredMatched = true;
                  }

                  if (! yyPredMatched) {

                    yyResult = pCommentBody(yyIndex);
                    yyError  = yyResult.select(yyError, yyRepetition1);
                    if (yyResult.hasValue()) {

                      yyBase = yyResult.index;
                      yyC    = character(yyBase);
                      if ('*' == yyC) {
                        yyIndex = yyResult.index + 1;

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

                          yyRepetition1 = yyIndex;
                          continue;
                        } else {
                          yyError = yyError.select("'*/' expected", yyBase);
                        }
                      } else {
                        yyError = yyError.select("'*/' expected", yyBase);
                      }
                    }
                  } else {
                    yyError = yyError.select("spacing expected", yyStart);
                  }
                }
                break;

              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;
                  }

                  yyResult = pLineTerminator(yyRepetition2);
                  yyError  = yyResult.select(yyError, yyRepetition1);
                  if (yyResult.hasValue()) {

                    yyRepetition1 = yyResult.index;
                    continue;
                  }
                }
                break;

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

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

    yyValue = null;

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

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.SimpleSpacing.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pSimpleSpacing(final int yyStart) throws IOException {
    int        yyC;
    int        yyIndex;
    int        yyRepetition1;
    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 '\r':
          {
            final int yyChoice2 = yyIndex;

            // Nested alternative 1.

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

              yyState.newline();

              yyRepetition1 = yyIndex;
              continue;
            }

            // Nested alternative 2.

            yyState.newline();

            yyRepetition1 = yyChoice2;
            continue;
          }

        case '\n':
          {
            yyState.newline();

            yyRepetition1 = yyIndex;
            continue;
          }

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

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

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

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

    yyValue = null;

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

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.CodeComment.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pCodeComment(final int yyStart) throws IOException {
    int        yyC;
    int        yyIndex;
    Result     yyResult;
    int        yyBase;
    String     yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

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

      yyC = character(yyIndex);
      if ('*' == yyC) {
        yyIndex = yyIndex + 1;

        yyC = character(yyIndex);
        if ('*' == yyC) {
          yyIndex = yyIndex + 1;

          yyResult = pCommentBody(yyIndex);
          yyError  = yyResult.select(yyError);
          if (yyResult.hasValue()) {

            yyBase = yyResult.index;
            yyC    = character(yyBase);
            if ('*' == yyC) {
              yyIndex = yyResult.index + 1;

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

                yyValue = difference(yyStart, yyIndex);

                return new SemanticValue(yyValue, yyIndex, yyError);
              } else {
                yyError = yyError.select("'*/' expected", yyBase);
              }
            } else {
              yyError = yyError.select("'*/' expected", yyBase);
            }
          }
        }
      }
    }

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

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.TraditionalComment.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pTraditionalComment(final int yyStart) throws IOException {
    int        yyC;
    int        yyIndex;
    Result     yyResult;
    boolean    yyPredMatched;
    int        yyBase;
    Void       yyValue;
    ParseError yyError = ParseError.DUMMY;

    // Alternative 1.

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

      yyC = character(yyIndex);
      if ('*' == yyC) {
        yyIndex = yyIndex + 1;

        yyPredMatched = false;

        yyC = character(yyIndex);
        if ('*' == yyC) {

          yyPredMatched = true;
        }

        if (! yyPredMatched) {

          yyResult = pCommentBody(yyIndex);
          yyError  = yyResult.select(yyError);
          if (yyResult.hasValue()) {

            yyBase = yyResult.index;
            yyC    = character(yyBase);
            if ('*' == yyC) {
              yyIndex = yyResult.index + 1;

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

                yyValue = null;

                return new SemanticValue(yyValue, yyIndex, yyError);
              } else {
                yyError = yyError.select("'*/' expected", yyBase);
              }
            } else {
              yyError = yyError.select("'*/' expected", yyBase);
            }
          }
        } else {
          yyError = yyError.select("traditional comment expected", yyStart);
        }
      }
    }

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

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.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;
  }

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.CommentBody.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pCommentBody(final int yyStart) throws IOException {
    int        yyC;
    int        yyIndex;
    boolean    yyPredMatched;
    int        yyRepetition1;
    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 '*':
          {
            yyPredMatched = false;

            yyC = character(yyIndex);
            if ('/' == yyC) {

              yyPredMatched = true;
            }

            if (! yyPredMatched) {

              yyRepetition1 = yyIndex;
              continue;
            } else {
              yyError = yyError.select("comment body expected", yyStart);
            }
          }
          break;

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

            // Nested alternative 1.

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

              yyState.newline();

              yyRepetition1 = yyIndex;
              continue;
            }

            // Nested alternative 2.

            yyState.newline();

            yyRepetition1 = yyChoice2;
            continue;
          }

        case '\n':
          {
            yyState.newline();

            yyRepetition1 = yyIndex;
            continue;
          }

        default:
          /* No match. */
        }
      }

      // Nested alternative 2.

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

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

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

    yyValue = null;

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

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

  /**
   * Parse nonterminal xtc.parser.PGrammar.LineTerminator.
   *
   * @param yyStart The index.
   * @return The result.
   * @throws IOException Signals an I/O error.
   */
  private Result pLineTerminator(final int yyStart) throws IOException {
    int        yyC;
    int        yyIndex;
    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;

            yyState.newline();

            yyValue = null;

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

          // Nested alternative 2.

          yyState.newline();

          yyValue = null;

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

      case '\n':
        {
          yyState.newline();

          yyValue = null;

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

      default:
        /* No match. */
      }
    }

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

}
