public FSMLexerBuilder <N> End(N nodeValue) { if (Fsm.HasState(CurrentState)) { FSMNode <N> node = Fsm.GetNode(CurrentState); node.IsEnd = true; node.Value = nodeValue; } return(this); }
private FSMNode <N> Move(FSMNode <N> from, char token, ReadOnlyMemory <char> value) { if (from != null && Transitions.TryGetValue(from.Id, out var transitions)) { // Do NOT use Linq, increases allocations AND running time for (var i = 0; i < transitions.Count; ++i) { var transition = transitions[i]; if (transition.Match(token, value)) { return(Nodes[transition.ToNode]); } } } return(null); }
public FSMMatch <N> Run(string source, int start) { string value = ""; var result = new FSMMatch <N>(false); var successes = new Stack <FSMMatch <N> >(); CurrentPosition = start; FSMNode <N> currentNode = Nodes[0]; int lastNode = 0; TokenPosition position = null; bool tokenStarted = false; if (CurrentPosition < source.Length) { char currentToken = source[CurrentPosition]; while (CurrentPosition < source.Length && currentNode != null) { currentToken = source[CurrentPosition]; bool consumeSkipped = true; while (consumeSkipped && !tokenStarted && CurrentPosition < source.Length) { currentToken = source[CurrentPosition]; if (IgnoreWhiteSpace && WhiteSpaces.Contains(currentToken)) { if (successes.Any()) { currentNode = null; } else { currentNode = Nodes[0]; } CurrentPosition++; CurrentColumn++; } else { var eol = EOLManager.IsEndOfLine(source, CurrentPosition); if (IgnoreEOL && eol != EOLType.No) { if (successes.Any()) { currentNode = null; } else { currentNode = Nodes[0]; } CurrentPosition += (eol == EOLType.Windows ? 2 : 1); CurrentColumn = 0; CurrentLine++; } else { consumeSkipped = false; } } } currentNode = Move(currentNode, currentToken, value); if (currentNode != null) { lastNode = currentNode.Id; value += currentToken; if (!tokenStarted) { tokenStarted = true; position = new TokenPosition(CurrentPosition, CurrentLine, CurrentColumn); } if (currentNode.IsEnd) { var resultInter = new FSMMatch <N>(true, currentNode.Value, value, position); successes.Push(resultInter); } if (HasAction(currentNode.Id)) { value = Actions[currentNode.Id](value); } CurrentPosition++; CurrentColumn++; } else { if (lastNode == 0 && !tokenStarted && !successes.Any() && CurrentPosition < source.Length) { throw new LexerException(new LexicalError(CurrentLine, CurrentColumn, source[CurrentPosition])); } ; } } } if (successes.Any()) { result = successes.Pop(); if (HasCallback(lastNode)) { result = Callbacks[lastNode](result); } } return(result); }