public int Lex(IEnumerator <int> input, StringBuilder capture, out bool more) { var states = FillEpsilonClosure(); while (input.MoveNext()) { more = true; var next = FA.FillMove(states, input.Current); if (0 == next.Count) { foreach (var state in states) { if (state.IsAccepting) { return(state.AcceptSymbol); } } return(-1); } capture.Append(char.ConvertFromUtf32(input.Current)); states = next; } more = false; foreach (var state in states) { if (state.IsAccepting) { return(state.AcceptSymbol); } } return(-1); }
/// <summary> /// This is where the work happens /// </summary> /// <returns>The symbol that was matched. members _state _line,_column,_position,_buffer and _input are also modified.</returns> int _Lex() { int acc; var states = _initialStates; _buffer.Clear(); switch (_state) { case -1: // initial if (!_MoveNextInput()) { _state = -2; acc = _GetAcceptingSymbol(states); if (-1 < acc) { return(acc); } else { return(-1); // "#ERROR"; } } _state = 0; // running break; case -2: // end of stream return(-2); // "#EOS"; } // Here's where we run most of the match. FillMove runs one interation of the NFA state machine. // We match until we can't match anymore (greedy matching) and then report the symbol of the last // match we found, or an error ("#ERROR") if we couldn't find one. while (true) { var next = FA.FillMove(states, _input.Current); if (0 == next.Count) // couldn't find any states { break; } _buffer.Append(_input.Current); states = next; if (!_MoveNextInput()) { // end of stream _state = -2; acc = _GetAcceptingSymbol(states); if (-1 < acc) // do we accept? { return(acc); } else { return(-1); // "#ERROR"; } } } acc = _GetAcceptingSymbol(states); if (-1 < acc) // do we accept? { return(acc); } else { // handle the error condition _buffer.Append(_input.Current); if (!_MoveNextInput()) { _state = -2; } return(-1); // "#ERROR"; } }