public override Token TryMatch(ParsingContext context, ISourceStream source) { while (true) { //Find next position var newPos = source.IndexOfAny(_stopChars, source.PreviewPosition + 1); //we either didn't find it if (newPos == -1) { return(context.CreateErrorToken(Resources.ErrNoEndForRegex));// "No end symbol for regex literal." } source.PreviewPosition = newPos; if (source.PreviewChar != EndSymbol) { //we hit CR or LF, this is an error return(context.CreateErrorToken(Resources.ErrNoEndForRegex)); } if (!CheckEscaped(source)) { break; } } source.PreviewPosition++; //move after end symbol //save pattern length, we will need it var patternLen = source.PreviewPosition - source.Location.Position - 2; //exclude start and end symbol //read switches and turn them into options RegexOptions options = RegexOptions.None; var switches = string.Empty; while (ReadSwitch(source, ref options)) { if (IsSet(RegexTermOptions.UniqueSwitches) && switches.Contains(source.PreviewChar)) { return(context.CreateErrorToken(Resources.ErrDupRegexSwitch, source.PreviewChar)); // "Duplicate switch '{0}' for regular expression" } switches += source.PreviewChar.ToString(); source.PreviewPosition++; } //check following symbol if (!IsSet(RegexTermOptions.AllowLetterAfter)) { var currChar = source.PreviewChar; if (char.IsLetter(currChar) || currChar == '_') { return(context.CreateErrorToken(Resources.ErrInvRegexSwitch, currChar)); // "Invalid switch '{0}' for regular expression" } } var token = source.CreateToken(this.OutputTerminal); //we have token, now what's left is to set its Value field. It is either pattern itself, or Regex instance string pattern = token.Text.Substring(1, patternLen); //exclude start and end symbol object value = pattern; if (IsSet(RegexTermOptions.CreateRegExObject)) { value = new Regex(pattern, options); } token.Value = value; token.Details = switches; //save switches in token.Details return(token); }
public static string GetRestOfLine(this ISourceStream source, int position) { var endIndex = source.IndexOfAny(eol, position); if (endIndex < 0) { endIndex = source.Length; } return(source.GetText(position, endIndex - position)); }
private string ReadNotQuotedBody(ParsingContext context, ISourceStream source) { var startPos = source.Location.Position; var sepPos = source.IndexOfAny(_terminators, startPos); if (sepPos < 0) { sepPos = source.Length; } source.PreviewPosition = sepPos; var valueText = source.GetText(startPos, sepPos - startPos); return(valueText); }
private Token TryMatchContentExtended(ParsingContext context, ISourceStream source) { StringBuilder tokenText = new StringBuilder(); while (true) { //Find next position of one of stop chars var nextPos = source.IndexOfAny(_stopChars, source.PreviewPosition); if (nextPos == -1) { if (IsSet(FreeTextOptions.AllowEof)) { source.PreviewPosition = source.Length; return(source.CreateToken(this.OutputTerminal)); } else { return(null); } } var newText = source.GetText(source.PreviewPosition, nextPos - source.PreviewPosition); tokenText.Append(newText); source.PreviewPosition = nextPos; //if it is escape, add escaped text and continue search if (CheckEscape(source, tokenText)) { continue; } //check terminators if (CheckTerminators(source, tokenText)) { break; //from while (true); we reached } //The current stop is not at escape or terminator; add this char to token text and move on tokenText.Append(source.PreviewChar); source.PreviewPosition++; }//while var text = tokenText.ToString(); if (string.IsNullOrEmpty(text) && (this.FreeTextOptions & Parsing.FreeTextOptions.AllowEmpty) == 0) { return(null); } return(source.CreateToken(this.OutputTerminal, text)); }
private Token CompleteMatch(ParsingContext context, ISourceStream source) { //Find end symbol while (!source.EOF()) { int firstCharPos; if (EndSymbols.Count == 1) { firstCharPos = source.IndexOf(EndSymbols[0], source.PreviewPosition); } else { firstCharPos = source.IndexOfAny(_endSymbolsFirsts, source.PreviewPosition); } if (firstCharPos < 0) { source.PreviewPosition = source.Length; return(null); //indicating error } //We found a character that might start an end symbol; let's see if it is true. source.PreviewPosition = firstCharPos; foreach (string endSymbol in EndSymbols) { if (source.MatchSymbol(endSymbol)) { //We found end symbol; eat end symbol only if it is not line comment. // For line comment, leave LF symbol there, it might be important to have a separate LF token if (!_isLineComment) { source.PreviewPosition += endSymbol.Length; } return(source.CreateToken(this.OutputTerminal)); } //if } //foreach endSymbol source.PreviewPosition++; //move to the next char and try again } //while return(null); //might happen if we found a start char of end symbol, but not the full endSymbol } //method
public override Token TryMatch(ParsingContext context, ISourceStream source) { bool isEscape = source.PreviewChar == EscapeChar && EscapeChar != NoEscape; if (isEscape) { //return a token containing only escaped char var value = source.NextPreviewChar.ToString(); source.PreviewPosition += 2; return(source.CreateToken(this.OutputTerminal, value)); } var stopIndex = source.IndexOfAny(_stopChars, source.Location.Position + 1); if (stopIndex == source.Location.Position) { return(null); } if (stopIndex < 0) { stopIndex = source.Length; } source.PreviewPosition = stopIndex; return(source.CreateToken(this.OutputTerminal)); } //method
public static int IndexOfAny(this ISourceStream source, char[] anyOf, int index) { return(source.IndexOfAny(anyOf, index, source.Length - index)); }