Example #1
0
 /** Legal as long as there is at least one item on the state's stack. */
 public boolean isLegal(State state, List<ParserConstraint> constraints) {
   if (state.finished) {
     return false;
   }
   if (state.stack.size() == 0) {
     return false;
   }
   Tree top = state.stack.peek();
   if (top.label().value().equals(label)) {
     // Disallow unary transitions where the label doesn't change
     return false;
   }
   if (top.label().value().startsWith("@") && !label.equals(top.label().value().substring(1))) {
     return false;
   }
   if (top.children().length == 1) {
     Tree child = top.children()[0];
     if (child.children().length == 1) {
       Tree grandChild = child.children()[0];
       if (grandChild.children().length == 1) {
         // Three consecutive unary trees.  Not legal to keep adding unaries.
         // TODO: do preterminals count in that equation?
         return false;
       }
     }
   }
   if (isRoot && (state.stack.size() > 1 || !state.endOfQueue())) {
     return false;
   }
   // UnaryTransition actually doesn't care about the constraints.
   // If the constraint winds up unsatisfied, we'll get stuck and
   // have to do an "emergency transition" to fix the situation.
   return true;
 }
  private boolean parseInternal() {
    final int maxBeamSize = Math.max(parser.op.testOptions().beamSize, 1);

    success = true;
    unparsable = false;
    PriorityQueue<State> beam =
        new PriorityQueue<>(maxBeamSize + 1, ScoredComparator.ASCENDING_COMPARATOR);
    beam.add(initialState);
    // TODO: don't construct as many PriorityQueues
    while (beam.size() > 0) {
      // System.err.println("================================================");
      // System.err.println("Current beam:");
      // System.err.println(beam);
      PriorityQueue<State> oldBeam = beam;
      beam = new PriorityQueue<>(maxBeamSize + 1, ScoredComparator.ASCENDING_COMPARATOR);
      State bestState = null;
      for (State state : oldBeam) {
        Collection<ScoredObject<Integer>> predictedTransitions =
            parser.model.findHighestScoringTransitions(state, true, maxBeamSize, constraints);
        // System.err.println("Examining state: " + state);
        for (ScoredObject<Integer> predictedTransition : predictedTransitions) {
          Transition transition = parser.model.transitionIndex.get(predictedTransition.object());
          State newState = transition.apply(state, predictedTransition.score());
          // System.err.println("  Transition: " + transition + " (" + predictedTransition.score() +
          // ")");
          if (bestState == null || bestState.score() < newState.score()) {
            bestState = newState;
          }
          beam.add(newState);
          if (beam.size() > maxBeamSize) {
            beam.poll();
          }
        }
      }
      if (beam.size() == 0) {
        // Oops, time for some fallback plan
        // This can happen with the set of constraints given by the original paper
        // For example, one particular French model had a situation where it would reach
        //   @Ssub @Ssub .
        // without a left(Ssub) transition, so finishing the parse was impossible.
        // This will probably result in a bad parse, but at least it
        // will result in some sort of parse.
        for (State state : oldBeam) {
          Transition transition = parser.model.findEmergencyTransition(state, constraints);
          if (transition != null) {
            State newState = transition.apply(state);
            if (bestState == null || bestState.score() < newState.score()) {
              bestState = newState;
            }
            beam.add(newState);
          }
        }
      }

      // bestState == null only happens when we have failed to make progress, so quit
      // If the bestState is finished, we are done
      if (bestState == null || bestState.isFinished()) {
        break;
      }
    }
    List<State> bestParses;
    if (beam.size() == 0) {
      success = false;
      unparsable = true;
      debinarized = null;
      finalState = null;
      bestParses = Collections.emptyList();
    } else {
      // TODO: filter out beam elements that aren't finished
      bestParses = Generics.newArrayList(beam);
      Collections.sort(bestParses, beam.comparator());
      Collections.reverse(bestParses);
      finalState = bestParses.get(0);
      debinarized = debinarizer.transformTree(finalState.stack.peek());
      debinarized =
          Tsurgeon.processPattern(
              rearrangeFinalPunctuationTregex, rearrangeFinalPunctuationTsurgeon, debinarized);
    }
    return success;
  }