/// <summary> /// Find error recovery state. /// </summary> /// <returns>result.</returns> private bool FindErrorRecoveryState() { while (true) // pop states until one found that accepts error token { if (FsaState.ParserTable != null && FsaState.ParserTable.ContainsKey(errorToken) && FsaState.ParserTable[errorToken] > 0) // shift { return(true); } StateStack.Pop(); ValueStack.Pop(); LocationStack.Pop(); if (StateStack.IsEmpty()) { return(false); } else { FsaState = StateStack.TopElement(); } } }
/// <summary> /// Reduce. /// </summary> /// <param name="ruleNumber">The rule to reduce by.</param> private void Reduce(int ruleNumber) { Rule rule = rules[ruleNumber]; // // Default actions for unit productions. // if (rule.RightHandSide.Length == 1) { CurrentSemanticValue = ValueStack.TopElement(); // Default action: $$ = $1; CurrentLocationSpan = LocationStack.TopElement(); // Default action "@$ = @1; } else { if (rule.RightHandSide.Length == 0) { // Create a new blank value. // Explicit semantic action may mutate this value CurrentSemanticValue = default(TValue); // The location span for an empty production will start with the // beginning of the next lexeme, and end with the finish of the // previous lexeme. This gives the correct behaviour when this // nonsense value is used in later Merge operations. CurrentLocationSpan = (Scanner.yylloc != null && LastSpan != null ? Scanner.yylloc.Merge(LastSpan) : default(TSpan)); } else { // Default action: $$ = $1; CurrentSemanticValue = ValueStack.TopElement(); // Default action "@$ = @1.Merge(@N)" for location info. TSpan at1 = LocationStack[LocationStack.Depth - rule.RightHandSide.Length]; TSpan atN = LocationStack[LocationStack.Depth - 1]; CurrentLocationSpan = ((at1 != null && atN != null) ? at1.Merge(atN) : default(TSpan)); } } DoAction(ruleNumber); for (int i = rule.RightHandSide.Length - 1; i >= 0; i--) { _valueParameterList[i] = ValueStack.Pop(); // capture the values - added by Nate Wallace StateStack.Pop(); LocationStack.Pop(); } if (!_errorOccured) { ProcessReduce(rule.LeftHandSide, _valueParameterList, rule.RightHandSide.Length); // process the reduce action - added by Nate Wallace } else { _errorOccured = false; } FsaState = StateStack.TopElement(); if (FsaState.Goto.ContainsKey(rule.LeftHandSide)) { FsaState = states[FsaState.Goto[rule.LeftHandSide]]; } StateStack.Push(FsaState); ValueStack.Push(CurrentSemanticValue); LocationStack.Push(CurrentLocationSpan); }