Example #1
0
  //
  // Parse input allowing up to max_error_count Error token recoveries.
  // When max_error_count is 0, no Error token recoveries occur.
  // When max_error is > 0, it limits the number of Error token recoveries.
  // When max_error is < 0, the number of error token recoveries is unlimited.
  // Also, such recoveries only require one token to be parsed beyond the
  // recovery point.
  // (normally two tokens beyond the recovery point must be parsed)
  // Thus, a negative max_error_count should be used when error productions
  // are used to
  // skip tokens.
  //
  public Object parse(int max_error_count) throws BadParseException {
    state = new ParserState(START_STATE, tokStream);
    skipTokens = max_error_count < 0;

    state.pendingCommits = new LinkedList();
    backtrackRequested = false;
    state.trialActionCount = 0;

    // Next "start" token
    state.repair_token = 0;

    int start_token_index = tokStream.peek();
    int start_action_index = 0;

    // Last commit point
    int[] temp_stack = new int[1];
    temp_stack[0] = START_STATE;

    state.reallocateOtherStacks(start_token_index);

    int initial_error_token = backtrackParse(state.repair_token);
    for (int error_token = initial_error_token, count = 0;
        error_token != 0;
        error_token = backtrackParse(state.repair_token), count++) {
      if (count == max_error_count) throw new BadParseException(initial_error_token);
      state.actionCount = start_action_index;
      tokStream.reset(start_token_index);
      state.stateStackTop = temp_stack.length - 1;
      System.arraycopy(temp_stack, 0, state.stateStack, 0, temp_stack.length);
      state.reallocateOtherStacks(start_token_index);

      backtrackParseUpToError(state.repair_token, error_token);

      for (state.stateStackTop = findRecoveryStateIndex(state.stateStackTop);
          state.stateStackTop >= 0;
          state.stateStackTop = findRecoveryStateIndex(state.stateStackTop - 1)) {
        int recovery_token = state.tokens.get(state.locationStack[state.stateStackTop] - 1);
        state.repair_token =
            errorRepair(
                (recovery_token >= start_token_index ? recovery_token : error_token), error_token);
        if (state.repair_token != 0) break;
      }

      if (state.stateStackTop < 0) throw new BadParseException(initial_error_token);

      temp_stack = new int[state.stateStackTop + 1];
      System.arraycopy(state.stateStack, 0, temp_stack, 0, temp_stack.length);

      start_action_index = state.actionCount;
      start_token_index = tokStream.peek();
    }

    if (state.repair_token != 0) state.tokens.add(state.repair_token);
    int t;
    for (t = start_token_index; tokStream.getKind(t) != EOFT_SYMBOL; t = tokStream.getNext(t))
      state.tokens.add(t);
    state.tokens.add(t);

    return null;
  }
Example #2
0
 //
 // Process reductions and continue...
 //
 private int process_repair_reductions(int act) {
   do {
     System.out.println("process_repair_reductions: " + act);
     state.stateStackTop -= (prs.rhs(act) - 1);
     act = prs.ntAction(state.stateStack[state.stateStackTop], prs.lhs(act));
   } while (act <= NUM_RULES);
   return act;
 }
Example #3
0
 //
 // Process reductions and continue...
 //
 private int process_backtrack_reductions(int act) {
   do {
     state.stateStackTop -= (prs.rhs(act) - 1);
     trialAction(act);
     if (backtrackRequested) {
       backtrackRequested = false;
       return ERROR_ACTION;
     }
     act = prs.ntAction(state.stateStack[state.stateStackTop], prs.lhs(act));
   } while (act <= NUM_RULES);
   return act;
 }
Example #4
0
  private int errorRepair(int recovery_token, int error_token) {
    int temp_stack[] = new int[state.stateStackTop + 1];
    System.arraycopy(state.stateStack, 0, temp_stack, 0, temp_stack.length);
    for (;
        tokStream.getKind(recovery_token) != EOFT_SYMBOL;
        recovery_token = tokStream.getNext(recovery_token)) {
      System.out.println("recovery token: " + tokStream.getKind(recovery_token)); // $NON-NLS-1$
      tokStream.reset(recovery_token);
      if (repairable(error_token)) break;
      state.stateStackTop = temp_stack.length - 1;
      System.arraycopy(temp_stack, 0, state.stateStack, 0, temp_stack.length);
    }

    if (tokStream.getKind(recovery_token) == EOFT_SYMBOL) {
      tokStream.reset(recovery_token);
      if (!repairable(error_token)) {
        state.stateStackTop = temp_stack.length - 1;
        System.arraycopy(temp_stack, 0, state.stateStack, 0, temp_stack.length);
        return 0;
      }
    }

    state.stateStackTop = temp_stack.length - 1;
    System.arraycopy(temp_stack, 0, state.stateStack, 0, temp_stack.length);

    undoActions(state.undoStack[state.stateStackTop]);
    tokStream.reset(recovery_token);
    state.tokens.reset(state.locationStack[state.stateStackTop] - 1);
    state.actionCount = state.actionStack[state.stateStackTop];
    state.trialActionCount = state.undoStack[state.stateStackTop];

    return tokStream.makeErrorToken(
        state.tokens.get(state.locationStack[state.stateStackTop] - 1),
        tokStream.getPrevious(recovery_token),
        error_token,
        ERROR_SYMBOL);
  }
Example #5
0
  private boolean repairable(int error_token) {
    //
    // Allocate configuration stack.
    //
    ConfigurationStack configuration_stack = new ConfigurationStack(prs);

    //
    // Keep parsing until we successfully reach the end of file or
    // an error is encountered. The list of actions executed will
    // be stored in the "action" tuple.
    //
    int start_token = tokStream.peek();
    int final_token = tokStream.getStreamLength(); // unreachable
    int curtok = 0;
    int current_kind = ERROR_SYMBOL;
    int act = tAction(state.stateStack[state.stateStackTop], current_kind);

    for (; ; ) {
      if (act <= NUM_RULES) {
        state.stateStackTop--;
        act = process_repair_reductions(act);
      } else if (act > ERROR_ACTION) {
        curtok = tokStream.getToken();
        if (curtok > final_token) return true;
        current_kind = tokStream.getKind(curtok);
        act = process_repair_reductions(act - ERROR_ACTION);
      } else if (act < ACCEPT_ACTION) {
        curtok = tokStream.getToken();
        if (curtok > final_token) return true;
        current_kind = tokStream.getKind(curtok);
      } else if (act == ERROR_ACTION) {
        ConfigurationElement configuration = configuration_stack.pop();
        if (configuration == null) act = ERROR_ACTION;
        else {
          state.stateStackTop = configuration.stack_top;
          configuration.retrieveStack(state.stateStack);
          act = configuration.act;
          curtok = configuration.curtok;
          if (curtok == 0) {
            current_kind = ERROR_SYMBOL;
            tokStream.reset(start_token);
          } else {
            current_kind = tokStream.getKind(curtok);
            tokStream.reset(tokStream.getNext(curtok));
          }
          continue;
        }
        break;
      } else if (act > ACCEPT_ACTION) {
        if (configuration_stack.findConfiguration(state.stateStack, state.stateStackTop, curtok))
          act = ERROR_ACTION;
        else {
          configuration_stack.push(state.stateStack, state.stateStackTop, act + 1, curtok, 0);
          act = prs.baseAction(act);
        }
        continue;
      } else break; // assert(act == ACCEPT_ACTION);
      try {
        //
        // We consider a configuration to be acceptable for recovery
        // if we are able to consume enough symbols in the remaining
        // tokens to reach another potential recovery point past the
        // original error token.
        //
        if ((curtok > error_token) && (final_token == tokStream.getStreamLength())) {
          //
          // If the ERROR_SYMBOL is a valid Action Adjunct in the
          // state
          // "act" then we set the terminating token as the successor
          // of
          // the current token. I.e., we have to be able to parse at
          // least
          // two tokens past the re-synch point before we claim
          // victory.
          //
          if (recoverableState(act)) final_token = skipTokens ? curtok : tokStream.getNext(curtok);
        }

        state.stateStack[++state.stateStackTop] = act;
      } catch (IndexOutOfBoundsException e) {
        state.reallocateStateStack();
        state.stateStack[state.stateStackTop] = act;
      }

      act = tAction(act, current_kind);
    }

    //
    // If we can reach the end of the input successfully, we claim victory.
    //
    return (act == ACCEPT_ACTION);
  }
Example #6
0
  private void backtrackParseUpToError(int initial_token, int error_token) {
    //
    // Allocate configuration stack.
    //
    state.configurationStack = new ConfigurationStack(prs);
    state.trialActionStack = new LinkedList<Integer>();
    state.trialActionStack.add(Integer.valueOf(state.trialActionCount));

    //
    // Keep parsing until we successfully reach the end of file or
    // an error is encountered. The list of actions executed will
    // be stored in the "action" tuple.
    //

    // tokStream.reset(initial_token);
    int start_token = tokStream.peek();
    state.curtok = (initial_token > 0 ? initial_token : tokStream.getToken());
    int current_kind = tokStream.getKind(state.curtok);
    state.act = tAction(state.stateStack[state.stateStackTop], current_kind);

    state.tokens.add(state.curtok);
    state.locationStack[state.stateStackTop] = state.tokens.size();
    state.actionStack[state.stateStackTop] = state.actionCount;
    state.undoStack[state.stateStackTop] = state.trialActionCount;

    for (; ; ) {
      //
      // if the parser needs to stop processing,
      // it may do so here.
      //
      if (monitor != null && monitor.isCancelled()) return;

      state.parserLocationStack[state.stateStackTop] = state.curtok;

      if (state.act <= NUM_RULES) {
        state.actionCount++;
        state.stateStackTop--;
        state.act = process_backtrack_reductions(state.act);
      } else if (state.act > ERROR_ACTION) {
        state.actionCount++;
        state.lastToken = state.curtok;
        state.curtok = tokStream.getToken();
        current_kind = tokStream.getKind(state.curtok);
        state.tokens.add(state.curtok);
        state.act = process_backtrack_reductions(state.act - ERROR_ACTION);
      } else if (state.act < ACCEPT_ACTION) {
        state.actionCount++;
        state.lastToken = state.curtok;
        state.curtok = tokStream.getToken();
        current_kind = tokStream.getKind(state.curtok);
        state.tokens.add(state.curtok);
      } else if (state.act == ERROR_ACTION) {
        if (state.curtok != error_token) {
          ConfigurationElement configuration = state.configurationStack.pop();
          if (configuration == null) state.act = ERROR_ACTION;
          else {
            boolean shouldPop = prs.baseAction(configuration.conflict_index) == 0;
            undoActions(shouldPop);
            state.actionCount = configuration.action_length;
            state.act = configuration.act;
            int next_token_index = configuration.curtok;
            state.tokens.reset(next_token_index);
            state.curtok = state.tokens.get(next_token_index - 1);
            current_kind = tokStream.getKind(state.curtok);
            tokStream.reset(
                state.curtok == initial_token ? start_token : tokStream.getNext(state.curtok));
            state.stateStackTop = configuration.stack_top;
            configuration.retrieveStack(state.stateStack);
            state.locationStack[state.stateStackTop] = state.tokens.size();
            state.actionStack[state.stateStackTop] = state.actionCount;
            state.undoStack[state.stateStackTop] = state.trialActionCount;
            continue;
          }
        }
        break;
      } else if (state.act > ACCEPT_ACTION) {
        if (state.configurationStack.findConfiguration(
            state.stateStack, state.stateStackTop, state.tokens.size())) state.act = ERROR_ACTION;
        else {
          state.configurationStack.push(
              state.stateStack,
              state.stateStackTop,
              state.act + 1,
              state.tokens.size(),
              state.actionCount);
          state.trialActionStack.add(Integer.valueOf(state.trialActionCount));
          state.act = prs.baseAction(state.act);
        }
        continue;
      } else break; // assert(act == ACCEPT_ACTION);

      state.stateStack[++state.stateStackTop] = state.act; // no need
      // to check
      // if out of
      // bounds
      state.locationStack[state.stateStackTop] = state.tokens.size();
      state.actionStack[state.stateStackTop] = state.actionCount;
      state.undoStack[state.stateStackTop] = state.trialActionCount;
      state.act = tAction(state.act, current_kind);
    }

    // assert(curtok == error_token);

    return;
  }
Example #7
0
  //
  // Parse the input until either the parse completes successfully or
  // an error is encountered. This function returns an integer that
  // represents the last action that was executed by the parser. If
  // the parse was succesful, then the tuple "action" contains the
  // successful sequence of actions that was executed.
  //
  private int backtrackParse(int initial_token) {
    //
    // Allocate configuration stack.
    //
    state.configurationStack = new ConfigurationStack(prs);
    state.trialActionStack = new LinkedList<Integer>();
    state.trialActionStack.add(Integer.valueOf(state.trialActionCount));

    //
    // Keep parsing until we successfully reach the end of file or
    // an error is encountered. The list of actions executed will
    // be stored in the "action" tuple.
    //
    int error_token = 0;
    int maxStackTop = state.stateStackTop;
    int start_token = tokStream.peek();
    state.curtok = (initial_token > 0 ? initial_token : tokStream.getToken());
    int current_kind = tokStream.getKind(state.curtok);
    state.act = tAction(state.stateStack[state.stateStackTop], current_kind);

    //
    // The main driver loop
    //
    for (; ; ) {
      //
      // if the parser needs to stop processing,
      // it may do so here.
      //
      if (monitor != null && monitor.isCancelled()) return 0;

      state.parserLocationStack[state.stateStackTop] = state.curtok;

      if (state.act <= NUM_RULES) {
        state.actionCount++;
        state.stateStackTop--;
        state.act = process_backtrack_reductions(state.act);
      } else if (state.act > ERROR_ACTION) {
        state.actionCount++;
        state.lastToken = state.curtok;
        state.curtok = tokStream.getToken();
        current_kind = tokStream.getKind(state.curtok);
        state.act = process_backtrack_reductions(state.act - ERROR_ACTION);
      } else if (state.act < ACCEPT_ACTION) {
        state.actionCount++;
        state.lastToken = state.curtok;
        state.curtok = tokStream.getToken();
        current_kind = tokStream.getKind(state.curtok);
      }

      if (state.act == ERROR_ACTION) {
        error_token = (error_token > state.curtok ? error_token : state.curtok);

        ConfigurationElement configuration = state.configurationStack.pop();
        if (configuration == null) state.act = ERROR_ACTION;
        else {
          boolean shouldPop = prs.baseAction(configuration.conflict_index) == 0;
          undoActions(shouldPop);
          state.actionCount = configuration.action_length;
          state.act = configuration.act;
          state.curtok = configuration.curtok;
          current_kind = tokStream.getKind(state.curtok);
          tokStream.reset(
              state.curtok == initial_token ? start_token : tokStream.getNext(state.curtok));
          state.stateStackTop = configuration.stack_top;
          configuration.retrieveStack(state.stateStack);
          continue;
        }
        break;
      }
      if (state.act > ACCEPT_ACTION && state.act != ERROR_ACTION) {
        if (state.configurationStack.findConfiguration(
            state.stateStack, state.stateStackTop, state.curtok)) state.act = ERROR_ACTION;
        else {
          state.configurationStack.push(
              state.stateStack,
              state.stateStackTop,
              state.act + 1,
              state.curtok,
              state.actionCount);
          state.trialActionStack.add(Integer.valueOf(state.trialActionCount));
          state.act = prs.baseAction(state.act);
          maxStackTop = state.stateStackTop > maxStackTop ? state.stateStackTop : maxStackTop;
        }
        continue;
      } else if (state.act == ACCEPT_ACTION) {
        break;
      }
      try {
        state.stateStack[++state.stateStackTop] = state.act;
      } catch (IndexOutOfBoundsException e) {
        state.reallocateStateStack();
        state.stateStack[state.stateStackTop] = state.act;
      }

      state.act = tAction(state.act, current_kind);
    }

    // System.out.println("****Number of configurations: " +
    // configuration_stack.configurationSize());
    // System.out.println("****Number of elements in stack tree: " +
    // configuration_stack.numStateElements());
    // System.out.println("****Number of elements in stacks: " +
    // configuration_stack.stacksSize());
    // System.out.println("****Number of actions: " + action.size());
    // System.out.println("****Max Stack Size = " + maxStackTop);
    // System.out.flush();
    return (state.act == ERROR_ACTION ? error_token : 0);
  }