private ParserAction GetShiftActionInCurrentState() { ParserAction result = null; if (_currentState.Actions.TryGetValue(_currentInput.Term, out result) || _currentInput.Token != null && _currentInput.Token.AsSymbol != null && _currentState.Actions.TryGetValue(_currentInput.Token.AsSymbol, out result)) { if (result.ActionType == ParserActionType.Shift) { return(result); } } return(null); }
private bool TryRecoverImpl() { //1. We need to find a state in the stack that has a shift item based on error production (with error token), // and error terminal is current. This state would have a shift action on error token. ParserAction errorShiftAction = FindErrorShiftActionInStack(); if (errorShiftAction == null) { return(false); //we failed to recover } //2. Shift error token - execute shift action if (_traceOn) { AddTraceEntry(); } ExecuteShift(errorShiftAction.NewState); //4. Now we need to go along error production until the end, shifting tokens that CAN be shifted and ignoring others. // We shift until we can reduce while (_currentInput.Term != _grammar.Eof) { //Check if we can reduce var action = GetReduceActionInCurrentState(); if (action != null) { //Now reset scanner's position to current input position and clear all token queues; do it before ExecuteReduce // as reset would clear the input stack ResetSourceLocation(_currentInput.Span.Start, _currentInput.Span.EndPos); ExecuteReduce(action.ReduceProduction); return(true); //we recovered } //No reduce action in current state. Try to shift current token or throw it away or reduce action = GetShiftActionInCurrentState(); if (action != null) { ExecuteShift(action.NewState); //shift input token } else { ReadInput(); //throw away input token } } return(false); }//method
private bool ExecuteAction() { if (_currentInput == null) { ReadInput(); } //Trace current state if tracing is on if (_traceOn) { _currentTraceEntry = _context.AddParserTrace(_currentState, Stack.Top, _currentInput); } //Try getting action ParserAction action = GetAction(); if (action == null) { ReportParseError(); return(TryRecover()); } //write trace if (_currentTraceEntry != null) { _currentTraceEntry.SetDetails(action.ToString(), _currentState); } //Execute it switch (action.ActionType) { case ParserActionType.Shift: ExecuteShift(action.NewState); break; case ParserActionType.Operator: ExecuteOperatorAction(action.NewState, action.ReduceProduction); break; case ParserActionType.Reduce: ExecuteReduce(action.ReduceProduction); break; case ParserActionType.Code: ExecuteConflictAction(action); break; case ParserActionType.Jump: ExecuteNonCanonicalJump(action); break; case ParserActionType.Accept: ExecuteAccept(action); return(false); } //add info to trace return(true); }
private void ExecuteConflictAction(ParserAction action) { var args = new ConflictResolutionArgs(_context, action); _grammar.OnResolvingConflict(args); switch (args.Result) { case ParserActionType.Reduce: ExecuteReduce(args.ReduceProduction); break; case ParserActionType.Operator: ExecuteOperatorAction(action.NewState, args.ReduceProduction); break; case ParserActionType.Shift: default: ExecuteShift(action.NewState); break; } }
private void ExecuteNonCanonicalJump(ParserAction action) { _currentState = action.NewState; }
public static ParserAction CreateCodeAction(ParserState newState, Production reduceProduction) { var action = new ParserAction(ParserActionType.Code, newState, reduceProduction); return(action); }