// parse
  public ParsingResult parse(Source source) throws ParserException {
    net.sf.laja.parser.engine2.element.Element element = getGrammar1();

    boolean match = element.parse(0, source, false, true, false);
    int bestIndex = source.getBestIndex();

    if (match && source.reachedEnd()) {
      source.reset();
      element = getGrammar2();
      match = element.parse(0, source, false, true, true);
      if (!match) {
        throw new IllegalStateException(
            "The parsing result was true in phase 1, but false in phase 2.");
      }
      return new ParsingResult(true, source, syntaxErrorHandler);
    } else if (sourceRecorderLogWriter != null) {
      source.reset();
      source.getRecorder().setLogging(sourceRecorderLogWriter, bestIndex);
      element.parse(0, source, false, true, false);
    }

    return new ParsingResult(false, source, element, syntaxErrorHandler);
  }