Ejemplo n.º 1
0
        //TODO: need to rewrite, looks ugly
        private bool Recover()
        {
            //for recovery the current token must be error token, we rely on it
            if (!_currentToken.IsError())
            {
                _currentToken = _context.CreateErrorToken(_currentToken.Location, _currentToken.Text);
            }
            //Check the current state and states in stack for error shift action - this would be recovery state.
            ActionRecord action = GetCurrentAction();

            if (action == null || action.ActionType == ParserActionType.Reduce)
            {
                while (Stack.Count > 0)
                {
                    _currentState = Stack.Top.State;
                    Stack.Pop(1);
                    action = GetCurrentAction();
                    if (action != null && action.ActionType != ParserActionType.Reduce)
                    {
                        break; //we found shift action for error token
                    }
                }//while
            }//if
            if (action == null || action.ActionType == ParserActionType.Reduce)
            {
                return(false); //could not find shift action, cannot recover
            }
            //We found recovery state, and action contains ActionRecord for "error shift". Lets shift it.
            ExecuteShiftAction(action);//push the error token
            // Now shift all tokens from input that can be shifted.
            // These are the ones that are found in error production after the error. We ignore all other tokens
            // We stop when we find a state with reduce-only action.
            while (_currentToken.Terminal != Grammar.Eof)
            {
                //with current token, see if we can shift it.
                action = GetCurrentAction();
                if (action == null)
                {
                    NextToken(); //skip this token and continue reading input
                    continue;
                }
                if (action.ActionType == ParserActionType.Reduce || action.ActionType == ParserActionType.Operator)
                {
                    //we can reduce - let's reduce and return success - we recovered.
                    ExecuteReduceAction(action);
                    return(true);
                }
                //it is shift action, let's shift
                ExecuteShiftAction(action);
            }//while
            return(false); //
        }