State Parse(IEnumerable <Type_Terminal> tokens, int initialState) { List <State> stack = new List <State>(); { State init = new State(); init.state = initialState; stack.Add(init); } int state = initialState; using (IEnumerator <Type_Terminal> enumerator = tokens.GetEnumerator()) { bool haveToken = enumerator.MoveNext(); while (haveToken) { Type_Terminal token = enumerator.Current; ConfigTokenType type = GetTokenType(token); if (type == ConfigTokenType.Error) { state = ReduceError(stack, enumerator); } else { int offset = _transitionTable[state]; int action = offset <= 16 ? offset : _transitionTable[offset + (int)type]; if (action > 16) { State newState = new State(); newState.state = state = action - 16; newState.value_Terminal = token; stack.Add(newState); haveToken = enumerator.MoveNext(); } else if (action > 1) { int reductionId = action - 2; state = Reduce(reductionId, stack); } else if (action == 0 || type != ConfigTokenType.EOF) { state = ReduceError(stack, enumerator); } else { return(stack[1]); } } } } throw new InvalidOperationException("ran out of tokens, somehow"); }
protected abstract Type_Rule Reduce_Rule_2(Type_Terminal errorSeg);
protected abstract Type_State Reduce_RuleList_2(Type_Terminal errorSeg);
protected abstract Type_Rule Reduce_Rule_1(Type_Terminal regexSeg, Type_Terminal labelSeg);
protected abstract Type_Setting Reduce_Setting_2(Type_Terminal errorSeg);
protected abstract Type_State Reduce_State_1(Type_Terminal labelSeg, Type_State ruleListSeg);
protected abstract Type_Setting Reduce_Setting_1(Type_Terminal labelSeg, Type_Terminal settingValueSeg);
protected abstract Type_Config Reduce_ConfigSettings_3(Type_Terminal errorSeg);
protected abstract Type_Config Reduce_Config_2(Type_Config configSeg, Type_Terminal errorSeg);
protected abstract ConfigTokenType GetTokenType(Type_Terminal terminal);
int ReduceError(List <State> stack, IEnumerator <Type_Terminal> enumerator) { Type_Terminal errorToken = enumerator.Current; if (GetTokenType(enumerator.Current) != ConfigTokenType.EOF) { if (!enumerator.MoveNext()) { throw new InvalidOperationException("ran out of tokens while attempting to recover from a parse error."); } } bool[] failed = new bool[11]; do { int state = stack[stack.Count - 1].state; int offset = _transitionTable[state]; int action = offset <= 16 ? offset : _transitionTable[offset + (int)ConfigTokenType.Error]; if (action == 0 || action > 16) { break; } else { int reductionId = action - 2; state = Reduce(reductionId, stack); } }while (true); do { ConfigTokenType nextType = GetTokenType(enumerator.Current); if (!failed[(int)nextType]) { for (int i = stack.Count - 1; i >= 0; i--) { int state = stack[i].state; int offset = _transitionTable[state]; if (offset <= 16) { continue; } int action = _transitionTable[offset + (int)ConfigTokenType.Error] - 16; if (action <= 0) { continue; } if (!CanBeFollowedBy(stack, i, action, nextType)) { continue; } State newState = new State(); newState.state = action; newState.value_Terminal = errorToken; stack.RemoveRange(i + 1, stack.Count - i - 1); stack.Add(newState); return(action); } failed[(int)nextType] = true; } if (nextType == ConfigTokenType.EOF) { throw new InvalidOperationException("unexpected token: " + GetTokenType(errorToken)); } }while (enumerator.MoveNext()); throw new InvalidOperationException("ran out of tokens while attempting to recover from a parse error."); }