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 <= 33 ? offset : _transitionTable[offset + (int)(type & ColumnMask)]; if (action > 33) { State newState = new State(); newState.state = state = action - 33; 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_Segment Reduce_Segment_2(Type_Terminal rawSegmentSeg, Type_Terminal segmentModifierSeg);
protected abstract Type_Segment Reduce_Segment_1(Type_Terminal rawSegmentSeg);
protected abstract Type_Rule Reduce_SegmentList_2(Type_Terminal errorSeg);
protected abstract Type_Production Reduce_Production_2(Type_Terminal errorSeg);
protected abstract Type_Production Reduce_Production_1(Type_Terminal nonTerminalSeg, Type_Terminal productionTypeDefSeg, Type_Production ruleListSeg);
protected abstract ConfigTokenType GetTokenType(Type_Terminal terminal);
protected abstract Type_Command Reduce_CommandExpression_2(Type_Terminal nullSeg);
protected abstract Type_Using Reduce_Using_2(Type_Terminal errorSeg);
protected abstract Type_Using Reduce_Using_1(Type_Terminal labelSeg, Type_Terminal stringSeg);
protected abstract Type_Setting Reduce_Setting_2(Type_Terminal labelSeg, Type_Terminal errorSeg);
protected abstract Type_Setting Reduce_Setting_1(Type_Terminal labelSeg, Type_Terminal settingValueSeg);
protected abstract Type_Config Reduce_ConfigSettings_5(Type_Terminal errorSeg);
protected abstract Type_Config Reduce_Config_2(Type_Config configSeg, Type_Terminal errorSeg);
protected abstract Type_Command Reduce_Command_2(Type_Terminal errorSeg);
protected abstract Type_Command Reduce_CommandExpression_1(Type_Terminal argumentValueSeg);
protected abstract Type_EntryPoint Reduce_EntryPoint_1(Type_Terminal nonTerminalSeg);
protected abstract Type_EntryPoint Reduce_EntryPoint_2(Type_Terminal errorSeg);
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[19]; do { int state = stack[stack.Count - 1].state; int offset = _transitionTable[state]; int action = offset <= 33 ? offset : _transitionTable[offset + (int)(ConfigTokenType.Error & ColumnMask)]; if (action == 0 || action > 33) { break; } else { int reductionId = action - 2; state = Reduce(reductionId, stack); } }while (true); do { ConfigTokenType nextType = GetTokenType(enumerator.Current); if (!failed[(int)(nextType & ColumnMask)]) { for (int i = stack.Count - 1; i >= 0; i--) { int state = stack[i].state; int offset = _transitionTable[state]; if (offset <= 33) { continue; } int action = _transitionTable[offset + (int)(ConfigTokenType.Error & ColumnMask)] - 33; 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 & ColumnMask)] = 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."); }